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