track changes

This commit is contained in:
Murphy 2025-04-01 12:32:51 -04:00
parent 4dc44e8fce
commit 9945ad6119
Signed by: freya
GPG key ID: 9FBC6FFD6D2DBF17
5 changed files with 175 additions and 183 deletions

View file

@ -3,8 +3,6 @@
** **
** GENERATED AUTOMATICALLY - DO NOT EDIT ** GENERATED AUTOMATICALLY - DO NOT EDIT
** **
** Creation date: Mon Mar 31 11:38:04 2025
**
** This header file contains C Preprocessor macros which expand ** This header file contains C Preprocessor macros which expand
** into the byte offsets needed to reach fields within structs ** into the byte offsets needed to reach fields within structs
** used in the baseline system. Should those struct declarations ** used in the baseline system. Should those struct declarations

View file

@ -163,7 +163,7 @@ static void kreport(bool_t dtrace)
} }
#endif /* TRACE > 0 */ #endif /* TRACE > 0 */
cio_puts("\n-------------------------------\n"); cio_putchar('\n');
} }
#if defined(CONSOLE_STATS) #if defined(CONSOLE_STATS)
@ -304,10 +304,10 @@ int main(void)
user_init(); // user code handling user_init(); // user code handling
cio_puts("\nModule initialization complete.\n"); cio_puts("\nModule initialization complete.\n");
cio_puts("-------------------------------\n");
// report our configuration options // report our configuration options
kreport(true); kreport(true);
cio_puts("-------------------------------\n");
delay(DELAY_2_SEC); delay(DELAY_2_SEC);
@ -378,21 +378,23 @@ int main(void)
sio_enable(SIO_RX); sio_enable(SIO_RX);
#if 0
// produce a "system state" report // produce a "system state" report
cio_puts("System status: Queues "); cio_puts( "System status: Queues " );
pcb_queue_dump("R", ready, true); pcb_queue_dump( "R", ready, true );
pcb_queue_dump("W", waiting, true); pcb_queue_dump( "W", waiting, true );
pcb_queue_dump("S", sleeping, true); pcb_queue_dump( "S", sleeping, true );
pcb_queue_dump("Z", zombie, true); pcb_queue_dump( "Z", zombie, true );
pcb_queue_dump("I", sioread, true); pcb_queue_dump( "I", sioread, true );
ptable_dump_counts(); ptable_dump_counts();
pcb_dump("Current: ", current, true); pcb_dump( "Current: ", current, true );
delay(DELAY_3_SEC); delay( DELAY_3_SEC );
vm_print(current->pdir, true, TwoLevel); vm_print( current->pdir, true, TwoLevel );
delay(DELAY_3_SEC); delay( DELAY_3_SEC );
#endif
return 0; return 0;
} }

View file

