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