- better not check an entry for validity when we want to fill it
- bitfield definitions of page dirs were reversed... 040 is still wrong though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26528 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
74c5e8bd10
commit
d14351d2c6
@ -23,73 +23,73 @@
|
||||
// or comments
|
||||
struct short_page_directory_entry {
|
||||
// upper 32 bits
|
||||
uint32 type : 2; // DT_*
|
||||
uint32 write_protect : 1;
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 addr : 28; // address
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 write_protect : 1;
|
||||
uint32 type : 2; // DT_*
|
||||
};
|
||||
|
||||
struct long_page_directory_entry {
|
||||
// upper 32 bits
|
||||
uint32 type : 2;
|
||||
uint32 write_protect : 1;
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 _zero1 : 4;
|
||||
uint32 supervisor : 1;
|
||||
uint32 _zero2 : 1;
|
||||
uint32 _ones : 6;
|
||||
uint32 limit : 15;
|
||||
uint32 low_up : 1; // limit is lower(1)/upper(0)
|
||||
uint32 limit : 15;
|
||||
uint32 _ones : 6;
|
||||
uint32 _zero2 : 1;
|
||||
uint32 supervisor : 1;
|
||||
uint32 _zero1 : 4;
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 write_protect : 1;
|
||||
uint32 type : 2;
|
||||
// lower 32 bits
|
||||
uint32 unused : 4; //
|
||||
uint32 addr : 28; // address
|
||||
uint32 unused : 4; //
|
||||
};
|
||||
|
||||
struct short_page_table_entry {
|
||||
uint32 type : 2;
|
||||
uint32 write_protect : 1;
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 dirty : 1; // = modified
|
||||
uint32 _zero1 : 1;
|
||||
uint32 cache_disabled : 1; // = cache_inhibit
|
||||
uint32 _zero2 : 1;
|
||||
uint32 addr : 24; // address
|
||||
uint32 _zero2 : 1;
|
||||
uint32 cache_disabled : 1; // = cache_inhibit
|
||||
uint32 _zero1 : 1;
|
||||
uint32 dirty : 1; // = modified
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 write_protect : 1;
|
||||
uint32 type : 2;
|
||||
};
|
||||
|
||||
struct long_page_table_entry {
|
||||
// upper 32 bits
|
||||
uint32 type : 2;
|
||||
uint32 write_protect : 1;
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 dirty : 1; // = modified
|
||||
uint32 _zero1 : 1;
|
||||
uint32 cache_disabled : 1; // = cache_inhibit
|
||||
uint32 _zero2 : 1;
|
||||
uint32 supervisor : 1;
|
||||
uint32 _zero3 : 1;
|
||||
uint32 _ones : 6;
|
||||
uint32 low_up : 1; // limit is lower(1)/upper(0)
|
||||
// limit only used on early table terminators, else unused
|
||||
uint32 limit : 15;
|
||||
uint32 low_up : 1; // limit is lower(1)/upper(0)
|
||||
uint32 _ones : 6;
|
||||
uint32 _zero3 : 1;
|
||||
uint32 supervisor : 1;
|
||||
uint32 _zero2 : 1;
|
||||
uint32 cache_disabled : 1; // = cache_inhibit
|
||||
uint32 _zero1 : 1;
|
||||
uint32 dirty : 1; // = modified
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 write_protect : 1;
|
||||
uint32 type : 2;
|
||||
// lower 32 bits
|
||||
uint32 unused : 8; //
|
||||
uint32 addr : 24; // address
|
||||
uint32 unused : 8; //
|
||||
};
|
||||
|
||||
/* rarely used */
|
||||
struct short_indirect_entry {
|
||||
// upper 32 bits
|
||||
uint32 type : 2; // DT_*
|
||||
uint32 addr : 30; // address
|
||||
uint32 type : 2; // DT_*
|
||||
};
|
||||
|
||||
struct long_indirect_entry {
|
||||
// upper 32 bits
|
||||
uint32 type : 2;
|
||||
uint32 unused1 : 30;
|
||||
uint32 type : 2;
|
||||
// lower 32 bits
|
||||
uint32 unused2 : 2; //
|
||||
uint32 addr : 30; // address
|
||||
uint32 unused2 : 2; //
|
||||
};
|
||||
|
||||
/* for clarity:
|
||||
|
@ -24,73 +24,73 @@
|
||||
// or comments
|
||||
struct short_page_directory_entry {
|
||||
// upper 32 bits
|
||||
uint32 type : 2; // DT_*
|
||||
uint32 write_protect : 1;
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 addr : 28; // address
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 write_protect : 1;
|
||||
uint32 type : 2; // DT_*
|
||||
};
|
||||
|
||||
struct long_page_directory_entry {
|
||||
// upper 32 bits
|
||||
uint32 type : 2;
|
||||
uint32 write_protect : 1;
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 _zero1 : 4;
|
||||
uint32 supervisor : 1;
|
||||
uint32 _zero2 : 1;
|
||||
uint32 _ones : 6;
|
||||
uint32 limit : 15;
|
||||
uint32 low_up : 1; // limit is lower(1)/upper(0)
|
||||
uint32 limit : 15;
|
||||
uint32 _ones : 6;
|
||||
uint32 _zero2 : 1;
|
||||
uint32 supervisor : 1;
|
||||
uint32 _zero1 : 4;
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 write_protect : 1;
|
||||
uint32 type : 2;
|
||||
// lower 32 bits
|
||||
uint32 unused : 4; //
|
||||
uint32 addr : 28; // address
|
||||
uint32 unused : 4; //
|
||||
};
|
||||
|
||||
struct short_page_table_entry {
|
||||
uint32 type : 2;
|
||||
uint32 write_protect : 1;
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 dirty : 1; // = modified
|
||||
uint32 _zero1 : 1;
|
||||
uint32 cache_disabled : 1; // = cache_inhibit
|
||||
uint32 _zero2 : 1;
|
||||
uint32 addr : 24; // address
|
||||
uint32 _zero2 : 1;
|
||||
uint32 cache_disabled : 1; // = cache_inhibit
|
||||
uint32 _zero1 : 1;
|
||||
uint32 dirty : 1; // = modified
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 write_protect : 1;
|
||||
uint32 type : 2;
|
||||
};
|
||||
|
||||
struct long_page_table_entry {
|
||||
// upper 32 bits
|
||||
uint32 type : 2;
|
||||
uint32 write_protect : 1;
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 dirty : 1; // = modified
|
||||
uint32 _zero1 : 1;
|
||||
uint32 cache_disabled : 1; // = cache_inhibit
|
||||
uint32 _zero2 : 1;
|
||||
uint32 supervisor : 1;
|
||||
uint32 _zero3 : 1;
|
||||
uint32 _ones : 6;
|
||||
uint32 low_up : 1; // limit is lower(1)/upper(0)
|
||||
// limit only used on early table terminators, else unused
|
||||
uint32 limit : 15;
|
||||
uint32 low_up : 1; // limit is lower(1)/upper(0)
|
||||
uint32 _ones : 6;
|
||||
uint32 _zero3 : 1;
|
||||
uint32 supervisor : 1;
|
||||
uint32 _zero2 : 1;
|
||||
uint32 cache_disabled : 1; // = cache_inhibit
|
||||
uint32 _zero1 : 1;
|
||||
uint32 dirty : 1; // = modified
|
||||
uint32 accessed : 1; // = used
|
||||
uint32 write_protect : 1;
|
||||
uint32 type : 2;
|
||||
// lower 32 bits
|
||||
uint32 unused : 8; //
|
||||
uint32 addr : 24; // address
|
||||
uint32 unused : 8; //
|
||||
};
|
||||
|
||||
/* rarely used */
|
||||
struct short_indirect_entry {
|
||||
// upper 32 bits
|
||||
uint32 type : 2; // DT_*
|
||||
uint32 addr : 30; // address
|
||||
uint32 type : 2; // DT_*
|
||||
};
|
||||
|
||||
struct long_indirect_entry {
|
||||
// upper 32 bits
|
||||
uint32 type : 2;
|
||||
uint32 unused1 : 30;
|
||||
uint32 type : 2;
|
||||
// lower 32 bits
|
||||
uint32 unused2 : 2; //
|
||||
uint32 addr : 30; // address
|
||||
uint32 unused2 : 2; //
|
||||
};
|
||||
|
||||
/* for clarity:
|
||||
@ -101,19 +101,19 @@ struct long_indirect_entry {
|
||||
|
||||
typedef struct short_page_directory_entry page_root_entry;
|
||||
typedef struct short_page_directory_entry page_directory_entry;
|
||||
typedef struct long_page_table_entry page_table_entry;
|
||||
typedef struct long_indirect_entry page_indirect_entry;
|
||||
typedef struct short_page_table_entry page_table_entry;
|
||||
typedef struct short_indirect_entry page_indirect_entry;
|
||||
|
||||
/* scalar storage type that maps them */
|
||||
typedef uint32 page_root_entry_scalar;
|
||||
typedef uint32 page_directory_entry_scalar;
|
||||
typedef uint64 page_table_entry_scalar;
|
||||
typedef uint64 page_indirect_entry_scalar;
|
||||
typedef uint32 page_table_entry_scalar;
|
||||
typedef uint32 page_indirect_entry_scalar;
|
||||
|
||||
#define DT_ROOT DT_VALID_4
|
||||
#define DT_DIR DT_VALID_8
|
||||
#define DT_DIR DT_VALID_4
|
||||
//#define DT_PAGE DT_PAGE :)
|
||||
#define DT_INDIRECT DT_VALID_8
|
||||
#define DT_INDIRECT DT_VALID_4
|
||||
|
||||
/* default scalar values for entries */
|
||||
#define DFL_ROOTENT_VAL 0x00000000
|
||||
|
@ -142,7 +142,7 @@ add_page_table(addr_t virtualAddress)
|
||||
index = VADDR_TO_PRENT(virtualAddress);
|
||||
if (pr[index].type != DT_ROOT) {
|
||||
unsigned aindex = index & ~(NUM_DIRTBL_PER_PAGE-1); /* aligned */
|
||||
TRACE(("missing page root entry %d ai %d\n", index, aindex));
|
||||
//TRACE(("missing page root entry %d ai %d\n", index, aindex));
|
||||
tbl = mmu_get_next_page_tables();
|
||||
if (!tbl)
|
||||
return ENOMEM;
|
||||
@ -151,24 +151,21 @@ add_page_table(addr_t virtualAddress)
|
||||
page_root_entry *apr = &pr[aindex + i];
|
||||
apr->addr = TA_TO_PREA(tbl);
|
||||
apr->type = DT_ROOT;
|
||||
TRACE(("inserting tbl @ %p as %08x entry %08x\n", tbl, TA_TO_PREA(tbl), *(uint32 *)apr));
|
||||
//TRACE(("inserting tbl @ %p as %08x entry %08x\n", tbl, TA_TO_PREA(tbl), *(uint32 *)apr));
|
||||
// clear the table
|
||||
TRACE(("clearing table[%d]\n", i));
|
||||
//TRACE(("clearing table[%d]\n", i));
|
||||
pd = (page_directory_entry *)tbl;
|
||||
for (int32 j = 0; j < NUM_DIRENT_PER_TBL; j++)
|
||||
*(page_directory_entry_scalar *)(&pd[j]) = DFL_DIRENT_VAL;
|
||||
tbl += SIZ_DIRTBL;
|
||||
}
|
||||
}
|
||||
TRACE(("B %08lx\n", PRE_TO_TA(pr[index])));
|
||||
pd = (page_directory_entry *)PRE_TO_TA(pr[index]);
|
||||
TRACE(("C\n"));
|
||||
|
||||
index = VADDR_TO_PDENT(virtualAddress);
|
||||
TRACE(("checking pgdir@%p[%d]\n", pd, index));
|
||||
if (pd[index].type != DT_DIR) {
|
||||
unsigned aindex = index & ~(NUM_PAGETBL_PER_PAGE-1); /* aligned */
|
||||
TRACE(("missing page dir entry %d ai %d\n", index, aindex));
|
||||
//TRACE(("missing page dir entry %d ai %d\n", index, aindex));
|
||||
tbl = mmu_get_next_page_tables();
|
||||
if (!tbl)
|
||||
return ENOMEM;
|
||||
@ -178,7 +175,7 @@ add_page_table(addr_t virtualAddress)
|
||||
apd->addr = TA_TO_PDEA(tbl);
|
||||
apd->type = DT_DIR;
|
||||
// clear the table
|
||||
TRACE(("clearing table[%d]\n", i));
|
||||
//TRACE(("clearing table[%d]\n", i));
|
||||
pt = (page_table_entry *)tbl;
|
||||
for (int32 j = 0; j < NUM_PAGEENT_PER_TBL; j++)
|
||||
*(page_table_entry_scalar *)(&pt[j]) = DFL_PAGEENT_VAL;
|
||||
@ -203,23 +200,26 @@ lookup_pte(addr_t virtualAddress)
|
||||
page_root_entry *pr = gPageRoot;
|
||||
page_directory_entry *pd;
|
||||
page_table_entry *pt;
|
||||
uint32 index;
|
||||
uint32 rindex, dindex, pindex;
|
||||
|
||||
index = VADDR_TO_PRENT(virtualAddress);
|
||||
if (pr[index].type != DT_ROOT)
|
||||
panic("lookup_pte: invalid page root entry %d", index);
|
||||
pd = (page_directory_entry *)PRE_TO_TA(pr[index]);
|
||||
rindex = VADDR_TO_PRENT(virtualAddress);
|
||||
if (pr[rindex].type != DT_ROOT)
|
||||
panic("lookup_pte: invalid entry pgrt[%d]", rindex);
|
||||
pd = (page_directory_entry *)PRE_TO_TA(pr[rindex]);
|
||||
|
||||
index = VADDR_TO_PDENT(virtualAddress);
|
||||
if (pd[index].type != DT_DIR)
|
||||
panic("lookup_pte: invalid page directory entry %d", index);
|
||||
pt = (page_table_entry *)PDE_TO_TA(pd[index]);
|
||||
dindex = VADDR_TO_PDENT(virtualAddress);
|
||||
if (pd[dindex].type != DT_DIR)
|
||||
panic("lookup_pte: invalid entry pgrt[%d] prdir[%d]", rindex, dindex);
|
||||
pt = (page_table_entry *)PDE_TO_TA(pd[dindex]);
|
||||
|
||||
index = VADDR_TO_PTENT(virtualAddress);
|
||||
if (pt[index].type != DT_PAGE)
|
||||
panic("lookup_pte: invalid page table entry %d", index);
|
||||
pindex = VADDR_TO_PTENT(virtualAddress);
|
||||
#if 0 // of course, it's used in map_page!
|
||||
if (pt[pindex].type != DT_PAGE)
|
||||
panic("lookup_pte: invalid entry pgrt[%d] prdir[%d] pgtbl[%d]",
|
||||
rindex, dindex, pindex);
|
||||
#endif
|
||||
|
||||
return (&pt[index]);
|
||||
return (&pt[pindex]);
|
||||
}
|
||||
|
||||
|
||||
@ -231,11 +231,16 @@ unmap_page(addr_t virtualAddress)
|
||||
TRACE(("mmu->unmap_page(virtualAddress = %p)\n", (void *)virtualAddress));
|
||||
|
||||
if (virtualAddress < KERNEL_BASE)
|
||||
panic("unmap_page: asked to unmap invalid page %p!\n", (void *)virtualAddress);
|
||||
panic("unmap_page: asked to unmap invalid page %p!\n",
|
||||
(void *)virtualAddress);
|
||||
|
||||
// unmap the page from the correct page table
|
||||
pt = lookup_pte(virtualAddress);
|
||||
|
||||
if (pt->type != DT_PAGE)
|
||||
panic("unmap_page: asked to map non-existing page for %08x\n",
|
||||
virtualAddress);
|
||||
|
||||
pt->addr = TA_TO_PTEA(0xdeadb00b);
|
||||
pt->type = DT_INVALID;
|
||||
|
||||
@ -258,6 +263,10 @@ map_page(addr_t virtualAddress, addr_t physicalAddress, uint32 flags)
|
||||
|
||||
pt = lookup_pte(virtualAddress);
|
||||
|
||||
if (pt->type != DT_INVALID)
|
||||
panic("map_page: asked to map existing page for %08x\n",
|
||||
virtualAddress);
|
||||
|
||||
TRACE(("map_page: inserting pageTableEntry %p, physicalAddress %p\n",
|
||||
pt, physicalAddress));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user