]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/hibernate_i386.c
   2  * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29 #include <kern/machine.h> 
  30 #include <kern/misc_protos.h> 
  31 #include <kern/thread.h> 
  32 #include <kern/processor.h> 
  33 #include <kern/kalloc.h> 
  34 #include <mach/machine.h> 
  35 #include <mach/processor_info.h> 
  36 #include <mach/mach_types.h> 
  37 #include <i386/pmap.h> 
  38 #include <kern/cpu_data.h> 
  39 #include <IOKit/IOPlatformExpert.h> 
  42 #include <IOKit/IOHibernatePrivate.h> 
  43 #include <vm/vm_page.h> 
  45 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 
  48  * - we never will want to read or write memory below the start of kernel text 
  49  * - kernel text and data isn't included in pmap memory regions 
  52 extern void *sectTEXTB
; 
  53 extern char             *first_avail
; 
  55 hibernate_page_list_t 
* 
  56 hibernate_page_list_allocate(void) 
  61     uint32_t                pages
, page_count
; 
  62     hibernate_page_list_t 
* list
; 
  63     hibernate_bitmap_t 
*    bitmap
; 
  64     pmap_memory_region_t 
*  regions
; 
  65     pmap_memory_region_t 
*  rp
; 
  66     uint32_t                num_regions
, num_alloc_regions
; 
  70     /* Make a list of the maximum number of regions needed */ 
  71     num_alloc_regions 
= 1 + pmap_memory_region_count
; 
  73     /* Allocate our own list of memory regions so we can sort them in order. */ 
  74     regions 
= (pmap_memory_region_t 
*)kalloc(sizeof(pmap_memory_region_t
) * num_alloc_regions
); 
  78     /* Fill in the actual regions we will be returning. */ 
  81     /* XXX should check for non-volatile memory region below kernel space. */ 
  82     /* Kernel region is first. */ 
  83     base 
= (vm_offset_t
)(sectTEXTB
) & 0x3FFFFFFF; 
  84     rp
->base 
= atop_32(base
); 
  85     rp
->end 
= atop_32((vm_offset_t
)first_avail
) - 1; 
  89     /* Remaining memory regions.  Consolidate adjacent regions. */ 
  90     for (bank 
= 0; bank 
< (uint32_t) pmap_memory_region_count
; bank
++) 
  92         if ((rp
->end 
+ 1) == pmap_memory_regions
[bank
].base
) { 
  93             rp
->end 
= pmap_memory_regions
[bank
].end
; 
  97             rp
->base 
= pmap_memory_regions
[bank
].base
; 
  98             rp
->end 
= pmap_memory_regions
[bank
].end
; 
 103     /* Size the hibernation bitmap */ 
 104     size 
= sizeof(hibernate_page_list_t
); 
 106     for (bank 
= 0, rp 
= regions
; bank 
< num_regions
; bank
++, rp
++) { 
 107         pages 
= rp
->end 
+ 1 - rp
->base
; 
 109         size 
+= sizeof(hibernate_bitmap_t
) + ((pages 
+ 31) >> 5) * sizeof(uint32_t); 
 112     list 
= (hibernate_page_list_t 
*)kalloc(size
); 
 116     list
->list_size  
= size
; 
 117     list
->page_count 
= page_count
; 
 118     list
->bank_count 
= num_regions
; 
 120     /* Convert to hibernation bitmap. */ 
 121     /* This assumes that ranges are in order and do not overlap. */ 
 122     bitmap 
= &list
->bank_bitmap
[0]; 
 123     for (bank 
= 0, rp 
= regions
; bank 
< num_regions
; bank
++, rp
++) { 
 124         bitmap
->first_page 
= rp
->base
; 
 125         bitmap
->last_page 
= rp
->end
; 
 126         bitmap
->bitmapwords 
= (bitmap
->last_page 
+ 1 
 127                                - bitmap
->first_page 
+ 31) >> 5; 
 128         kprintf("HIB: Bank %d: 0x%x end 0x%x\n", bank
, 
 129                 ptoa_32(bitmap
->first_page
), 
 130                 ptoa_32(bitmap
->last_page
)); 
 131         bitmap 
= (hibernate_bitmap_t 
*) &bitmap
->bitmap
[bitmap
->bitmapwords
]; 
 134     kfree((void *)regions
, sizeof(pmap_memory_region_t
) * num_alloc_regions
); 
 139 hibernate_page_list_setall_machine(hibernate_page_list_t 
* page_list
, 
 140                                    hibernate_page_list_t 
* page_list_wired
, 
 143     KernelBootArgs_t 
*      bootArgs 
= (KernelBootArgs_t 
*)PE_state
.bootArgs
; 
 146     uint32_t                page
, count
; 
 148     for (bank 
= 0, mptr 
= bootArgs
->memoryMap
; bank 
< bootArgs
->memoryMapCount
; bank
++, mptr
++) { 
 150         if (kMemoryRangeNVS 
!= mptr
->type
) continue; 
 151         kprintf("Base NVS region 0x%x + 0x%x\n", (vm_offset_t
)mptr
->base
, (vm_size_t
)mptr
->length
); 
 152         /* Round to page size.  Hopefully this does not overlap any reserved areas. */ 
 153         page 
= atop_32(trunc_page((vm_offset_t
)mptr
->base
)); 
 154         count 
= atop_32(round_page((vm_offset_t
)mptr
->base 
+ (vm_size_t
)mptr
->length
)) - page
; 
 155         kprintf("Rounded NVS region 0x%x size 0x%x\n", page
, count
); 
 157         hibernate_set_page_state(page_list
, page_list_wired
, page
, count
, 1); 
 163 hibernate_processor_setup(IOHibernateImageHeader 
* header
) 
 165     current_cpu_datap()->cpu_hibernate 
= 1; 
 166     header
->processorFlags 
= 0; 
 167     return (KERN_SUCCESS
); 
 171 hibernate_vm_lock(void) 
 173     if (FALSE 
/* getPerProc()->hibernate */) 
 175         vm_page_lock_queues(); 
 176         mutex_lock(&vm_page_queue_free_lock
); 
 181 hibernate_vm_unlock(void) 
 183     if (FALSE 
/* getPerProc()->hibernate */) 
 185         mutex_unlock(&vm_page_queue_free_lock
); 
 186         vm_page_unlock_queues();