1 /*
2  * Copyright (c) 2004-2024 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
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.
14  *
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
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.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #ifndef __IOKIT_IOHIBERNATEPRIVATE_H
30 #define __IOKIT_IOHIBERNATEPRIVATE_H
31 
32 #if HIBERNATION
33 
34 #if defined(__arm64__)
35 
36 
37 // enable the hibernation exception handler on DEBUG and DEVELOPMENT kernels
38 #define HIBERNATE_TRAP_HANDLER (DEBUG || DEVELOPMENT)
39 
40 #endif /* defined(__arm64__) */
41 
42 #endif /* HIBERNATION */
43 
44 #ifndef __ASSEMBLER__
45 
46 #include <stdint.h>
47 #include <sys/cdefs.h>
48 
49 __BEGIN_DECLS
50 
51 #ifdef KERNEL
52 #include <libkern/crypto/aes.h>
53 #include <uuid/uuid.h>
54 #include <kern/debug.h>
55 
56 extern int kdb_printf(const char *format, ...) __printflike(1, 2);
57 #endif /* KERNEL */
58 
59 #define HIBERNATE_HMAC_SIZE 48 // SHA384 size in bytes
60 #define HIBERNATE_SHA256_SIZE 32 // SHA256 size in bytes
61 
62 struct IOHibernateHibSegment {
63 	uint32_t    iBootMemoryRegion;
64 	uint32_t    physPage;
65 	uint32_t    pageCount;
66 	uint32_t    protection;
67 };
68 typedef struct IOHibernateHibSegment IOHibernateHibSegment;
69 
70 #define NUM_HIBSEGINFO_SEGMENTS 10
71 struct IOHibernateHibSegInfo {
72 	struct IOHibernateHibSegment    segments[NUM_HIBSEGINFO_SEGMENTS];
73 	uint8_t                         hmac[HIBERNATE_HMAC_SIZE];
74 };
75 typedef struct IOHibernateHibSegInfo IOHibernateHibSegInfo;
76 
77 struct IOPolledFileExtent {
78 	uint64_t    start;
79 	uint64_t    length;
80 };
81 typedef struct IOPolledFileExtent IOPolledFileExtent;
82 
83 /**
84  * The following metadata is exclusively used on SPTM-based systems (where the
85  * SPTM will be the source of this information).
86  *
87  * Any metadata that is passed to XNU (by SPTM) at boot with the intent to be
88  * placed unmodified into the hibernation header is considered "protected". This
89  * metadata will be hashed and signed with the SPTM secret key to ensure that
90  * XNU cannot modify this data when entering it into the header. iBoot will then
91  * validate that the metadata has not been modified during a hibernation boot.
92  */
93 typedef struct {
94 	/**
95 	 * Array of physical address ranges/segments that need to be hashed into the
96 	 * hibernation image fully uncompressed and signed separately from the rest
97 	 * of the image payloads. This data is either needed by iBoot or hibtext
98 	 * when starting the hibernation restore process. iBoot will directly load
99 	 * these segments into memory and verify the hmac itself. The hash of the
100 	 * memory these segments point to is signed using Key0 (warm data key)
101 	 * during the hibernation entry process seeing as the data itself could
102 	 * change after boot (which is why the HMAC of the hibernation segments is
103 	 * not in this protected metadata structure).
104 	 */
105 	IOHibernateHibSegment hib_segments[NUM_HIBSEGINFO_SEGMENTS];
106 
107 	/* Start and end of DRAM. */
108 	uint64_t dram_base;
109 	uint64_t dram_size;
110 
111 	/**
112 	 * Starting physical address of the Device Tree.
113 	 *
114 	 * Note that this is the address of the "original" device tree,
115 	 * which is also the one that will have been restored once
116 	 * hibernation exit is complete. In other words, this has nothing
117 	 * to do with the "fresh", "new" device tree that iBoot constructs
118 	 * during hibernation exit, and that will only be used for
119 	 * hibernation exit itself, and, in very small parts, to update
120 	 * the IOKit mirror of the device tree.
121 	 */
122 	uint64_t dt_start_paddr;
123 
124 	/* Size of the Device Tree in bytes. See dt_start_paddr for what this means. */
125 	uint64_t dt_size;
126 
127 	/**
128 	 * The physical address of the entry point of the SPTM hibtext,
129 	 * i.e. the part of the SPTM that iBoot hands off to to perform
130 	 * hibernation exit.
131 	 */
132 	uint64_t sptm_entry_phys;
133 
134 	/**
135 	 * The physical page number at which the hibtext starts, to be mapped for
136 	 * execution by early hibtext initialization code, as well as the number
137 	 * of pages to map.
138 	 */
139 	uint32_t sptm_phys_page;
140 	uint32_t sptm_page_count;
141 
142 	/**
143 	 * Various region start and end addresses that the hibtext needs
144 	 * to properly do its job.
145 	 */
146 	uint64_t sptm_ro_start_phys;
147 	uint64_t xnu_ro_start_phys;
148 	uint64_t txm_ro_start_phys;
149 	uint64_t sptm_ro_start_virt;
150 	uint64_t xnu_ro_start_virt;
151 	uint64_t txm_ro_start_virt;
152 
153 	uint64_t sptm_rm_start_phys;
154 	uint64_t sptm_rm_end_phys;
155 	uint64_t sptm_le_end_phys;
156 
157 	/**
158 	 * The physical address of the consistent debug page, so that the
159 	 * hibtext can participate in this method of telling astris
160 	 * whether (and how) it panicked.
161 	 */
162 	uint64_t consistent_debug_page_phys;
163 
164 	/**
165 	 * The hibtext needs to restore the debug headers in the freshly
166 	 * loaded SPTM, using these values.
167 	 */
168 	uint64_t early_debug_consistent_debug_page;
169 	uint64_t global_debug_consistent_debug_page;
170 
171 	/**
172 	 * The virtual slide of the SPTM. This is directly the slide that iBoot has
173 	 * chosen to be the slide for the SPTM, and will be used directly by iBoot
174 	 * to load boot objects at the same place as before upon hibernation exit.
175 	 */
176 	uint64_t sptm_slide;
177 
178 	/**
179 	 * The CTRR region bounds.
180 	 */
181 	uint64_t ctrr_a_begin;
182 	uint64_t ctrr_a_end;
183 	uint64_t ctrr_c_begin;
184 	uint64_t ctrr_c_end;
185 	uint64_t ctrr_d_begin;
186 	uint64_t ctrr_d_end;
187 
188 	/**
189 	 * Physical address of the top of the page to be used as the stack in
190 	 * HIBTEXT. The stack is assumed to be a single page in size, so doing
191 	 * `hibtext_stack_top - PAGE_SIZE` will get the start of the page to be used
192 	 * as the HIBTEXT stack.
193 	 */
194 	uint64_t hibtext_stack_top;
195 } hib_protected_metadata_t;
196 
197 struct IOHibernateImageHeader {
198 	uint64_t    imageSize;
199 	uint64_t    image1Size;
200 
201 	uint32_t    restore1CodePhysPage;
202 	uint32_t    reserved1;
203 	uint64_t    restore1CodeVirt;
204 	uint32_t    restore1PageCount;
205 	uint32_t    restore1CodeOffset;
206 	uint32_t    restore1StackOffset;
207 
208 	uint32_t    pageCount;
209 	uint32_t    bitmapSize;
210 
211 	uint32_t    restore1Sum;
212 	uint32_t    image1Sum;
213 	uint32_t    image2Sum;
214 
215 	uint32_t    actualRestore1Sum;
216 	uint32_t    actualImage1Sum;
217 	uint32_t    actualImage2Sum;
218 
219 	uint32_t    actualUncompressedPages;
220 	uint32_t    conflictCount;
221 	uint32_t    nextFree;
222 
223 	uint32_t    signature;
224 	uint32_t    processorFlags;
225 
226 	uint32_t    runtimePages;
227 	uint32_t    runtimePageCount;
228 	uint64_t    runtimeVirtualPages __attribute__ ((packed));
229 
230 	uint32_t    performanceDataStart;
231 	uint32_t    performanceDataSize;
232 
233 	uint64_t    encryptStart __attribute__ ((packed));
234 	uint64_t    machineSignature __attribute__ ((packed));
235 
236 	uint32_t    previewSize;
237 	uint32_t    previewPageListSize;
238 
239 	uint32_t    diag[4];
240 
241 	uint32_t    handoffPages;
242 	uint32_t    handoffPageCount;
243 
244 	uint32_t    systemTableOffset;
245 
246 	uint32_t    debugFlags;
247 	uint32_t    options;
248 	uint64_t    sleepTime __attribute__ ((packed));
249 	uint32_t    compression;
250 
251 	uint8_t     bridgeBootSessionUUID[16];
252 
253 	uint64_t    lastHibAbsTime __attribute__ ((packed));
254 	union {
255 		uint64_t    lastHibContTime;
256 		uint64_t    hwClockOffset;
257 	} __attribute__ ((packed));
258 	uint64_t    kernVirtSlide __attribute__ ((packed));
259 
260 	/**
261 	 * The size of the non-arm64 version of this structure must be 512 bytes (to
262 	 * fit into a single disk sector). There is no size constraint for the arm64
263 	 * version of this structure.
264 	 */
265 	uint32_t    reserved[45];
266 
267 	uint64_t    kernelSlide __attribute__ ((packed));      // gVirtBase - gPhysBase (a different kind of "slide")
268 
269 	uint32_t    booterTime0;
270 	uint32_t    booterTime1;
271 	uint32_t    booterTime2;
272 
273 	uint32_t    booterStart;
274 	uint32_t    smcStart;
275 	uint32_t    connectDisplayTime;
276 	uint32_t    splashTime;
277 	uint32_t    booterTime;
278 	uint32_t    trampolineTime;
279 
280 	uint64_t    encryptEnd __attribute__ ((packed));
281 	uint64_t    deviceBase __attribute__ ((packed));
282 	uint32_t    deviceBlockSize;
283 
284 #if defined(__arm64__)
285 	/**
286 	 * Some of these fields are only used on PPL or SPTM-based systems while
287 	 * others are used on both. The individual fields cannot be compiled in
288 	 * based on any XNU-specific defines since this struct is also used by
289 	 * projects which do not have the same defines set (e.g., iBoot/SPTM), so
290 	 * we're stuck having all fields on all systems even if some of them go
291 	 * unused.
292 	 */
293 
294 	/* Both: Offset into the hibernation image of where to find the hibernation segments. */
295 	uint32_t    segmentsFileOffset;
296 
297 	/* Both: HMAC of all of the data written into the image that isn't a part of image1/2. */
298 	uint32_t    imageHeaderHMACSize;
299 	uint8_t     imageHeaderHMAC[HIBERNATE_HMAC_SIZE];
300 
301 	/* Both: HMAC of the IOHibernateHandoff data passed from iBoot to XNU. */
302 	uint8_t     handoffHMAC[HIBERNATE_HMAC_SIZE];
303 
304 	/* Both: HMACs of the wired (image1) and non-wired (image2) memory. */
305 	uint8_t     image1PagesHMAC[HIBERNATE_HMAC_SIZE];
306 	uint8_t     image2PagesHMAC[HIBERNATE_HMAC_SIZE];
307 
308 	/**
309 	 * PPL-only: List of memory regions that iBoot should restore and validate
310 	 * before jumping to hibtext. This struct contains both the list of segments
311 	 * as well as an HMAC covering the memory contained in all of the segments.
312 	 *
313 	 * This is not used on SPTM-based systems seeing as the SPTM wants to pass
314 	 * the hibernation segments as "protected" metadata which has its own HMAC
315 	 * separate from the HMAC covering the contents of the hibernation segments.
316 	 */
317 	IOHibernateHibSegInfo hibSegInfo;
318 
319 	/**
320 	 * PPL-only: HMAC of the read-only region. The SPTM treats the HMAC of CTRR
321 	 * protected memory as "protected" metadata so these fields are unused on
322 	 * the SPTM.
323 	 */
324 	uint8_t     rorgnHMAC[HIBERNATE_HMAC_SIZE];
325 	uint8_t     rorgnSHA256[HIBERNATE_SHA256_SIZE];
326 
327 	/**
328 	 * SPTM-only: Metadata generated by the SPTM at cold boot (before XNU boots
329 	 * up) that should be copied wholesale into the hibernation header. This
330 	 * metadata has its own HMAC generated by the SPTM using the SPTM secret
331 	 * key.
332 	 */
333 	hib_protected_metadata_t protected_metadata;
334 
335 	/**
336 	 * SPTM-only: HMAC of all of the protected metadata in the above structure.
337 	 * This is created using SPTM's secret key and will be verified by iBoot.
338 	 */
339 	uint8_t     protected_metadata_hmac[HIBERNATE_HMAC_SIZE];
340 
341 	/**
342 	 * HMAC of the memory that is protected by the SPTM's Read-Only Region
343 	 * (RORGN). This is created using SPTM's secret key and will be verified by
344 	 * hibtext.
345 	 */
346 	uint8_t     sptm_rorgn_hmac[HIBERNATE_HMAC_SIZE];
347 
348 	/**
349 	 * SPTM-only: HMAC of the memory that is protected by the XNU Read-Only
350 	 * Region (RORGN). This is created using XNU's secret key and will be
351 	 * verified by hibtext.
352 	 */
353 	uint8_t     xnu_rorgn_hmac[HIBERNATE_HMAC_SIZE];
354 
355 	/**
356 	 * SPTM-only: HMAC of the contents of the hibernation segments. This is
357 	 * created using Key0 (the warm data key) and will be verified by iBoot when
358 	 * loading the hibernation segments. This is not a part of the protected
359 	 * metadata seeing as the contents of the hibernation segments can change
360 	 * (even if the bounds of the segments don't).
361 	 */
362 	uint8_t     hib_segs_hmac[HIBERNATE_HMAC_SIZE];
363 #endif /* defined(__arm64__) */
364 
365 	uint32_t            fileExtentMapSize;
366 	IOPolledFileExtent  fileExtentMap[2];
367 };
368 typedef struct IOHibernateImageHeader IOHibernateImageHeader;
369 
370 enum{
371 	kIOHibernateDebugRestoreLogs = 0x00000001
372 };
373 
374 // options & IOHibernateOptions property
375 enum{
376 	kIOHibernateOptionSSD           = 0x00000001,
377 	kIOHibernateOptionColor         = 0x00000002,
378 	kIOHibernateOptionProgress      = 0x00000004,
379 	kIOHibernateOptionDarkWake      = 0x00000008,
380 	kIOHibernateOptionHWEncrypt     = 0x00000010,
381 };
382 
383 struct hibernate_bitmap_t {
384 	uint32_t    first_page;
385 	uint32_t    last_page;
386 	uint32_t    bitmapwords;
387 	uint32_t    bitmap[0];
388 };
389 typedef struct hibernate_bitmap_t hibernate_bitmap_t;
390 
391 struct hibernate_page_list_t {
392 	uint32_t              list_size;
393 	uint32_t              page_count;
394 	uint32_t              bank_count;
395 	hibernate_bitmap_t    bank_bitmap[0];
396 };
397 typedef struct hibernate_page_list_t hibernate_page_list_t;
398 
399 #if defined(_AES_H)
400 
401 struct hibernate_cryptwakevars_t {
402 	uint8_t aes_iv[AES_BLOCK_SIZE];
403 };
404 typedef struct hibernate_cryptwakevars_t hibernate_cryptwakevars_t;
405 
406 struct hibernate_cryptvars_t {
407 	uint8_t aes_iv[AES_BLOCK_SIZE];
408 	aes_ctx ctx;
409 };
410 typedef struct hibernate_cryptvars_t hibernate_cryptvars_t;
411 
412 #endif /* defined(_AES_H) */
413 
414 enum{
415 	kIOHibernateHandoffType                 = 0x686f0000,
416 	kIOHibernateHandoffTypeEnd              = kIOHibernateHandoffType + 0,
417 	kIOHibernateHandoffTypeGraphicsInfo     = kIOHibernateHandoffType + 1,
418 	kIOHibernateHandoffTypeCryptVars        = kIOHibernateHandoffType + 2,
419 	kIOHibernateHandoffTypeMemoryMap        = kIOHibernateHandoffType + 3,
420 	kIOHibernateHandoffTypeDeviceTree       = kIOHibernateHandoffType + 4,
421 	kIOHibernateHandoffTypeDeviceProperties = kIOHibernateHandoffType + 5,
422 	kIOHibernateHandoffTypeKeyStore         = kIOHibernateHandoffType + 6,
423 	kIOHibernateHandoffTypeVolumeCryptKey   = kIOHibernateHandoffType + 7,
424 };
425 
426 struct IOHibernateHandoff {
427 	uint32_t type;
428 	uint32_t bytecount;
429 	uint8_t  data[];
430 };
431 typedef struct IOHibernateHandoff IOHibernateHandoff;
432 
433 enum{
434 	kIOHibernateProgressCount         = 19,
435 	kIOHibernateProgressWidth         = 7,
436 	kIOHibernateProgressHeight        = 16,
437 	kIOHibernateProgressSpacing       = 3,
438 	kIOHibernateProgressOriginY       = 81,
439 
440 	kIOHibernateProgressSaveUnderSize = 2 * 5 + 14 * 2,
441 
442 	kIOHibernateProgressLightGray     = 230,
443 	kIOHibernateProgressMidGray       = 174,
444 	kIOHibernateProgressDarkGray      = 92
445 };
446 
447 enum{
448 	kIOHibernatePostWriteSleep   = 0,
449 	kIOHibernatePostWriteWake    = 1,
450 	kIOHibernatePostWriteHalt    = 2,
451 	kIOHibernatePostWriteRestart = 3
452 };
453 
454 
455 struct hibernate_graphics_t {
456 	uint64_t physicalAddress; // Base address of video memory
457 	int32_t  gfxStatus;     // EFI config restore status
458 	uint32_t rowBytes;              // Number of bytes per pixel row
459 	uint32_t width;                 // Width
460 	uint32_t height;                // Height
461 	uint32_t depth;                 // Pixel Depth
462 
463 	uint8_t progressSaveUnder[kIOHibernateProgressCount][kIOHibernateProgressSaveUnderSize];
464 };
465 typedef struct hibernate_graphics_t hibernate_graphics_t;
466 
467 #define DECLARE_IOHIBERNATEPROGRESSALPHA                                \
468 static const uint8_t gIOHibernateProgressAlpha                  \
469 [kIOHibernateProgressHeight][kIOHibernateProgressWidth] =       \
470 {                                                               \
471     { 0x00,0x63,0xd8,0xf0,0xd8,0x63,0x00 },                     \
472     { 0x51,0xff,0xff,0xff,0xff,0xff,0x51 },                     \
473     { 0xae,0xff,0xff,0xff,0xff,0xff,0xae },                     \
474     { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },                     \
475     { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },                     \
476     { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },                     \
477     { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },                     \
478     { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },                     \
479     { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },                     \
480     { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },                     \
481     { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },                     \
482     { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },                     \
483     { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },                     \
484     { 0xae,0xff,0xff,0xff,0xff,0xff,0xae },                     \
485     { 0x54,0xff,0xff,0xff,0xff,0xff,0x54 },                     \
486     { 0x00,0x66,0xdb,0xf3,0xdb,0x66,0x00 }                      \
487 };
488 
489 struct hibernate_preview_t {
490 	uint32_t  imageCount;   // Number of images
491 	uint32_t  width;        // Width
492 	uint32_t  height;       // Height
493 	uint32_t  depth;        // Pixel Depth
494 	uint64_t  lockTime;     // Lock time
495 	uint32_t  reservedG[7]; // reserved
496 	uint32_t  reservedK[8]; // reserved
497 };
498 typedef struct hibernate_preview_t hibernate_preview_t;
499 
500 struct hibernate_statistics_t {
501 	uint64_t image1Size;
502 	uint64_t imageSize;
503 	uint32_t image1Pages;
504 	uint32_t imagePages;
505 	uint32_t booterStart;
506 	uint32_t smcStart;
507 	uint32_t booterDuration;
508 	uint32_t booterConnectDisplayDuration;
509 	uint32_t booterSplashDuration;
510 	uint32_t booterDuration0;
511 	uint32_t booterDuration1;
512 	uint32_t booterDuration2;
513 	uint32_t trampolineDuration;
514 	uint32_t kernelImageReadDuration;
515 
516 	uint32_t graphicsReadyTime;
517 	uint32_t wakeNotificationTime;
518 	uint32_t lockScreenReadyTime;
519 	uint32_t hidReadyTime;
520 
521 	uint32_t wakeCapability;
522 	uint32_t hibCount;
523 	uint32_t resvA[14];
524 };
525 typedef struct hibernate_statistics_t hibernate_statistics_t;
526 
527 #define kIOSysctlHibernateStatistics    "kern.hibernatestatistics"
528 #define kIOSysctlHibernateGraphicsReady "kern.hibernategraphicsready"
529 #define kIOSysctlHibernateWakeNotify    "kern.hibernatewakenotification"
530 #define kIOSysctlHibernateScreenReady   "kern.hibernatelockscreenready"
531 #define kIOSysctlHibernateHIDReady      "kern.hibernatehidready"
532 #define kIOSysctlHibernateCount         "kern.hibernatecount"
533 #define kIOSysctlHibernateSetPreview    "kern.hibernatepreview"
534 
535 #define kIOHibernateSetPreviewEntitlementKey "com.apple.private.hibernation.set-preview"
536 
537 #ifdef KERNEL
538 
539 struct hibernate_scratch {
540 	uint8_t  *curPage;
541 	size_t    curPagePos;
542 	uint64_t  curPos;
543 	uint64_t  totalLength;
544 	ppnum_t  headPage;
545 	hibernate_page_list_t *map;
546 	uint32_t *nextFree;
547 };
548 typedef struct hibernate_scratch hibernate_scratch_t;
549 
550 void
551 vm_compressor_do_warmup(void);
552 
553 
554 hibernate_page_list_t *
555 hibernate_page_list_allocate(boolean_t log);
556 
557 kern_return_t
558 hibernate_alloc_page_lists(
559 	hibernate_page_list_t ** page_list_ret,
560 	hibernate_page_list_t ** page_list_wired_ret,
561 	hibernate_page_list_t ** page_list_pal_ret);
562 
563 kern_return_t
564 hibernate_setup(IOHibernateImageHeader * header,
565     boolean_t vmflush,
566     hibernate_page_list_t * page_list,
567     hibernate_page_list_t * page_list_wired,
568     hibernate_page_list_t * page_list_pal);
569 
570 kern_return_t
571 hibernate_teardown(hibernate_page_list_t * page_list,
572     hibernate_page_list_t * page_list_wired,
573     hibernate_page_list_t * page_list_pal);
574 
575 kern_return_t
576 hibernate_pin_swap(boolean_t begin);
577 
578 kern_return_t
579 hibernate_processor_setup(IOHibernateImageHeader * header);
580 
581 void
582 hibernate_gobble_pages(uint32_t gobble_count, uint32_t free_page_time);
583 void
584 hibernate_free_gobble_pages(void);
585 
586 void
587 hibernate_vm_lock_queues(void);
588 void
589 hibernate_vm_unlock_queues(void);
590 
591 void
592 hibernate_vm_lock(void);
593 void
594 hibernate_vm_unlock(void);
595 void
596 hibernate_vm_lock_end(void);
597 boolean_t
598 hibernate_vm_locks_are_safe(void);
599 
600 // mark pages not to be saved, based on VM system accounting
601 void
602 hibernate_page_list_setall(hibernate_page_list_t * page_list,
603     hibernate_page_list_t * page_list_wired,
604     hibernate_page_list_t * page_list_pal,
605     boolean_t preflight,
606     boolean_t discard_all,
607     uint32_t * pagesOut);
608 
609 // mark pages to be saved, or pages not to be saved but available
610 // for scratch usage during restore
611 void
612 hibernate_page_list_setall_machine(hibernate_page_list_t * page_list,
613     hibernate_page_list_t * page_list_wired,
614     boolean_t preflight,
615     uint32_t * pagesOut);
616 
617 // mark pages not to be saved and not for scratch usage during restore
618 void
619 hibernate_page_list_set_volatile( hibernate_page_list_t * page_list,
620     hibernate_page_list_t * page_list_wired,
621     uint32_t * pagesOut);
622 
623 void
624 hibernate_page_list_discard(hibernate_page_list_t * page_list);
625 
626 int
627 hibernate_should_abort(void);
628 
629 void
630 hibernate_set_page_state(hibernate_page_list_t * page_list, hibernate_page_list_t * page_list_wired,
631     vm_offset_t ppnum, vm_offset_t count, uint32_t kind);
632 
633 void
634 hibernate_page_bitset(hibernate_page_list_t * list, boolean_t set, uint32_t page);
635 
636 boolean_t
637 hibernate_page_bittst(hibernate_page_list_t * list, uint32_t page);
638 
639 hibernate_bitmap_t *
640 hibernate_page_bitmap_pin(hibernate_page_list_t * list, uint32_t * page);
641 
642 uint32_t
643 hibernate_page_bitmap_count(hibernate_bitmap_t * bitmap, uint32_t set, uint32_t page);
644 
645 uintptr_t
646 hibernate_restore_phys_page(uint64_t src, uint64_t dst, uint32_t len, uint32_t procFlags);
647 
648 void
649 hibernate_scratch_init(hibernate_scratch_t * scratch, hibernate_page_list_t * map, uint32_t * nextFree);
650 
651 void
652 hibernate_scratch_start_read(hibernate_scratch_t * scratch);
653 
654 void
655 hibernate_scratch_write(hibernate_scratch_t * scratch, const void * buffer, size_t size);
656 
657 void
658 hibernate_scratch_read(hibernate_scratch_t * scratch, void * buffer, size_t size);
659 
660 void
661 hibernate_machine_init(void);
662 
663 uint32_t
664 hibernate_write_image(void);
665 
666 ppnum_t
667 hibernate_page_list_grab(hibernate_page_list_t * list, uint32_t * pNextFree);
668 
669 void
670 hibernate_reserve_restore_pages(uint64_t headerPhys, IOHibernateImageHeader *header, hibernate_page_list_t * map);
671 
672 long
673 hibernate_machine_entrypoint(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
674 long
675 hibernate_kernel_entrypoint(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
676 void
677 hibernate_newruntime_map(void * map, vm_size_t map_size,
678     uint32_t system_table_offset);
679 
680 void
681 hibernate_rebuild_vm_structs(void);
682 
683 
684 extern uint32_t    gIOHibernateState;
685 extern uint32_t    gIOHibernateMode;
686 extern uint32_t    gIOHibernateDebugFlags;
687 extern uint32_t    gIOHibernateFreeTime;        // max time to spend freeing pages (ms)
688 extern boolean_t   gIOHibernateStandbyDisabled;
689 #if !defined(__arm64__)
690 extern uint8_t     gIOHibernateRestoreStack[];
691 extern uint8_t     gIOHibernateRestoreStackEnd[];
692 #endif /* !defined(__arm64__) */
693 extern IOHibernateImageHeader *    gIOHibernateCurrentHeader;
694 
695 #define HIBLOGFROMPANIC(fmt, args...) \
696     { if (kernel_debugger_entry_count) { kdb_printf(fmt, ## args); } }
697 
698 #define HIBLOG(fmt, args...)    \
699     { if (kernel_debugger_entry_count) { kdb_printf(fmt, ## args); } else { kprintf(fmt, ## args); printf(fmt, ## args); } }
700 
701 #define HIBPRINT(fmt, args...)  \
702     { if (kernel_debugger_entry_count) { kdb_printf(fmt, ## args); } else { kprintf(fmt, ## args); } }
703 
704 
705 #endif /* KERNEL */
706 
707 // gIOHibernateState, kIOHibernateStateKey
708 enum{
709 	kIOHibernateStateInactive            = 0,
710 	kIOHibernateStateHibernating         = 1,/* writing image */
711 	kIOHibernateStateWakingFromHibernate = 2 /* booted and restored image */
712 };
713 
714 // gIOHibernateMode, kIOHibernateModeKey
715 enum{
716 	kIOHibernateModeOn      = 0x00000001,
717 	kIOHibernateModeSleep   = 0x00000002,
718 	kIOHibernateModeEncrypt = 0x00000004,
719 	kIOHibernateModeDiscardCleanInactive = 0x00000008,
720 	kIOHibernateModeDiscardCleanActive   = 0x00000010,
721 	kIOHibernateModeSwitch      = 0x00000020,
722 	kIOHibernateModeRestart     = 0x00000040,
723 	kIOHibernateModeSSDInvert   = 0x00000080,
724 	kIOHibernateModeFileResize  = 0x00000100,
725 };
726 
727 // IOHibernateImageHeader.signature
728 enum{
729 	kIOHibernateHeaderSignature        = 0x73696d65U,
730 	kIOHibernateHeaderInvalidSignature = 0x7a7a7a7aU,
731 	kIOHibernateHeaderOpenSignature    = 0xf1e0be9dU,
732 	kIOHibernateHeaderDebugDataSignature = 0xfcddfcddU
733 };
734 
735 // kind for hibernate_set_page_state()
736 enum{
737 	kIOHibernatePageStateFree        = 0,
738 	kIOHibernatePageStateWiredSave   = 1,
739 	kIOHibernatePageStateUnwiredSave = 2
740 };
741 
742 #define kIOHibernateModeKey             "Hibernate Mode"
743 #define kIOHibernateFileKey             "Hibernate File"
744 #define kIOHibernateFileMinSizeKey      "Hibernate File Min"
745 #define kIOHibernateFileMaxSizeKey      "Hibernate File Max"
746 #define kIOHibernateFreeRatioKey        "Hibernate Free Ratio"
747 #define kIOHibernateFreeTimeKey         "Hibernate Free Time"
748 
749 #define kIOHibernateStateKey            "IOHibernateState"
750 #define kIOHibernateFeatureKey          "Hibernation"
751 #define kIOHibernatePreviewBufferKey    "IOPreviewBuffer"
752 
753 #ifndef kIOHibernatePreviewActiveKey
754 #define kIOHibernatePreviewActiveKey    "IOHibernatePreviewActive"
755 // values for kIOHibernatePreviewActiveKey
756 enum {
757 	kIOHibernatePreviewActive  = 0x00000001,
758 	kIOHibernatePreviewUpdates = 0x00000002
759 };
760 #endif
761 
762 #define kIOHibernateOptionsKey      "IOHibernateOptions"
763 #define kIOHibernateGfxStatusKey    "IOHibernateGfxStatus"
764 enum {
765 	kIOHibernateGfxStatusUnknown = ((int32_t) 0xFFFFFFFF)
766 };
767 
768 #define kIOHibernateBootImageKey        "boot-image"
769 #define kIOHibernateBootImageKeyKey     "boot-image-key"
770 #define kIOHibernateBootSignatureKey    "boot-signature"
771 
772 #define kIOHibernateMemorySignatureKey    "memory-signature"
773 #define kIOHibernateMemorySignatureEnvKey "mem-sig"
774 #define kIOHibernateMachineSignatureKey   "machine-signature"
775 
776 #define kIOHibernateRTCVariablesKey     "IOHibernateRTCVariables"
777 #define kIOHibernateSMCVariablesKey     "IOHibernateSMCVariables"
778 
779 #define kIOHibernateBootSwitchVarsKey   "boot-switch-vars"
780 
781 #define kIOHibernateBootNoteKey         "boot-note"
782 
783 
784 #define kIOHibernateUseKernelInterpreter    0x80000000
785 
786 enum{
787 	kIOPreviewImageIndexDesktop = 0,
788 	kIOPreviewImageIndexLockScreen = 1,
789 	kIOPreviewImageCount = 2
790 };
791 
792 enum{
793 	kIOScreenLockNoLock          = 1,
794 	kIOScreenLockUnlocked        = 2,
795 	kIOScreenLockLocked          = 3,
796 	kIOScreenLockFileVaultDialog = 4,
797 };
798 
799 #define kIOScreenLockStateKey       "IOScreenLockState"
800 #define kIOBooterScreenLockStateKey "IOBooterScreenLockState"
801 
802 __END_DECLS
803 
804 #endif /* !__ASSEMBLER__ */
805 
806 #endif /* ! __IOKIT_IOHIBERNATEPRIVATE_H */
807