]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/hibernate_i386.c
xnu-2050.48.11.tar.gz
[apple/xnu.git] / osfmk / i386 / hibernate_i386.c
index f0507454ad9402a0a701875b7ee24bb76c324d25..83c33dba54db23cdd8dde4a21228be8ae10ff3a0 100644 (file)
@@ -1,31 +1,29 @@
 /*
  * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
+ * @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 
- * 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.
- *
- * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
- * Please see the License for the specific language governing rights and 
+ * 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.
+ * 
+ * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
  * limitations under the License.
- *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 #include <kern/machine.h>
 
 #include <IOKit/IOHibernatePrivate.h>
 #include <vm/vm_page.h>
-#include "i386_lowmem.h"
+#include <i386/i386_lowmem.h>
+
+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;
@@ -65,7 +65,7 @@ hibernate_page_list_allocate(void)
     hibernate_bitmap_t     dram_ranges[MAX_BANKS];
     boot_args *                    args = (boot_args *) PE_state.bootArgs;
 
-    mptr = args->MemoryMap;
+    mptr = (EfiMemoryRange *)ml_static_ptovirt(args->MemoryMap);
     if (args->MemoryMapDescriptorSize == 0)
        panic("Invalid memory map descriptor size");
     msize = args->MemoryMapDescriptorSize;
@@ -76,8 +76,13 @@ hibernate_page_list_allocate(void)
     {
        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)
        {
@@ -87,23 +92,41 @@ hibernate_page_list_allocate(void)
            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:
@@ -131,7 +154,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;
 
@@ -144,9 +167,8 @@ 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];
     }
 
@@ -158,6 +180,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)
 {
 }
@@ -170,10 +193,12 @@ hibernate_page_list_set_volatile( hibernate_page_list_t * page_list,
 {
     boot_args * args = (boot_args *) PE_state.bootArgs;
 
+#if !defined(x86_64)
     hibernate_set_page_state(page_list, page_list_wired, 
                I386_HIB_PAGETABLE, I386_HIB_PAGETABLE_COUNT, 
                kIOHibernatePageStateFree);
     *pagesOut -= I386_HIB_PAGETABLE_COUNT;
+#endif
 
     if (args->efiRuntimeServicesPageStart)
     {
@@ -194,6 +219,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);
 }
@@ -201,19 +229,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();
 }