* Copyright (c) 2004-2012 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
+ *
* 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
* 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.
- *
+ *
* 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,
* 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_OSREFERENCE_LICENSE_HEADER_END@
*/
extern ppnum_t max_ppnum;
-#define MAX_BANKS 32
+#define MAX_BANKS 32
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
hibernate_page_list_t *
hibernate_page_list_allocate(boolean_t log)
{
- ppnum_t base, num;
- vm_size_t size;
- uint32_t bank, num_banks;
- uint32_t pages, page_count;
- hibernate_page_list_t * list;
- hibernate_bitmap_t * bitmap;
-
- EfiMemoryRange * mptr;
- 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;
- ppnum_t pnmax = max_ppnum;
-
- mptr = (EfiMemoryRange *)ml_static_ptovirt(args->MemoryMap);
- if (args->MemoryMapDescriptorSize == 0)
- panic("Invalid memory map descriptor size");
- msize = args->MemoryMapDescriptorSize;
- mcount = args->MemoryMapSize / msize;
+ ppnum_t base, num;
+ vm_size_t size;
+ uint32_t bank, num_banks;
+ uint32_t pages, page_count;
+ hibernate_page_list_t * list;
+ hibernate_bitmap_t * bitmap;
+
+ EfiMemoryRange * mptr;
+ 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;
+ ppnum_t pnmax = max_ppnum;
+
+ mptr = (EfiMemoryRange *)ml_static_ptovirt(args->MemoryMap);
+ if (args->MemoryMapDescriptorSize == 0) {
+ panic("Invalid memory map descriptor size");
+ }
+ msize = args->MemoryMapDescriptorSize;
+ mcount = args->MemoryMapSize / msize;
#if KASAN
- /* adjust max page number to include stolen memory */
- if (atop(shadow_ptop) > pnmax) {
- pnmax = (ppnum_t)atop(shadow_ptop);
- }
+ /* adjust max page number to include stolen memory */
+ if (atop(shadow_ptop) > pnmax) {
+ pnmax = (ppnum_t)atop(shadow_ptop);
+ }
#endif
- 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;
+ 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 KASAN
- if (i == shadow_stolen_idx) {
- /*
- * Add all stolen pages to the bitmap. Later we will prune the unused
- * pages.
- */
- num += shadow_pages_total;
- }
+ if (i == shadow_stolen_idx) {
+ /*
+ * Add all stolen pages to the bitmap. Later we will prune the unused
+ * pages.
+ */
+ num += shadow_pages_total;
+ }
#endif
- if (base > pnmax)
- continue;
- if ((base + num - 1) > pnmax)
- num = pnmax - base + 1;
- if (!num)
- 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:
-
- for (bank = 0; bank < num_banks; bank++)
- {
- if (dram_ranges[bank].first_page <= base)
+ if (base > pnmax) {
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;
- bcopy(&dram_ranges[bank],
- &dram_ranges[bank + 1],
- (num_banks - bank - 1) * sizeof(hibernate_bitmap_t));
- dram_ranges[bank].first_page = base;
+ if ((base + num - 1) > pnmax) {
+ num = pnmax - base + 1;
+ }
+ if (!num) {
+ continue;
}
- 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:
- case kEfiMemoryMappedIO:
- case kEfiMemoryMappedIOPortSpace:
- default:
- break;
+
+ 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:
+
+ 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;
+ }
+ bcopy(&dram_ranges[bank],
+ &dram_ranges[bank + 1],
+ (num_banks - bank - 1) * sizeof(hibernate_bitmap_t));
+ dram_ranges[bank].first_page = base;
+ }
+ 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:
+ case kEfiMemoryMappedIO:
+ case kEfiMemoryMappedIOPortSpace:
+ default:
+ break;
+ }
+ }
+
+ if (num_banks >= MAX_BANKS) {
+ return NULL;
}
- }
-
- if (num_banks >= MAX_BANKS)
- return (NULL);
-
- // size the hibernation bitmap
-
- size = sizeof(hibernate_page_list_t);
- page_count = 0;
- for (bank = 0; bank < num_banks; bank++) {
- pages = dram_ranges[bank].last_page + 1 - dram_ranges[bank].first_page;
- page_count += pages;
- size += sizeof(hibernate_bitmap_t) + ((pages + 31) >> 5) * sizeof(uint32_t);
- }
-
- list = (hibernate_page_list_t *)kalloc(size);
- if (!list)
- return (list);
-
- list->list_size = (uint32_t)size;
- list->page_count = page_count;
- list->bank_count = num_banks;
-
- // convert to hibernation bitmap.
-
- bitmap = &list->bank_bitmap[0];
- for (bank = 0; bank < num_banks; bank++)
- {
- bitmap->first_page = dram_ranges[bank].first_page;
- bitmap->last_page = dram_ranges[bank].last_page;
- bitmap->bitmapwords = (bitmap->last_page + 1
- - bitmap->first_page + 31) >> 5;
- 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);
+
+ // size the hibernation bitmap
+
+ size = sizeof(hibernate_page_list_t);
+ page_count = 0;
+ for (bank = 0; bank < num_banks; bank++) {
+ pages = dram_ranges[bank].last_page + 1 - dram_ranges[bank].first_page;
+ page_count += pages;
+ size += sizeof(hibernate_bitmap_t) + ((pages + 31) >> 5) * sizeof(uint32_t);
+ }
+
+ list = (hibernate_page_list_t *)kalloc(size);
+ if (!list) {
+ return list;
+ }
+
+ list->list_size = (uint32_t)size;
+ list->page_count = page_count;
+ list->bank_count = num_banks;
+
+ // convert to hibernation bitmap.
+
+ bitmap = &list->bank_bitmap[0];
+ for (bank = 0; bank < num_banks; bank++) {
+ bitmap->first_page = dram_ranges[bank].first_page;
+ bitmap->last_page = dram_ranges[bank].last_page;
+ bitmap->bitmapwords = (bitmap->last_page + 1
+ - bitmap->first_page + 31) >> 5;
+ 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;
}
// mark pages not to be saved, but available for scratch usage during restore
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)
+ __unused hibernate_page_list_t * page_list_wired,
+ __unused boolean_t preflight,
+ __unused uint32_t * pagesOut)
{
}
// mark pages not to be saved and not for scratch usage during restore
void
hibernate_page_list_set_volatile( hibernate_page_list_t * page_list,
- hibernate_page_list_t * page_list_wired,
- uint32_t * pagesOut)
+ hibernate_page_list_t * page_list_wired,
+ uint32_t * pagesOut)
{
- boot_args * args = (boot_args *) PE_state.bootArgs;
+ boot_args * args = (boot_args *) PE_state.bootArgs;
- if (args->efiRuntimeServicesPageStart)
- {
- hibernate_set_page_state(page_list, page_list_wired,
- args->efiRuntimeServicesPageStart, args->efiRuntimeServicesPageCount,
+ if (args->efiRuntimeServicesPageStart) {
+ hibernate_set_page_state(page_list, page_list_wired,
+ args->efiRuntimeServicesPageStart, args->efiRuntimeServicesPageCount,
kIOHibernatePageStateFree);
- *pagesOut -= args->efiRuntimeServicesPageCount;
- }
+ *pagesOut -= args->efiRuntimeServicesPageCount;
+ }
}
-kern_return_t
+kern_return_t
hibernate_processor_setup(IOHibernateImageHeader * header)
{
- boot_args * args = (boot_args *) PE_state.bootArgs;
+ boot_args * args = (boot_args *) PE_state.bootArgs;
- cpu_datap(0)->cpu_hibernate = 1;
- header->processorFlags = 0;
+ cpu_datap(0)->cpu_hibernate = 1;
+ header->processorFlags = 0;
- header->runtimePages = args->efiRuntimeServicesPageStart;
- header->runtimePageCount = args->efiRuntimeServicesPageCount;
- header->runtimeVirtualPages = args->efiRuntimeServicesVirtualPageStart;
- header->performanceDataStart = args->performanceDataStart;
- header->performanceDataSize = args->performanceDataSize;
+ header->runtimePages = args->efiRuntimeServicesPageStart;
+ header->runtimePageCount = args->efiRuntimeServicesPageCount;
+ header->runtimeVirtualPages = args->efiRuntimeServicesVirtualPageStart;
+ header->performanceDataStart = args->performanceDataStart;
+ header->performanceDataSize = args->performanceDataSize;
- return (KERN_SUCCESS);
+ return KERN_SUCCESS;
}
static boolean_t hibernate_vm_locks_safe;
void
hibernate_vm_lock(void)
{
- if (current_cpu_datap()->cpu_hibernate) {
- hibernate_vm_lock_queues();
- hibernate_vm_locks_safe = TRUE;
- }
+ if (current_cpu_datap()->cpu_hibernate) {
+ hibernate_vm_lock_queues();
+ hibernate_vm_locks_safe = TRUE;
+ }
}
void
hibernate_vm_unlock(void)
{
- assert(FALSE == ml_get_interrupts_enabled());
- if (current_cpu_datap()->cpu_hibernate) hibernate_vm_unlock_queues();
- ml_set_is_quiescing(TRUE);
+ assert(FALSE == ml_get_interrupts_enabled());
+ if (current_cpu_datap()->cpu_hibernate) {
+ hibernate_vm_unlock_queues();
+ }
+ ml_set_is_quiescing(TRUE);
}
// ACPI calls hibernate_vm_lock(), interrupt disable, hibernate_vm_unlock() on sleep,
void
hibernate_vm_lock_end(void)
{
- assert(FALSE == ml_get_interrupts_enabled());
- hibernate_vm_locks_safe = FALSE;
- ml_set_is_quiescing(FALSE);
+ assert(FALSE == ml_get_interrupts_enabled());
+ hibernate_vm_locks_safe = FALSE;
+ ml_set_is_quiescing(FALSE);
}
boolean_t
hibernate_vm_locks_are_safe(void)
{
- assert(FALSE == ml_get_interrupts_enabled());
- return (hibernate_vm_locks_safe);
+ assert(FALSE == ml_get_interrupts_enabled());
+ return hibernate_vm_locks_safe;
}