]>
Commit | Line | Data |
---|---|---|
3a60a9f5 A |
1 | /* |
2 | * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. | |
3 | * | |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
3a60a9f5 | 5 | * |
2d21ac55 A |
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. | |
8f6c56a5 | 14 | * |
2d21ac55 A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
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 | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
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. | |
8f6c56a5 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
3a60a9f5 A |
27 | */ |
28 | ||
29 | #include <stdint.h> | |
30 | ||
31 | #ifdef __cplusplus | |
32 | extern "C" { | |
33 | #endif | |
34 | ||
35 | #ifdef KERNEL | |
36 | #include <crypto/aes.h> | |
6d2010ae | 37 | #include <uuid/uuid.h> |
3a60a9f5 A |
38 | #endif |
39 | ||
40 | struct IOPolledFileExtent | |
41 | { | |
42 | uint64_t start; | |
43 | uint64_t length; | |
44 | }; | |
45 | typedef struct IOPolledFileExtent IOPolledFileExtent; | |
46 | ||
47 | struct IOHibernateImageHeader | |
48 | { | |
49 | uint64_t imageSize; | |
50 | uint64_t image1Size; | |
51 | ||
6d2010ae A |
52 | uint32_t restore1CodePhysPage; |
53 | uint32_t reserved1; | |
54 | uint64_t restore1CodeVirt; | |
3a60a9f5 A |
55 | uint32_t restore1PageCount; |
56 | uint32_t restore1CodeOffset; | |
57 | uint32_t restore1StackOffset; | |
58 | ||
59 | uint32_t pageCount; | |
60 | uint32_t bitmapSize; | |
61 | ||
62 | uint32_t restore1Sum; | |
63 | uint32_t image1Sum; | |
64 | uint32_t image2Sum; | |
65 | ||
66 | uint32_t actualRestore1Sum; | |
67 | uint32_t actualImage1Sum; | |
68 | uint32_t actualImage2Sum; | |
69 | ||
70 | uint32_t actualUncompressedPages; | |
71 | uint32_t conflictCount; | |
72 | uint32_t nextFree; | |
73 | ||
74 | uint32_t signature; | |
75 | uint32_t processorFlags; | |
76 | ||
0c530ab8 A |
77 | uint32_t runtimePages; |
78 | uint32_t runtimePageCount; | |
b0d623f7 | 79 | uint64_t runtimeVirtualPages __attribute__ ((packed)); |
d1ecb069 A |
80 | |
81 | uint32_t performanceDataStart; | |
82 | uint32_t performanceDataSize; | |
3a60a9f5 | 83 | |
b0d623f7 A |
84 | uint64_t encryptStart __attribute__ ((packed)); |
85 | uint64_t machineSignature __attribute__ ((packed)); | |
3a60a9f5 A |
86 | |
87 | uint32_t previewSize; | |
88 | uint32_t previewPageListSize; | |
89 | ||
90 | uint32_t diag[4]; | |
91 | ||
6d2010ae A |
92 | uint32_t handoffPages; |
93 | uint32_t handoffPageCount; | |
94 | ||
0c530ab8 A |
95 | uint32_t systemTableOffset; |
96 | ||
b0d623f7 | 97 | uint32_t debugFlags; |
0b4c1975 | 98 | uint32_t options; |
b0d623f7 | 99 | |
6d2010ae | 100 | uint32_t reserved[70]; // make sizeof == 512 |
0b4c1975 A |
101 | |
102 | uint64_t encryptEnd __attribute__ ((packed)); | |
103 | uint64_t deviceBase __attribute__ ((packed)); | |
3a60a9f5 A |
104 | |
105 | uint32_t fileExtentMapSize; | |
106 | IOPolledFileExtent fileExtentMap[2]; | |
107 | }; | |
108 | typedef struct IOHibernateImageHeader IOHibernateImageHeader; | |
109 | ||
b0d623f7 A |
110 | enum |
111 | { | |
112 | kIOHibernateDebugRestoreLogs = 0x00000001 | |
113 | }; | |
3a60a9f5 | 114 | |
0b4c1975 A |
115 | // options & IOHibernateOptions property |
116 | enum | |
117 | { | |
118 | kIOHibernateOptionSSD = 0x00000001, | |
119 | kIOHibernateOptionColor = 0x00000002, | |
120 | kIOHibernateOptionProgress = 0x00000004, | |
121 | kIOHibernateOptionDarkWake = 0x00000008, | |
122 | }; | |
123 | ||
3a60a9f5 A |
124 | struct hibernate_bitmap_t |
125 | { | |
126 | uint32_t first_page; | |
127 | uint32_t last_page; | |
128 | uint32_t bitmapwords; | |
129 | uint32_t bitmap[0]; | |
130 | }; | |
131 | typedef struct hibernate_bitmap_t hibernate_bitmap_t; | |
132 | ||
133 | struct hibernate_page_list_t | |
134 | { | |
135 | uint32_t list_size; | |
136 | uint32_t page_count; | |
137 | uint32_t bank_count; | |
138 | hibernate_bitmap_t bank_bitmap[0]; | |
139 | }; | |
140 | typedef struct hibernate_page_list_t hibernate_page_list_t; | |
141 | ||
2d21ac55 A |
142 | #if defined(_AES_H) |
143 | ||
3a60a9f5 A |
144 | struct hibernate_cryptwakevars_t |
145 | { | |
3a60a9f5 | 146 | uint8_t aes_iv[AES_BLOCK_SIZE]; |
3a60a9f5 A |
147 | }; |
148 | typedef struct hibernate_cryptwakevars_t hibernate_cryptwakevars_t; | |
149 | ||
150 | struct hibernate_cryptvars_t | |
151 | { | |
3a60a9f5 A |
152 | uint8_t aes_iv[AES_BLOCK_SIZE]; |
153 | aes_ctx ctx; | |
3a60a9f5 A |
154 | }; |
155 | typedef struct hibernate_cryptvars_t hibernate_cryptvars_t; | |
156 | ||
2d21ac55 A |
157 | #endif /* defined(_AES_H) */ |
158 | ||
6d2010ae A |
159 | enum |
160 | { | |
161 | kIOHibernateHandoffType = 0x686f0000, | |
162 | kIOHibernateHandoffTypeEnd = kIOHibernateHandoffType + 0, | |
163 | kIOHibernateHandoffTypeGraphicsInfo = kIOHibernateHandoffType + 1, | |
164 | kIOHibernateHandoffTypeCryptVars = kIOHibernateHandoffType + 2, | |
165 | kIOHibernateHandoffTypeMemoryMap = kIOHibernateHandoffType + 3, | |
166 | kIOHibernateHandoffTypeDeviceTree = kIOHibernateHandoffType + 4, | |
167 | kIOHibernateHandoffTypeDeviceProperties = kIOHibernateHandoffType + 5, | |
168 | kIOHibernateHandoffTypeKeyStore = kIOHibernateHandoffType + 6, | |
169 | }; | |
170 | ||
171 | struct IOHibernateHandoff | |
172 | { | |
173 | uint32_t type; | |
174 | uint32_t bytecount; | |
175 | uint8_t data[]; | |
176 | }; | |
177 | typedef struct IOHibernateHandoff IOHibernateHandoff; | |
3a60a9f5 A |
178 | |
179 | enum | |
180 | { | |
181 | kIOHibernateProgressCount = 19, | |
182 | kIOHibernateProgressWidth = 7, | |
183 | kIOHibernateProgressHeight = 16, | |
184 | kIOHibernateProgressSpacing = 3, | |
185 | kIOHibernateProgressOriginY = 81, | |
186 | ||
187 | kIOHibernateProgressSaveUnderSize = 2*5+14*2, | |
188 | ||
189 | kIOHibernateProgressLightGray = 230, | |
190 | kIOHibernateProgressMidGray = 174, | |
191 | kIOHibernateProgressDarkGray = 92 | |
192 | }; | |
193 | ||
2d21ac55 A |
194 | enum |
195 | { | |
196 | kIOHibernatePostWriteSleep = 0, | |
197 | kIOHibernatePostWriteWake = 1, | |
198 | kIOHibernatePostWriteHalt = 2, | |
199 | kIOHibernatePostWriteRestart = 3 | |
200 | }; | |
201 | ||
202 | ||
3a60a9f5 A |
203 | struct hibernate_graphics_t |
204 | { | |
0b4c1975 A |
205 | uint32_t physicalAddress; // Base address of video memory |
206 | int32_t gfxStatus; // EFI config restore status | |
0c530ab8 A |
207 | uint32_t rowBytes; // Number of bytes per pixel row |
208 | uint32_t width; // Width | |
209 | uint32_t height; // Height | |
210 | uint32_t depth; // Pixel Depth | |
211 | ||
212 | uint8_t progressSaveUnder[kIOHibernateProgressCount][kIOHibernateProgressSaveUnderSize]; | |
3a60a9f5 A |
213 | }; |
214 | typedef struct hibernate_graphics_t hibernate_graphics_t; | |
215 | ||
216 | #define DECLARE_IOHIBERNATEPROGRESSALPHA \ | |
217 | static const uint8_t gIOHibernateProgressAlpha \ | |
218 | [kIOHibernateProgressHeight][kIOHibernateProgressWidth] = \ | |
219 | { \ | |
220 | { 0x00,0x63,0xd8,0xf0,0xd8,0x63,0x00 }, \ | |
221 | { 0x51,0xff,0xff,0xff,0xff,0xff,0x51 }, \ | |
222 | { 0xae,0xff,0xff,0xff,0xff,0xff,0xae }, \ | |
223 | { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 }, \ | |
224 | { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 }, \ | |
225 | { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 }, \ | |
226 | { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 }, \ | |
227 | { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 }, \ | |
228 | { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 }, \ | |
229 | { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 }, \ | |
230 | { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 }, \ | |
231 | { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 }, \ | |
232 | { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 }, \ | |
233 | { 0xae,0xff,0xff,0xff,0xff,0xff,0xae }, \ | |
234 | { 0x54,0xff,0xff,0xff,0xff,0xff,0x54 }, \ | |
235 | { 0x00,0x66,0xdb,0xf3,0xdb,0x66,0x00 } \ | |
236 | }; | |
237 | ||
238 | #ifdef KERNEL | |
239 | ||
240 | #ifdef __cplusplus | |
241 | ||
242 | void IOHibernateSystemInit(IOPMrootDomain * rootDomain); | |
243 | ||
244 | IOReturn IOHibernateSystemSleep(void); | |
245 | IOReturn IOHibernateSystemHasSlept(void); | |
246 | IOReturn IOHibernateSystemWake(void); | |
247 | IOReturn IOHibernateSystemPostWake(void); | |
248 | ||
249 | #endif /* __cplusplus */ | |
250 | ||
251 | #ifdef _SYS_CONF_H_ | |
252 | typedef void (*kern_get_file_extents_callback_t)(void * ref, uint64_t start, uint64_t size); | |
253 | ||
254 | struct kern_direct_file_io_ref_t * | |
255 | kern_open_file_for_direct_io(const char * name, | |
256 | kern_get_file_extents_callback_t callback, | |
6d2010ae A |
257 | void * callback_ref, |
258 | dev_t * partition_device_result, | |
259 | dev_t * image_device_result, | |
260 | uint64_t * partitionbase_result, | |
261 | uint64_t * maxiocount_result, | |
262 | uint32_t * oflags, | |
263 | off_t offset, | |
264 | caddr_t addr, | |
265 | vm_size_t len); | |
0b4c1975 A |
266 | |
267 | ||
3a60a9f5 | 268 | void |
6d2010ae A |
269 | kern_close_file_for_direct_io(struct kern_direct_file_io_ref_t * ref, |
270 | off_t offset, caddr_t addr, vm_size_t len); | |
3a60a9f5 A |
271 | int |
272 | kern_write_file(struct kern_direct_file_io_ref_t * ref, off_t offset, caddr_t addr, vm_size_t len); | |
2d21ac55 | 273 | int get_kernel_symfile(struct proc *p, char const **symfile); |
3a60a9f5 A |
274 | #endif /* _SYS_CONF_H_ */ |
275 | ||
276 | hibernate_page_list_t * | |
277 | hibernate_page_list_allocate(void); | |
278 | ||
279 | kern_return_t | |
280 | hibernate_setup(IOHibernateImageHeader * header, | |
0b4c1975 A |
281 | uint32_t free_page_ratio, |
282 | uint32_t free_page_time, | |
283 | boolean_t vmflush, | |
3a60a9f5 A |
284 | hibernate_page_list_t ** page_list_ret, |
285 | hibernate_page_list_t ** page_list_wired_ret, | |
6d2010ae | 286 | hibernate_page_list_t ** page_list_pal_ret, |
3a60a9f5 A |
287 | boolean_t * encryptedswap); |
288 | kern_return_t | |
289 | hibernate_teardown(hibernate_page_list_t * page_list, | |
290 | hibernate_page_list_t * page_list_wired); | |
291 | ||
292 | kern_return_t | |
293 | hibernate_processor_setup(IOHibernateImageHeader * header); | |
294 | ||
b0d623f7 A |
295 | void |
296 | hibernate_gobble_pages(uint32_t gobble_count, uint32_t free_page_time); | |
297 | void | |
298 | hibernate_free_gobble_pages(void); | |
299 | ||
3a60a9f5 A |
300 | void |
301 | hibernate_vm_lock(void); | |
302 | void | |
303 | hibernate_vm_unlock(void); | |
304 | ||
0c530ab8 | 305 | // mark pages not to be saved, based on VM system accounting |
3a60a9f5 A |
306 | void |
307 | hibernate_page_list_setall(hibernate_page_list_t * page_list, | |
308 | hibernate_page_list_t * page_list_wired, | |
6d2010ae | 309 | hibernate_page_list_t * page_list_pal, |
3a60a9f5 A |
310 | uint32_t * pagesOut); |
311 | ||
0c530ab8 A |
312 | // mark pages to be saved, or pages not to be saved but available |
313 | // for scratch usage during restore | |
3a60a9f5 A |
314 | void |
315 | hibernate_page_list_setall_machine(hibernate_page_list_t * page_list, | |
316 | hibernate_page_list_t * page_list_wired, | |
317 | uint32_t * pagesOut); | |
0c530ab8 A |
318 | |
319 | // mark pages not to be saved and not for scratch usage during restore | |
320 | void | |
321 | hibernate_page_list_set_volatile( hibernate_page_list_t * page_list, | |
322 | hibernate_page_list_t * page_list_wired, | |
323 | uint32_t * pagesOut); | |
324 | ||
3a60a9f5 A |
325 | void |
326 | hibernate_page_list_discard(hibernate_page_list_t * page_list); | |
327 | ||
0b4c1975 A |
328 | int |
329 | hibernate_should_abort(void); | |
330 | ||
3a60a9f5 A |
331 | void |
332 | hibernate_set_page_state(hibernate_page_list_t * page_list, hibernate_page_list_t * page_list_wired, | |
333 | vm_offset_t ppnum, vm_offset_t count, uint32_t kind); | |
334 | ||
335 | void | |
336 | hibernate_page_bitset(hibernate_page_list_t * list, boolean_t set, uint32_t page); | |
0c530ab8 | 337 | |
3a60a9f5 A |
338 | boolean_t |
339 | hibernate_page_bittst(hibernate_page_list_t * list, uint32_t page); | |
340 | ||
0c530ab8 A |
341 | hibernate_bitmap_t * |
342 | hibernate_page_bitmap_pin(hibernate_page_list_t * list, uint32_t * page); | |
343 | ||
3a60a9f5 | 344 | uint32_t |
0c530ab8 | 345 | hibernate_page_bitmap_count(hibernate_bitmap_t * bitmap, uint32_t set, uint32_t page); |
3a60a9f5 | 346 | |
6d2010ae | 347 | uintptr_t |
3a60a9f5 A |
348 | hibernate_restore_phys_page(uint64_t src, uint64_t dst, uint32_t len, uint32_t procFlags); |
349 | ||
350 | void | |
351 | hibernate_machine_init(void); | |
2d21ac55 A |
352 | |
353 | uint32_t | |
3a60a9f5 A |
354 | hibernate_write_image(void); |
355 | ||
356 | long | |
357 | hibernate_machine_entrypoint(IOHibernateImageHeader * header, void * p2, void * p3, void * p4); | |
358 | long | |
359 | hibernate_kernel_entrypoint(IOHibernateImageHeader * header, void * p2, void * p3, void * p4); | |
0c530ab8 A |
360 | void |
361 | hibernate_newruntime_map(void * map, vm_size_t map_size, | |
362 | uint32_t system_table_offset); | |
363 | ||
3a60a9f5 A |
364 | |
365 | extern uint32_t gIOHibernateState; | |
366 | extern uint32_t gIOHibernateMode; | |
b0d623f7 | 367 | extern uint32_t gIOHibernateDebugFlags; |
3a60a9f5 A |
368 | extern uint32_t gIOHibernateFreeTime; // max time to spend freeing pages (ms) |
369 | extern uint8_t gIOHibernateRestoreStack[]; | |
370 | extern uint8_t gIOHibernateRestoreStackEnd[]; | |
371 | extern IOHibernateImageHeader * gIOHibernateCurrentHeader; | |
3a60a9f5 A |
372 | |
373 | #define HIBLOG(fmt, args...) \ | |
374 | { kprintf(fmt, ## args); printf(fmt, ## args); } | |
375 | ||
376 | #define HIBPRINT(fmt, args...) \ | |
377 | { kprintf(fmt, ## args); } | |
378 | ||
379 | #endif /* KERNEL */ | |
380 | ||
381 | // gIOHibernateState, kIOHibernateStateKey | |
382 | enum | |
383 | { | |
384 | kIOHibernateStateInactive = 0, | |
385 | kIOHibernateStateHibernating = 1, /* writing image */ | |
386 | kIOHibernateStateWakingFromHibernate = 2 /* booted and restored image */ | |
387 | }; | |
388 | ||
389 | // gIOHibernateMode, kIOHibernateModeKey | |
390 | enum | |
391 | { | |
392 | kIOHibernateModeOn = 0x00000001, | |
393 | kIOHibernateModeSleep = 0x00000002, | |
394 | kIOHibernateModeEncrypt = 0x00000004, | |
3a60a9f5 | 395 | kIOHibernateModeDiscardCleanInactive = 0x00000008, |
2d21ac55 A |
396 | kIOHibernateModeDiscardCleanActive = 0x00000010, |
397 | kIOHibernateModeSwitch = 0x00000020, | |
0b4c1975 A |
398 | kIOHibernateModeRestart = 0x00000040, |
399 | kIOHibernateModeSSDInvert = 0x00000080, | |
3a60a9f5 A |
400 | }; |
401 | ||
402 | // IOHibernateImageHeader.signature | |
403 | enum | |
404 | { | |
405 | kIOHibernateHeaderSignature = 0x73696d65, | |
406 | kIOHibernateHeaderInvalidSignature = 0x7a7a7a7a | |
407 | }; | |
408 | ||
409 | // kind for hibernate_set_page_state() | |
410 | enum | |
411 | { | |
412 | kIOHibernatePageStateFree = 0, | |
413 | kIOHibernatePageStateWiredSave = 1, | |
414 | kIOHibernatePageStateUnwiredSave = 2 | |
415 | }; | |
416 | ||
417 | #define kIOHibernateModeKey "Hibernate Mode" | |
418 | #define kIOHibernateFileKey "Hibernate File" | |
419 | #define kIOHibernateFreeRatioKey "Hibernate Free Ratio" | |
420 | #define kIOHibernateFreeTimeKey "Hibernate Free Time" | |
421 | ||
422 | #define kIOHibernateStateKey "IOHibernateState" | |
423 | #define kIOHibernateFeatureKey "Hibernation" | |
424 | #define kIOHibernatePreviewBufferKey "IOPreviewBuffer" | |
425 | ||
2d21ac55 A |
426 | #define kIOHibernatePreviewActiveKey "IOHibernatePreviewActive" |
427 | // values for kIOHibernatePreviewActiveKey | |
428 | enum { | |
429 | kIOHibernatePreviewActive = 0x00000001, | |
430 | kIOHibernatePreviewUpdates = 0x00000002 | |
431 | }; | |
432 | ||
0b4c1975 A |
433 | #define kIOHibernateOptionsKey "IOHibernateOptions" |
434 | #define kIOHibernateGfxStatusKey "IOHibernateGfxStatus" | |
435 | enum { | |
436 | kIOHibernateGfxStatusUnknown = ((int32_t) 0xFFFFFFFF) | |
437 | }; | |
438 | ||
3a60a9f5 A |
439 | #define kIOHibernateBootImageKey "boot-image" |
440 | #define kIOHibernateBootImageKeyKey "boot-image-key" | |
441 | #define kIOHibernateBootSignatureKey "boot-signature" | |
442 | ||
443 | #define kIOHibernateMemorySignatureKey "memory-signature" | |
444 | #define kIOHibernateMemorySignatureEnvKey "mem-sig" | |
445 | #define kIOHibernateMachineSignatureKey "machine-signature" | |
446 | ||
0c530ab8 | 447 | #define kIOHibernateRTCVariablesKey "IOHibernateRTCVariables" |
6d2010ae | 448 | #define kIOHibernateSMCVariablesKey "IOHibernateSMCVariables" |
0c530ab8 | 449 | |
2d21ac55 A |
450 | #define kIOHibernateBootSwitchVarsKey "boot-switch-vars" |
451 | ||
6d2010ae | 452 | #define kIOHibernateUseKernelInterpreter 0x80000000 |
2d21ac55 | 453 | |
3a60a9f5 A |
454 | #ifdef __cplusplus |
455 | } | |
456 | #endif |