X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/c0fea4742e91338fffdcf79f86a7c1d5e2b97eb1..143464d58d2bd6378e74eec636961ceb0d32fb91:/osfmk/i386/hibernate_i386.c diff --git a/osfmk/i386/hibernate_i386.c b/osfmk/i386/hibernate_i386.c index d8f14ea46..a16994234 100644 --- a/osfmk/i386/hibernate_i386.c +++ b/osfmk/i386/hibernate_i386.c @@ -1,23 +1,29 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004-2012 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ #include @@ -36,14 +42,16 @@ #include #include -#include "i386_lowmem.h" +#include + +extern ppnum_t max_ppnum; #define MAX_BANKS 32 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ hibernate_page_list_t * -hibernate_page_list_allocate(void) +hibernate_page_list_allocate(boolean_t log) { ppnum_t base, num; vm_size_t size; @@ -56,46 +64,74 @@ hibernate_page_list_allocate(void) uint32_t mcount, msize, i; hibernate_bitmap_t dram_ranges[MAX_BANKS]; boot_args * args = (boot_args *) PE_state.bootArgs; + uint32_t non_os_pagecount; - mptr = args->MemoryMap; + mptr = (EfiMemoryRange *)ml_static_ptovirt(args->MemoryMap); if (args->MemoryMapDescriptorSize == 0) panic("Invalid memory map descriptor size"); msize = args->MemoryMapDescriptorSize; mcount = args->MemoryMapSize / msize; num_banks = 0; + non_os_pagecount = 0; for (i = 0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) { base = (ppnum_t) (mptr->PhysicalStart >> I386_PGSHIFT); num = (ppnum_t) mptr->NumberOfPages; + + if (base > max_ppnum) + continue; + if ((base + num - 1) > max_ppnum) + num = max_ppnum - base + 1; if (!num) - continue; + continue; switch (mptr->Type) { // any kind of dram + case kEfiACPIMemoryNVS: + case kEfiPalCode: + non_os_pagecount += num; + + // OS used dram case kEfiLoaderCode: case kEfiLoaderData: case kEfiBootServicesCode: case kEfiBootServicesData: case kEfiConventionalMemory: - case kEfiACPIReclaimMemory: - case kEfiACPIMemoryNVS: - case kEfiPalCode: - if (!num_banks || (base != (1 + dram_ranges[num_banks - 1].last_page))) + for (bank = 0; bank < num_banks; bank++) + { + if (dram_ranges[bank].first_page <= base) + continue; + if ((base + num) == dram_ranges[bank].first_page) + { + dram_ranges[bank].first_page = base; + num = 0; + } + break; + } + if (!num) break; + + if (bank && (base == (1 + dram_ranges[bank - 1].last_page))) + bank--; + else { num_banks++; - if (num_banks >= MAX_BANKS) - break; - dram_ranges[num_banks - 1].first_page = base; + if (num_banks >= MAX_BANKS) break; + bcopy(&dram_ranges[bank], + &dram_ranges[bank + 1], + (num_banks - bank - 1) * sizeof(hibernate_bitmap_t)); + dram_ranges[bank].first_page = base; } - dram_ranges[num_banks - 1].last_page = base + num - 1; + dram_ranges[bank].last_page = base + num - 1; break; // runtime services will be restarted, so no save case kEfiRuntimeServicesCode: case kEfiRuntimeServicesData: + // contents are volatile once the platform expert starts + case kEfiACPIReclaimMemory: // non dram case kEfiReservedMemoryType: case kEfiUnusableMemory: @@ -123,7 +159,7 @@ hibernate_page_list_allocate(void) if (!list) return (list); - list->list_size = size; + list->list_size = (uint32_t)size; list->page_count = page_count; list->bank_count = num_banks; @@ -136,11 +172,11 @@ hibernate_page_list_allocate(void) bitmap->last_page = dram_ranges[bank].last_page; bitmap->bitmapwords = (bitmap->last_page + 1 - bitmap->first_page + 31) >> 5; - kprintf("hib bank[%d]: 0x%x000 end 0x%xfff\n", bank, - bitmap->first_page, - bitmap->last_page); + if (log) kprintf("hib bank[%d]: 0x%x000 end 0x%xfff\n", + bank, bitmap->first_page, bitmap->last_page); bitmap = (hibernate_bitmap_t *) &bitmap->bitmap[bitmap->bitmapwords]; } + if (log) printf("efi pagecount %d\n", non_os_pagecount); return (list); } @@ -150,6 +186,7 @@ hibernate_page_list_allocate(void) void hibernate_page_list_setall_machine( __unused hibernate_page_list_t * page_list, __unused hibernate_page_list_t * page_list_wired, + __unused boolean_t preflight, __unused uint32_t * pagesOut) { } @@ -162,11 +199,6 @@ hibernate_page_list_set_volatile( hibernate_page_list_t * page_list, { boot_args * args = (boot_args *) PE_state.bootArgs; - hibernate_set_page_state(page_list, page_list_wired, - I386_HIB_PAGETABLE, I386_HIB_PAGETABLE_COUNT, - kIOHibernatePageStateFree); - *pagesOut -= I386_HIB_PAGETABLE_COUNT; - if (args->efiRuntimeServicesPageStart) { hibernate_set_page_state(page_list, page_list_wired, @@ -186,6 +218,9 @@ hibernate_processor_setup(IOHibernateImageHeader * header) header->runtimePages = args->efiRuntimeServicesPageStart; header->runtimePageCount = args->efiRuntimeServicesPageCount; + header->runtimeVirtualPages = args->efiRuntimeServicesVirtualPageStart; + header->performanceDataStart = args->performanceDataStart; + header->performanceDataSize = args->performanceDataSize; return (KERN_SUCCESS); } @@ -193,19 +228,11 @@ hibernate_processor_setup(IOHibernateImageHeader * header) void hibernate_vm_lock(void) { - if (current_cpu_datap()->cpu_hibernate) - { - vm_page_lock_queues(); - mutex_lock(&vm_page_queue_free_lock); - } + if (current_cpu_datap()->cpu_hibernate) hibernate_vm_lock_queues(); } void hibernate_vm_unlock(void) { - if (current_cpu_datap()->cpu_hibernate) - { - mutex_unlock(&vm_page_queue_free_lock); - vm_page_unlock_queues(); - } + if (current_cpu_datap()->cpu_hibernate) hibernate_vm_unlock_queues(); }