@ -963,16 +963,8 @@ void pcb_dump(const char *msg, register pcb_t *pcb, bool_t all)
return; return;
} }
cio_printf(" %d", pcb->pid); cio_printf(" %d %s", pcb->pid,
pcb->state >= N_STATES ? "???" : state_str[pcb->state]);
cio_printf(" %s", pcb->state >= N_STATES ? "???" : state_str[pcb->state]);
#if 0
if( pcb->state >= N_STATES ) {
cio_puts( " ????" );
} else {
cio_printf( " %s", state_str[pcb->state] );
}
#endif
if (!all) { if (!all) {
// just printing IDs and states on one line // just printing IDs and states on one line
@ -982,13 +974,6 @@ void pcb_dump(const char *msg, register pcb_t *pcb, bool_t all)
// now, the rest of the contents // now, the rest of the contents
cio_printf(" %s", cio_printf(" %s",
pcb->priority >= N_PRIOS ? "???" : prio_str[pcb->priority]); pcb->priority >= N_PRIOS ? "???" : prio_str[pcb->priority]);
#if 0
if( pcb->priority >= N_PRIOS ) {
cio_puts( " ???" );
} else {
cio_printf( " %s", prio_str[pcb->priority] );
}
#endif
cio_printf(" ticks %u xit %d wake %08x\n", pcb->ticks, pcb->exit_status, cio_printf(" ticks %u xit %d wake %08x\n", pcb->ticks, pcb->exit_status,
pcb->wakeup); pcb->wakeup);
@ -1007,8 +992,6 @@ void pcb_dump(const char *msg, register pcb_t *pcb, bool_t all)
/** /**
** pcb_queue_dump(msg,queue,contents) ** pcb_queue_dump(msg,queue,contents)
** **
** Dump the contents of the specified queue to the console
**
** @param msg[in] Optional message to print ** @param msg[in] Optional message to print
** @param queue[in] The queue to dump ** @param queue[in] The queue to dump
** @param contents[in] Also dump (some) contents? ** @param contents[in] Also dump (some) contents?
@ -1124,16 +1107,10 @@ void ptable_dump_counts(void)
cio_printf("Ptable: %u ***", unknown); cio_printf("Ptable: %u ***", unknown);
for (n = 0; n < N_STATES; ++n) { for (n = 0; n < N_STATES; ++n) {
cio_printf(" %u %s", nstate[n], if (nstate[n]) {
state_str[n] != NULL ? state_str[n] : "???"); cio_printf(" %u %s", nstate[n],
#if 0 state_str[n] != NULL ? state_str[n] : "???");
cio_printf( " %u ", nstate[n] );
if( state_str[n][0] != '\0' ) {
cio_puts( state_str[n] );
} else {
cio_puts( "???" );
} }
#endif
} }
cio_putchar('\n'); cio_putchar('\n');
} }

View file

@ -510,45 +510,72 @@ static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args,
** Stack alignment rules for the SysV ABI i386 supplement dictate that ** Stack alignment rules for the SysV ABI i386 supplement dictate that
** the 'argc' parameter must be at an address that is a multiple of 16; ** the 'argc' parameter must be at an address that is a multiple of 16;
** see below for more information. ** see below for more information.
**
** Ultimately, this is what the bottom end of the stack will look like:
**
** kvavptr
** kvacptr |
** | |
** v v
** argc argv av[0] av[1] etc NULL str0 str1 etc.
** [....][....][....][....] ... [0000] ... [......0......0.........]
** | ^ | | ^ ^
** | | | | | |
** ------ | ---------------------|-------
** ---------------------------
*/ */
/* /*
** Find the user stack. The PDE entry for user address space points ** We need to find the last page of the user stack. Find the page
** to a page table for the first 4MB of the address space, but the ** table for the 4MB user address space. The physical address of its
** "pointer" there a physical frame address. ** frame is in the first page directory entry. Extract that from the
** entry and convert it into a virtual address for the kernel to use.
*/ */
pde_t *kv_userpt = (pde_t *)P2V(PTE_ADDR(pcb->pdir[USER_PDE])); pde_t *kv_userpt = (pde_t *)P2V(PTE_ADDR(pcb->pdir[USER_PDE]));
assert(kv_userpt != NULL); assert(kv_userpt != NULL);
/* /*
** The final entries in that PMT are for the pages of the user stack. ** The final entries in that PMT are for the pages of the user stack.
** Grab the address of the frame for the last one. (Again, we need ** Grab the physical address of the frame for the last one. (Again,
** to convert it to a virtual address we can use.) ** we need to convert it to a virtual address we can use.)
*/ */
// the PMT entry for that page // the PMT entry for that page
pte_t pmt_entry = kv_userpt[USER_STK_LAST_PTE]; pte_t pmt_entry = kv_userpt[USER_STK_LAST_PTE];
assert(IS_PRESENT(pmt_entry)); assert(IS_PRESENT(pmt_entry));
// kernel VA for the first byte following that page // user VA for the first byte of that page
uint8_t *kv_ptr = (uint8_t *)P2V(PTE_ADDR(pmt_entry) + SZ_PAGE); uint32_t *uvptr = (uint32_t *)USER_STACK_P2;
assert(kv_ptr != NULL);
// user VA for the first byte following that page // convert that address to a kernel VA
uint32_t *uv_ptr = (uint32_t *)(USER_STACK_P2 + SZ_PAGE); uint32_t *kvptr = (uint32_t *)vm_uva2kva(pcb->pdir, (void *)uvptr);
// Pointers to where the arg strings should be filled in.
uint32_t kv_strings = ((uint32_t)kv_ptr) - argbytes;
uint32_t uv_strings = ((uint32_t)uv_ptr) - argbytes;
// back the pointers up to the nearest word boundary; because we're
// moving toward location 0, the nearest word boundary is just the
// next smaller address whose low-order two bits are zeroes
kv_strings &= MOD4_MASK;
uv_strings &= MOD4_MASK;
/* /*
** Next, we need to copy over the data. Start by determining where ** Move these pointers to where the string area will begin. We
** will then back up to the next lower multiple-of-four address.
*/
uint32_t uvstrptr = ((uint32_t)uvptr) + SZ_PAGE - argbytes;
uvstrptr &= MOD4_MASK;
uint32_t kvstrptr = ((uint32_t)kvptr) + SZ_PAGE - argbytes;
kvstrptr &= MOD4_MASK;
// Copy over the argv strings, remembering where each string begins
for (int i = 0; i < argc; ++i) {
// copy the string using kernel addresses
strcpy((char *)kvstrptr, kv_args[i]);
// remember the user address where this string went
uv_argv[i] = (char *)uvstrptr;
// adjust both string addresses
kvstrptr += strlengths[i];
uvstrptr += strlengths[i];
}
/*
** Next, we need to copy over the other data. Start by determining
** where 'argc' should go. ** where 'argc' should go.
** **
** Stack alignment is controlled by the SysV ABI i386 supplement, ** Stack alignment is controlled by the SysV ABI i386 supplement,
@ -564,68 +591,37 @@ static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args,
** Isn't technical documentation fun? Ultimately, this means that ** Isn't technical documentation fun? Ultimately, this means that
** the first parameter to main() should be on the stack at an address ** the first parameter to main() should be on the stack at an address
** that is a multiple of 16. In our case, that is 'argc'. ** that is a multiple of 16. In our case, that is 'argc'.
** */
/*
** The space needed for argc, argv, and the argv array itself is ** The space needed for argc, argv, and the argv array itself is
** argc + 3 words (argc+1 for the argv entries, plus one word each ** argc + 3 words (argc+1 for the argv entries, plus one word each
** for argc and argv). We back up that much from 'strings'. ** for argc and argv). We back up that much from the string area.
*/ */
int nwords = argc + 3; int nwords = argc + 3;
uint32_t *kv_acptr = ((uint32_t *)kv_strings) - nwords; uint32_t *kvacptr = ((uint32_t *)kvstrptr) - nwords;
uint32_t *uv_acptr = ((uint32_t *)uv_strings) - nwords; uint32_t *uvacptr = ((uint32_t *)uvstrptr) - nwords;
// back these up to multiple-of-16 addresses for stack alignment // back these up to multiple-of-16 addresses for stack alignment
kv_acptr = (uint32_t *)(((uint32_t)kv_acptr) & MOD16_MASK); kvacptr = (uint32_t *)(((uint32_t)kvacptr) & MOD16_MASK);
uv_acptr = (uint32_t *)(((uint32_t)uv_acptr) & MOD16_MASK); uvacptr = (uint32_t *)(((uint32_t)uvacptr) & MOD16_MASK);
// the argv location
uint32_t *kv_avptr = kv_acptr + 1;
// the user address for the first argv entry
uint32_t *uv_avptr = uv_acptr + 2;
// Copy over the argv strings.
for (int i = 0; i < argc; ++i) {
// copy the string using kernel addresses
strcpy((char *)kv_strings, kv_args[i]);
// remember the user address where this string went
uv_argv[i] = (char *)uv_strings;
// adjust both string addresses
kv_strings += strlengths[i];
uv_strings += strlengths[i];
}
/*
** Next, we copy in argc, argv, and the pointers. The stack will
** look something like this:
**
** kv_avptr
** kv_acptr |
** | |
** v v
** argc argv av[0] av[1] etc NULL str0 str1 etc.
** [....][....][....][....] ... [0000] ... [......0......0.........]
** | ^ | | ^ ^
** | | | | | |
** ------ | ---------------------|-------
** ---------------------------
*/
// copy in 'argc' // copy in 'argc'
*kv_acptr = argc; *kvacptr = argc;
// copy in 'argv' // 'argv' immediately follows 'argc', and 'argv[0]' immediately
*kv_avptr++ = (uint32_t)uv_avptr; // follows 'argv'
uint32_t *kvavptr = kvacptr + 2;
*(kvavptr - 1) = (uint32_t)kvavptr;
// now, the argv entries themselves // now, the argv entries themselves
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
*kv_avptr++ = (uint32_t)uv_argv[i]; *kvavptr++ = (uint32_t)uv_argv[i];
} }
// and the trailing NULL // and the trailing NULL
*kv_avptr = NULL; *kvavptr = NULL;
/* /*
** Almost done! ** Almost done!
@ -641,8 +637,8 @@ static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args,
// Locate the context save area on the stack by backup up one // Locate the context save area on the stack by backup up one
// "context" from where the argc value is saved // "context" from where the argc value is saved
context_t *kv_ctx = ((context_t *)kv_acptr) - 1; context_t *kvctx = ((context_t *)kvacptr) - 1;
uint32_t uv_ctx = (uint32_t)(((context_t *)uv_acptr) - 1); uint32_t uvctx = (uint32_t)(((context_t *)uvacptr) - 1);
/* /*
** We cleared the entire stack earlier, so all the context ** We cleared the entire stack earlier, so all the context
@ -655,18 +651,18 @@ static context_t *stack_setup(pcb_t *pcb, uint32_t entry, const char **args,
** where it winds up. ** where it winds up.
*/ */
kv_ctx->eflags = DEFAULT_EFLAGS; // IF enabled, IOPL 0 kvctx->eflags = DEFAULT_EFLAGS; // IF enabled, IOPL 0
kv_ctx->eip = entry; // initial EIP kvctx->eip = entry; // initial EIP
kv_ctx->cs = GDT_CODE; // segment registers kvctx->cs = GDT_CODE; // segment registers
kv_ctx->ss = GDT_STACK; kvctx->ss = GDT_STACK;
kv_ctx->ds = kv_ctx->es = kv_ctx->fs = kv_ctx->gs = GDT_DATA; kvctx->ds = kvctx->es = kvctx->fs = kvctx->gs = GDT_DATA;
/* /*
** Return the new context pointer to the caller. It will be our ** Return the new context pointer to the caller as a user
** caller's responsibility to schedule this process. ** space virtual address.
*/ */
return ((context_t *)uv_ctx); return ((context_t *)uvctx);
} }
/* /*

View file

@ -95,13 +95,19 @@ static uint32_t ptcount(pte_t *ptr, bool_t dir)
} }
// decode a PDE // decode a PDE
static void pde_prt(uint32_t level, uint32_t i, uint32_t entry) static void pde_prt(uint32_t level, uint32_t i, uint32_t entry, bool_t all)
{ {
if (!IS_PRESENT(entry) && !all) {
return;
}
// indent // indent
for (int n = 0; n <= level; ++n) for (int n = 0; n <= level; ++n)
cio_puts(" "); cio_puts(" ");
// line header // line header
cio_printf("[%08x] %08x", i, entry); cio_printf("[%03x] %08x", i, entry);
// perms // perms
if (IS_LARGE(entry)) { // PS is 1 if (IS_LARGE(entry)) { // PS is 1
if ((entry & PDE_PAT) != 0) if ((entry & PDE_PAT) != 0)
@ -122,43 +128,49 @@ static void pde_prt(uint32_t level, uint32_t i, uint32_t entry)
cio_puts(" U"); cio_puts(" U");
if ((entry & PDE_RW) != 0) if ((entry & PDE_RW) != 0)
cio_puts(" W"); cio_puts(" W");
cio_puts((entry & PDE_P) != 0 ? " P" : "!P");
cio_printf(" --> %s %08x", IS_LARGE(entry) ? "Pg" : "PT", PDE_ADDR(entry)); // frame address
cio_printf(" P --> %s %08x\n", IS_LARGE(entry) ? "Pg" : "PT",
PDE_ADDR(entry));
} }
// decode a PTE // decode a PTE
static void pte_prt(uint32_t level, uint32_t i, uint32_t entry) static void pte_prt(uint32_t level, uint32_t i, uint32_t entry, bool_t all)
{ {
if (!IS_PRESENT(entry) && !all) {
return;
}
// indent // indent
for (int n = 0; n <= level; ++n) for (int n = 0; n <= level; ++n)
cio_puts(" "); cio_puts(" ");
// line header
cio_printf("[%08x] %08x", i, entry);
// perms
if ((entry & PDE_G) != 0)
cio_puts(" G");
if ((entry & PDE_PAT) != 0)
cio_puts(" PAT");
if ((entry & PDE_D) != 0)
cio_puts(" D");
if ((entry & PDE_A) != 0)
cio_puts(" A");
if ((entry & PDE_PCD) != 0)
cio_puts(" CD");
if ((entry & PDE_PWT) != 0)
cio_puts(" WT");
if ((entry & PDE_US) != 0)
cio_puts(" U");
if ((entry & PDE_RW) != 0)
cio_puts(" W");
cio_puts((entry & PDE_P) != 0 ? " P" : "!P");
cio_printf(" --> Pg %08x", PTE_ADDR(entry)); // line header
cio_printf("[%03x] %08x", i, entry);
// perms
if ((entry & PTE_G) != 0)
cio_puts(" G");
if ((entry & PTE_PAT) != 0)
cio_puts(" PAT");
if ((entry & PTE_D) != 0)
cio_puts(" D");
if ((entry & PTE_A) != 0)
cio_puts(" A");
if ((entry & PTE_PCD) != 0)
cio_puts(" CD");
if ((entry & PTE_PWT) != 0)
cio_puts(" WT");
if ((entry & PTE_US) != 0)
cio_puts(" U");
if ((entry & PTE_RW) != 0)
cio_puts(" W");
cio_printf(" P --> Pg %08x\n", PTE_ADDR(entry));
} }
/** /**
** Name: pdump ** Name: ptdump
** **
** Recursive helper for table hierarchy dump. ** Recursive helper for table hierarchy dump.
** **
@ -168,40 +180,44 @@ static void pte_prt(uint32_t level, uint32_t i, uint32_t entry)
** @param mode How to display the entries ** @param mode How to display the entries
*/ */
ATTR_UNUSED ATTR_UNUSED
static void pdump(uint_t level, void *pt, bool_t dir, enum vmmode_e mode) static void ptdump(uint_t level, void *pt, bool_t dir, enum vmmode_e mode)
{ {
pte_t *ptr = (pte_t *)pt; pte_t *ptr = (pte_t *)pt;
cio_printf("? at 0x%08x:", dir ? "PDir" : "PTbl", (uint32_t)pt); // indent two spaces per level
for (int n = 0; n < level; ++n)
cio_puts(" ");
cio_printf("%s at 0x%08x:", dir ? "PDir" : "PTbl", (uint32_t)pt);
uint32_t nums = ptcount(ptr, dir); uint32_t nums = ptcount(ptr, dir);
if (dir) { if (dir) {
cio_printf(" %u 4MB", (nums >> 16)); cio_printf(" 4MB=%u", (nums >> 16));
} }
cio_printf(" %u P %u !P\n", nums & 0xffff, cio_printf(" P=%u !P=%u\n", nums & 0xffff,
N_PTE - ((nums >> 16) + (nums & 0xffff))); N_PTE - ((nums >> 16) + (nums & 0xffff)));
for (uint32_t i = 0; i < (uint32_t)N_PTE; ++i) { for (uint32_t i = 0; i < (uint32_t)N_PTE; ++i) {
pte_t entry = *ptr; pte_t entry = *ptr++;
if (dir) {
// this is a PDIR entry; could be either a 4MB // only process this entry if it's not empty
// page, or a PMT pointer if (entry) {
if (mode > Simple) { if (dir) {
pde_prt(level, i, entry); // this is a PDIR entry; could be either a 4MB
cio_putchar('\n'); // page, or a PMT pointer
if (!IS_LARGE(entry)) { if (mode > Simple) {
pdump(level + 1, (void *)*ptr, false, mode); pde_prt(level, i, entry, false);
if (!IS_LARGE(entry) && mode > OneLevel) {
ptdump(level + 1, (void *)P2V(PTE_ADDR(entry)), false,
mode);
}
}
} else {
// just a PMT entry
if (mode > Simple) {
pte_prt(level, i, entry, false);
} }
} }
} else {
// just a PMT entry
if (mode > Simple) {
pte_prt(level, i, entry);
cio_putchar('\n');
}
} }
// move to the next entry
++ptr;
} }
} }
@ -285,7 +301,7 @@ void vm_init(void)
// add the entries for the user address space // add the entries for the user address space
for (uint32_t addr = 0; addr < NUM_4MB; addr += SZ_PAGE) { for (uint32_t addr = 0; addr < NUM_4MB; addr += SZ_PAGE) {
int stat = vm_map(kpdir, (void *)addr, addr, SZ_PAGE, PTE_RW); int stat = vm_map(kpdir, (void *)addr, addr, SZ_PAGE, PTE_US | PTE_RW);
if (stat != SUCCESS) { if (stat != SUCCESS) {
cio_printf("vm_init, map %08x->%08x failed, status %d\n", addr, cio_printf("vm_init, map %08x->%08x failed, status %d\n", addr,
addr, stat); addr, stat);
@ -315,8 +331,8 @@ void vm_init(void)
** **
** Convert a user VA into a kernel address. Works for all addresses - ** Convert a user VA into a kernel address. Works for all addresses -
** if the address is a page address, the low-order nine bits will be ** if the address is a page address, the low-order nine bits will be
** zeroes; otherwise, they is the offset into the page, which is ** zeroes; otherwise, they are the offset into the page, which is
** unchanged within the address spaces. ** unchanged between the address spaces.
** **
** @param pdir Pointer to the page directory to examine ** @param pdir Pointer to the page directory to examine
** @param va Virtual address to check ** @param va Virtual address to check
@ -333,7 +349,7 @@ void *vm_uva2kva(pde_t *pdir, void *va)
pte_t entry = *pte; pte_t entry = *pte;
// is this a valid address for the user? // is this a valid address for the user?
if (IS_PRESENT(entry)) { if (!IS_PRESENT(entry)) {
return NULL; return NULL;
} }
@ -477,7 +493,7 @@ pte_t *vm_getpte(pde_t *pdir, const void *va, bool_t alloc)
// NOTE: the allocator is serving us virtual page addresses, // NOTE: the allocator is serving us virtual page addresses,
// so we must convert them to physical addresses for the // so we must convert them to physical addresses for the
// table entries // table entries
*pde_ptr = V2P(ptbl) | PDE_P | PDE_RW; *pde_ptr = V2P(ptbl) | PDE_P | PDE_RW | PDE_US;
} }
// finally, return a pointer to the entry in the page table for this VA // finally, return a pointer to the entry in the page table for this VA
@ -630,7 +646,7 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size,
if (wr) { if (wr) {
entrybase |= PTE_RW; entrybase |= PTE_RW;
} }
if (sys) { if (!sys) {
entrybase |= PTE_US; entrybase |= PTE_US;
} }
@ -664,7 +680,7 @@ int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size,
memclr(page, SZ_PAGE); memclr(page, SZ_PAGE);
// create the PTE for this frame // create the PTE for this frame
uint32_t entry = (uint32_t)(PTE_ADDR(V2P(page)) | entrybase); uint32_t entry = (uint32_t)(V2P(PTE_ADDR(page)) | entrybase);
*pte = entry; *pte = entry;
// copy data if we need to // copy data if we need to
@ -711,6 +727,7 @@ void vm_free(pde_t *pdir)
pde_t *curr = pdir; pde_t *curr = pdir;
int nf = 0; int nf = 0;
int nt = 0; int nt = 0;
for (int i = 0; i < N_PDE; ++i) { for (int i = 0; i < N_PDE; ++i) {
// the entry itself // the entry itself
pde_t entry = *curr; pde_t entry = *curr;
@ -721,14 +738,15 @@ void vm_free(pde_t *pdir)
assert(!IS_LARGE(entry)); assert(!IS_LARGE(entry));
// get the PMT pointer // get the PMT pointer
pte_t *pmt = (pte_t *)PTE_ADDR(entry); pte_t *pmt = (pte_t *)P2V(PTE_ADDR(entry));
// walk the PMT // walk the PMT
for (int j = 0; j < N_PTE; ++j) { for (int j = 0; j < N_PTE; ++j) {
pte_t tmp = *pmt;
// does this entry point to a frame? // does this entry point to a frame?
if (IS_PRESENT(*pmt)) { if (IS_PRESENT(tmp)) {
// yes - free the frame // yes - free the frame
km_page_free((void *)PTE_ADDR(*pmt)); km_page_free((void *)P2V(PTE_ADDR(tmp)));
++nf; ++nf;
// mark it so we don't get surprised // mark it so we don't get surprised
*pmt = 0; *pmt = 0;
@ -737,7 +755,7 @@ void vm_free(pde_t *pdir)
++pmt; ++pmt;
} }
// now, free the PMT itself // now, free the PMT itself
km_page_free((void *)PDE_ADDR(entry)); km_page_free((void *)P2V(PDE_ADDR(entry)));
++nt; ++nt;
*curr = 0; *curr = 0;
} }
@ -875,7 +893,8 @@ int vm_uvmdup(pde_t *new, pde_t *old)
if (!IS_LARGE(entry)) { if (!IS_LARGE(entry)) {
// it's a 4KB page, so we need to duplicate the PMT // it's a 4KB page, so we need to duplicate the PMT
pte_t *newpt = (pte_t *)vm_pagedup((void *)PTE_ADDR(entry)); pte_t *newpt =
(pte_t *)vm_pagedup((void *)P2V(PTE_ADDR(entry)));
if (newpt == NULL) { if (newpt == NULL) {
return E_NO_MEMORY; return E_NO_MEMORY;
} }
@ -883,7 +902,7 @@ int vm_uvmdup(pde_t *new, pde_t *old)
uint32_t perms = PERMS(entry); uint32_t perms = PERMS(entry);
// create the new PDE entry by replacing the frame # // create the new PDE entry by replacing the frame #
entry = ((uint32_t)newpt) | perms; entry = ((uint32_t)V2P(PTE_ADDR(newpt))) | perms;
} }
} else { } else {
@ -919,8 +938,8 @@ void vm_print(void *pt, bool_t dir, enum vmmode_e mode)
return; return;
} }
cio_printf("Starting at 0x%08x (%s):\n", (uint32_t)pt, cio_printf(", starting at 0x%08x (%s):\n", (uint32_t)pt,
dir ? "PDIR" : "PMT"); dir ? "PDIR" : "PMT");
pdump(0, pt, dir, mode); ptdump(1, pt, dir, mode);
} }