X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/de355530ae67247cbd0da700edb3a2a1dae884c2..743b15655a24ee3fe9f458f383003e011db0558f:/osfmk/ppc/savearea.c?ds=sidebyside diff --git a/osfmk/ppc/savearea.c b/osfmk/ppc/savearea.c index 1b59e82cc..fcda2ab4c 100644 --- a/osfmk/ppc/savearea.c +++ b/osfmk/ppc/savearea.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -24,7 +24,6 @@ * */ -#include #include #include #include @@ -44,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -123,25 +121,26 @@ unsigned int backchain = 0; /* Debug flag */ * Allocate our initial context save areas. As soon as we do this, * we can take an interrupt. We do the saveareas here, 'cause they're guaranteed * to be at least page aligned. + * + * Note: these initial saveareas are all to be allocated from V=R, less than 4GB + * space. */ -void savearea_init(vm_offset_t *addrx) { +void savearea_init(vm_offset_t addr) { - savearea_comm *savec, *savec2, *saveprev; - vm_offset_t save, save2, addr; + savearea_comm *savec; + vm_offset_t save; int i; saveanchor.savetarget = InitialSaveTarget; /* Initial target value */ saveanchor.saveinuse = 0; /* Number of areas in use */ - saveanchor.savefree = 0; /* Remember the start of the free chain */ + saveanchor.savefree = 0; /* Remember the start of the free chain */ saveanchor.savefreecnt = 0; /* Remember the length */ - saveanchor.savepoolfwd = (unsigned int *)&saveanchor; /* Remember pool forward */ - saveanchor.savepoolbwd = (unsigned int *)&saveanchor; /* Remember pool backward */ - - addr = *addrx; /* Make this easier for ourselves */ + saveanchor.savepoolfwd = (addr64_t)&saveanchor; /* Remember pool forward */ + saveanchor.savepoolbwd = (addr64_t)&saveanchor; /* Remember pool backward */ save = addr; /* Point to the whole block of blocks */ @@ -150,7 +149,7 @@ void savearea_init(vm_offset_t *addrx) { */ - for(i=0; i < 8; i++) { /* Initialize the back pocket saveareas */ + for(i=0; i < BackPocketSaveBloks; i++) { /* Initialize the back pocket saveareas */ savec = (savearea_comm *)save; /* Get the control area for this one */ @@ -158,7 +157,7 @@ void savearea_init(vm_offset_t *addrx) { savec->sac_vrswap = 0; /* V=R, so the translation factor is 0 */ savec->sac_flags = sac_perm; /* Mark it permanent */ savec->sac_flags |= 0x0000EE00; /* Debug eyecatcher */ - save_queue((savearea *)savec); /* Add page to savearea lists */ + save_queue((uint32_t)savec >> 12); /* Add page to savearea lists */ save += PAGE_SIZE; /* Jump up to the next one now */ } @@ -175,8 +174,8 @@ void savearea_init(vm_offset_t *addrx) { saveanchor.savefree = 0; /* Remember the start of the free chain */ saveanchor.savefreecnt = 0; /* Remember the length */ saveanchor.saveadjust = 0; /* Set none needed yet */ - saveanchor.savepoolfwd = (unsigned int *)&saveanchor; /* Remember pool forward */ - saveanchor.savepoolbwd = (unsigned int *)&saveanchor; /* Remember pool backward */ + saveanchor.savepoolfwd = (addr64_t)&saveanchor; /* Remember pool forward */ + saveanchor.savepoolbwd = (addr64_t)&saveanchor; /* Remember pool backward */ for(i=0; i < InitialSaveBloks; i++) { /* Initialize the saveareas */ @@ -186,40 +185,37 @@ void savearea_init(vm_offset_t *addrx) { savec->sac_vrswap = 0; /* V=R, so the translation factor is 0 */ savec->sac_flags = sac_perm; /* Mark it permanent */ savec->sac_flags |= 0x0000EE00; /* Debug eyecatcher */ - save_queue((savearea *)savec); /* Add page to savearea lists */ + save_queue((uint32_t)savec >> 12); /* Add page to savearea lists */ save += PAGE_SIZE; /* Jump up to the next one now */ } - *addrx = save; /* Move the free storage lowwater mark */ - /* * We now have a free list that has our initial number of entries * The local qfret lists is empty. When we call save_get below it will see that * the local list is empty and fill it for us. * - * It is ok to call save_get_phys here because even though if we are translation on, we are still V=R and - * running with BAT registers so no interruptions. Regular interruptions will be off. Using save_get - * would be wrong if the tracing was enabled--it would cause an exception. + * It is ok to call save_get here because all initial saveareas are V=R in less + * than 4GB space, so 32-bit addressing is ok. + * */ - save2 = (vm_offset_t)save_get_phys(); /* This will populate the local list - and get the first one for the system */ - per_proc_info[0].next_savearea = (unsigned int)save2; /* Tell the exception handler about it */ - +/* + * This will populate the local list and get the first one for the system + */ + getPerProc()->next_savearea = (vm_offset_t)save_get(); + /* * The system is now able to take interruptions */ - return; - } /* - * Returns a savearea. If the free list needs size adjustment it happens here. + * Obtains a savearea. If the free list needs size adjustment it happens here. * Don't actually allocate the savearea until after the adjustment is done. */ @@ -267,15 +263,17 @@ void save_release(struct savearea *save) { /* Release a save area */ void save_adjust(void) { - savearea_comm *sctl, *sctlnext, *freepool, *freepage, *realpage; + savearea_comm *sctl, *sctlnext, *freepage; kern_return_t ret; + uint64_t vtopmask; + ppnum_t physpage; if(saveanchor.saveadjust < 0) { /* Do we need to adjust down? */ sctl = (savearea_comm *)save_trim_free(); /* Trim list to the need count, return start of trim list */ while(sctl) { /* Release the free pages back to the kernel */ - sctlnext = (savearea_comm *)sctl->save_prev; /* Get next in list */ + sctlnext = CAST_DOWN(savearea_comm *, sctl->save_prev); /* Get next in list */ kmem_free(kernel_map, (vm_offset_t) sctl, PAGE_SIZE); /* Release the page */ sctl = sctlnext; /* Chain onwards */ } @@ -291,15 +289,18 @@ void save_adjust(void) { panic("Whoops... Not a bit of wired memory left for saveareas\n"); } - realpage = (savearea_comm *)pmap_extract(kernel_pmap, (vm_offset_t)freepage); /* Get the physical */ + physpage = pmap_find_phys(kernel_pmap, (vm_offset_t)freepage); /* Find physical page */ + if(!physpage) { /* See if we actually have this mapped*/ + panic("save_adjust: wired page not mapped - va = %08X\n", freepage); /* Die */ + } bzero((void *)freepage, PAGE_SIZE); /* Clear it all to zeros */ freepage->sac_alloc = 0; /* Mark all entries taken */ - freepage->sac_vrswap = (unsigned int)freepage ^ (unsigned int)realpage; /* Form mask to convert V to R and vice versa */ + freepage->sac_vrswap = ((uint64_t)physpage << 12) ^ (uint64_t)((uintptr_t)freepage); /* XOR to calculate conversion mask */ freepage->sac_flags |= 0x0000EE00; /* Set debug eyecatcher */ - save_queue((savearea *)realpage); /* Add all saveareas on page to free list */ + save_queue(physpage); /* Add all saveareas on page to free list */ } } } @@ -307,7 +308,7 @@ void save_adjust(void) { /* * Fake up information to make the saveareas look like a zone */ - +void save_fake_zone_info(int *count, vm_size_t *cur_size, vm_size_t *max_size, vm_size_t *elem_size, vm_size_t *alloc_size, int *collectable, int *exhaustable) {