X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/316670eb35587141e969394ae8537d66b9211e80..a1c7dba18ef36983396c282fe85292db066e39db:/osfmk/i386/i386_vm_init.c diff --git a/osfmk/i386/i386_vm_init.c b/osfmk/i386/i386_vm_init.c index 9a9735c5c..8a1d753b5 100644 --- a/osfmk/i386/i386_vm_init.c +++ b/osfmk/i386/i386_vm_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2008 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2003-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -54,7 +54,6 @@ * the rights to redistribute these changes. */ -#include #include @@ -78,11 +77,7 @@ #include #include #include -#ifdef __x86_64__ #include -#else -#include -#endif #include #include @@ -105,6 +100,16 @@ vm_offset_t vm_kernel_top; vm_offset_t vm_kernel_stext; vm_offset_t vm_kernel_etext; vm_offset_t vm_kernel_slide; +vm_offset_t vm_hib_base; +vm_offset_t vm_kext_base = VM_MIN_KERNEL_AND_KEXT_ADDRESS; +vm_offset_t vm_kext_top = VM_MIN_KERNEL_ADDRESS; + +vm_offset_t vm_prelink_stext; +vm_offset_t vm_prelink_etext; +vm_offset_t vm_prelink_sinfo; +vm_offset_t vm_prelink_einfo; +vm_offset_t vm_slinkedit; +vm_offset_t vm_elinkedit; #define MAXLORESERVE (32 * 1024 * 1024) @@ -135,6 +140,7 @@ vm_offset_t segTEXTB; unsigned long segSizeTEXT; vm_offset_t segDATAB; unsigned long segSizeDATA; vm_offset_t segLINKB; unsigned long segSizeLINK; vm_offset_t segPRELINKB; unsigned long segSizePRELINK; +vm_offset_t segPRELINKINFOB; unsigned long segSizePRELINKINFO; vm_offset_t segHIBB; unsigned long segSizeHIB; vm_offset_t sectCONSTB; unsigned long sectSizeConst; @@ -156,11 +162,8 @@ uint64_t firmware_MMIO_bytes; /* * Linker magic to establish the highest address in the kernel. - * This is replicated from libsa which marks last_kernel_symbol - * but that's not visible from here in osfmk. */ -__asm__(".zerofill __LAST, __last, _kernel_top, 0"); -extern void *kernel_top; +extern void *last_kernel_symbol; #if DEBUG #define PRINT_PMAP_MEMORY_TABLE @@ -183,7 +186,6 @@ i386_vm_init(uint64_t maxmem, unsigned int msize; ppnum_t fap; unsigned int i; - unsigned int safeboot; ppnum_t maxpg = 0; uint32_t pmap_type; uint32_t maxloreserve; @@ -192,7 +194,6 @@ i386_vm_init(uint64_t maxmem, boolean_t mbuf_override = FALSE; boolean_t coalescing_permitted; vm_kernel_base_page = i386_btop(args->kaddr); -#ifdef __x86_64__ vm_offset_t base_address; vm_offset_t static_base_address; @@ -238,8 +239,6 @@ i386_vm_init(uint64_t maxmem, } } -#endif // __x86_64__ - /* * Now retrieve addresses for end, edata, and etext * from MACH-O headers. @@ -254,6 +253,8 @@ i386_vm_init(uint64_t maxmem, "__HIB", &segSizeHIB); segPRELINKB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, "__PRELINK_TEXT", &segSizePRELINK); + segPRELINKINFOB = (vm_offset_t) getsegdatafromheader(&_mh_execute_header, + "__PRELINK_INFO", &segSizePRELINKINFO); segTEXT = getsegbynamefromheader(&_mh_execute_header, "__TEXT"); segDATA = getsegbynamefromheader(&_mh_execute_header, @@ -268,11 +269,10 @@ i386_vm_init(uint64_t maxmem, sHIB = segHIBB; eHIB = segHIBB + segSizeHIB; + vm_hib_base = sHIB; /* Zero-padded from ehib to stext if text is 2M-aligned */ stext = segTEXTB; -#ifdef __x86_64__ lowGlo.lgStext = stext; -#endif etext = (vm_offset_t) round_page_64(lastsectTEXT->addr + lastsectTEXT->size); /* Zero-padded from etext to sdata if text is 2M-aligned */ sdata = segDATAB; @@ -295,6 +295,7 @@ i386_vm_init(uint64_t maxmem, DBG("segLINKB = %p\n", (void *) segLINKB); DBG("segHIBB = %p\n", (void *) segHIBB); DBG("segPRELINKB = %p\n", (void *) segPRELINKB); + DBG("segPRELINKINFOB = %p\n", (void *) segPRELINKINFOB); DBG("sHIB = %p\n", (void *) sHIB); DBG("eHIB = %p\n", (void *) eHIB); DBG("stext = %p\n", (void *) stext); @@ -303,12 +304,18 @@ i386_vm_init(uint64_t maxmem, DBG("edata = %p\n", (void *) edata); DBG("sconstdata = %p\n", (void *) sconstdata); DBG("econstdata = %p\n", (void *) econstdata); - DBG("kernel_top = %p\n", (void *) &kernel_top); + DBG("kernel_top = %p\n", (void *) &last_kernel_symbol); vm_kernel_base = sHIB; - vm_kernel_top = (vm_offset_t) &kernel_top; + vm_kernel_top = (vm_offset_t) &last_kernel_symbol; vm_kernel_stext = stext; vm_kernel_etext = etext; + vm_prelink_stext = segPRELINKB; + vm_prelink_etext = segPRELINKB + segSizePRELINK; + vm_prelink_sinfo = segPRELINKINFOB; + vm_prelink_einfo = segPRELINKINFOB + segSizePRELINKINFO; + vm_slinkedit = segLINKB; + vm_elinkedit = segLINKB + segSizePRELINK; vm_set_page_size(); @@ -316,9 +323,6 @@ i386_vm_init(uint64_t maxmem, * Compute the memory size. */ - if ((1 == vm_himemory_mode) || PE_parse_boot_argn("-x", &safeboot, sizeof (safeboot))) { - maxpg = 1 << (32 - I386_PGSHIFT); - } avail_remaining = 0; avail_end = 0; pmptr = pmap_memory_regions; @@ -346,6 +350,32 @@ i386_vm_init(uint64_t maxmem, base = (ppnum_t) (mptr->PhysicalStart >> I386_PGSHIFT); top = (ppnum_t) (((mptr->PhysicalStart) >> I386_PGSHIFT) + mptr->NumberOfPages - 1); + if (base == 0) { + /* + * Avoid having to deal with the edge case of the + * very first possible physical page and the roll-over + * to -1; just ignore that page. + */ + kprintf("WARNING: ignoring first page in [0x%llx:0x%llx]\n", (uint64_t) base, (uint64_t) top); + base++; + } + if (top + 1 == 0) { + /* + * Avoid having to deal with the edge case of the + * very last possible physical page and the roll-over + * to 0; just ignore that page. + */ + kprintf("WARNING: ignoring last page in [0x%llx:0x%llx]\n", (uint64_t) base, (uint64_t) top); + top--; + } + if (top < base) { + /* + * That was the only page in that region, so + * ignore the whole region. + */ + continue; + } + #if MR_RSV_TEST static uint32_t nmr = 0; if ((base > 0x20000) && (nmr++ < 4)) @@ -472,14 +502,16 @@ i386_vm_init(uint64_t maxmem, if ((mptr->Attribute & EFI_MEMORY_KERN_RESERVED) && (top < vm_kernel_base_page)) { - pmptr->alloc = pmptr->base; + pmptr->alloc_up = pmptr->base; + pmptr->alloc_down = pmptr->end; pmap_reserved_range_indices[pmap_last_reserved_range_index++] = pmap_memory_region_count; } else { /* * mark as already mapped */ - pmptr->alloc = top; + pmptr->alloc_up = top + 1; + pmptr->alloc_down = top; } pmptr->type = pmap_type; pmptr->attribute = mptr->Attribute; @@ -491,7 +523,9 @@ i386_vm_init(uint64_t maxmem, * mark already allocated */ pmptr->base = base; - pmptr->alloc = pmptr->end = (fap - 1); + pmptr->end = (fap - 1); + pmptr->alloc_up = pmptr->end + 1; + pmptr->alloc_down = pmptr->end; pmptr->type = pmap_type; pmptr->attribute = mptr->Attribute; /* @@ -501,10 +535,10 @@ i386_vm_init(uint64_t maxmem, pmptr++; pmap_memory_region_count++; - pmptr->alloc = pmptr->base = fap; + pmptr->alloc_up = pmptr->base = fap; pmptr->type = pmap_type; pmptr->attribute = mptr->Attribute; - pmptr->end = top; + pmptr->alloc_down = pmptr->end = top; if (mptr->Attribute & EFI_MEMORY_KERN_RESERVED) pmap_reserved_range_indices[pmap_last_reserved_range_index++] = pmap_memory_region_count; @@ -512,10 +546,10 @@ i386_vm_init(uint64_t maxmem, /* * entire range useable */ - pmptr->alloc = pmptr->base = base; + pmptr->alloc_up = pmptr->base = base; pmptr->type = pmap_type; pmptr->attribute = mptr->Attribute; - pmptr->end = top; + pmptr->alloc_down = pmptr->end = top; if (mptr->Attribute & EFI_MEMORY_KERN_RESERVED) pmap_reserved_range_indices[pmap_last_reserved_range_index++] = pmap_memory_region_count; } @@ -531,12 +565,12 @@ i386_vm_init(uint64_t maxmem, if (prev_pmptr && (pmptr->type == prev_pmptr->type) && (coalescing_permitted) && - (pmptr->base == pmptr->alloc) && + (pmptr->base == pmptr->alloc_up) && + (prev_pmptr->end == prev_pmptr->alloc_down) && (pmptr->base == (prev_pmptr->end + 1))) { - if (prev_pmptr->end == prev_pmptr->alloc) - prev_pmptr->alloc = pmptr->base; prev_pmptr->end = pmptr->end; + prev_pmptr->alloc_down = pmptr->alloc_down; } else { pmap_memory_region_count++; prev_pmptr = pmptr; @@ -552,10 +586,11 @@ i386_vm_init(uint64_t maxmem, addr64_t region_start, region_end; addr64_t efi_start, efi_end; for (j=0;jtype, (addr64_t) p->base << I386_PGSHIFT, - (addr64_t) p->alloc << I386_PGSHIFT, + (addr64_t) p->alloc_up << I386_PGSHIFT, + (addr64_t) p->alloc_down << I386_PGSHIFT, (addr64_t) p->end << I386_PGSHIFT); region_start = (addr64_t) p->base << I386_PGSHIFT; region_end = ((addr64_t) p->end << I386_PGSHIFT) - 1; @@ -626,8 +661,10 @@ i386_vm_init(uint64_t maxmem, highest_pn = cur_end; pages_to_use--; } - if (pages_to_use == 0) + if (pages_to_use == 0) { pmap_memory_regions[cur_region].end = cur_end; + pmap_memory_regions[cur_region].alloc_down = cur_end; + } cur_region++; } @@ -669,7 +706,9 @@ i386_vm_init(uint64_t maxmem, else maxloreserve = MAXLORESERVE / PAGE_SIZE; +#if SOCKETS mbuf_reserve = bsd_mbuf_cluster_reserve(&mbuf_override) / PAGE_SIZE; +#endif } else maxloreserve = (maxloreserve * (1024 * 1024)) / PAGE_SIZE; @@ -717,8 +756,8 @@ pmap_next_page_reserved(ppnum_t *pn) { for (n = 0; n < pmap_last_reserved_range_index; n++) { uint32_t reserved_index = pmap_reserved_range_indices[n]; region = &pmap_memory_regions[reserved_index]; - if (region->alloc < region->end) { - *pn = region->alloc++; + if (region->alloc_up <= region->alloc_down) { + *pn = region->alloc_up++; avail_remaining--; if (*pn > max_ppnum) @@ -729,7 +768,7 @@ pmap_next_page_reserved(ppnum_t *pn) { pmap_reserved_pages_allocated++; #if DEBUG - if (region->alloc == region->end) { + if (region->alloc_up > region->alloc_down) { kprintf("Exhausted reserved range index: %u, base: 0x%x end: 0x%x, type: 0x%x, attribute: 0x%llx\n", reserved_index, region->base, region->end, region->type, region->attribute); } #endif @@ -755,8 +794,8 @@ pmap_next_page_hi( for (n = pmap_memory_region_count - 1; n >= 0; n--) { region = &pmap_memory_regions[n]; - if (region->alloc != region->end) { - *pn = region->alloc++; + if (region->alloc_down >= region->alloc_up) { + *pn = region->alloc_down--; avail_remaining--; if (*pn > max_ppnum) @@ -784,12 +823,12 @@ pmap_next_page( ppnum_t *pn) { if (avail_remaining) while (pmap_memory_region_current < pmap_memory_region_count) { - if (pmap_memory_regions[pmap_memory_region_current].alloc == - pmap_memory_regions[pmap_memory_region_current].end) { + if (pmap_memory_regions[pmap_memory_region_current].alloc_up > + pmap_memory_regions[pmap_memory_region_current].alloc_down) { pmap_memory_region_current++; continue; } - *pn = pmap_memory_regions[pmap_memory_region_current].alloc++; + *pn = pmap_memory_regions[pmap_memory_region_current].alloc_up++; avail_remaining--; if (*pn > max_ppnum)