1/*
2 * Copyright (c) 2004 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#include <stdint.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#ifdef KERNEL
36#include <libkern/crypto/aes.h>
37#include <uuid/uuid.h>
38#endif
39
40#ifndef __IOKIT_IOHIBERNATEPRIVATE_H
41#define __IOKIT_IOHIBERNATEPRIVATE_H
42
43struct IOPolledFileExtent
44{
45    uint64_t	start;
46    uint64_t	length;
47};
48typedef struct IOPolledFileExtent IOPolledFileExtent;
49
50struct IOHibernateImageHeader
51{
52    uint64_t	imageSize;
53    uint64_t	image1Size;
54
55    uint32_t	restore1CodePhysPage;
56    uint32_t    reserved1;
57    uint64_t	restore1CodeVirt;
58    uint32_t	restore1PageCount;
59    uint32_t	restore1CodeOffset;
60    uint32_t	restore1StackOffset;
61
62    uint32_t	pageCount;
63    uint32_t	bitmapSize;
64
65    uint32_t	restore1Sum;
66    uint32_t	image1Sum;
67    uint32_t	image2Sum;
68
69    uint32_t	actualRestore1Sum;
70    uint32_t	actualImage1Sum;
71    uint32_t	actualImage2Sum;
72
73    uint32_t	actualUncompressedPages;
74    uint32_t	conflictCount;
75    uint32_t	nextFree;
76
77    uint32_t	signature;
78    uint32_t	processorFlags;
79
80    uint32_t    runtimePages;
81    uint32_t    runtimePageCount;
82    uint64_t    runtimeVirtualPages __attribute__ ((packed));
83
84    uint32_t    performanceDataStart;
85    uint32_t    performanceDataSize;
86
87    uint64_t	encryptStart __attribute__ ((packed));
88    uint64_t	machineSignature __attribute__ ((packed));
89
90    uint32_t    previewSize;
91    uint32_t    previewPageListSize;
92
93    uint32_t	diag[4];
94
95    uint32_t    handoffPages;
96    uint32_t    handoffPageCount;
97
98    uint32_t    systemTableOffset;
99
100    uint32_t	debugFlags;
101    uint32_t	options;
102    uint32_t	sleepTime;
103    uint32_t    compression;
104
105    uint32_t	reserved[58];		// make sizeof == 512
106    uint32_t	booterTime0;
107    uint32_t	booterTime1;
108    uint32_t	booterTime2;
109
110    uint32_t	booterStart;
111    uint32_t	smcStart;
112    uint32_t	connectDisplayTime;
113    uint32_t	splashTime;
114    uint32_t	booterTime;
115    uint32_t	trampolineTime;
116
117    uint64_t	encryptEnd __attribute__ ((packed));
118    uint64_t	deviceBase __attribute__ ((packed));
119    uint32_t	deviceBlockSize;
120
121    uint32_t		fileExtentMapSize;
122    IOPolledFileExtent	fileExtentMap[2];
123};
124typedef struct IOHibernateImageHeader IOHibernateImageHeader;
125
126enum
127{
128    kIOHibernateDebugRestoreLogs = 0x00000001
129};
130
131// options & IOHibernateOptions property
132enum
133{
134    kIOHibernateOptionSSD           = 0x00000001,
135    kIOHibernateOptionColor         = 0x00000002,
136    kIOHibernateOptionProgress      = 0x00000004,
137    kIOHibernateOptionDarkWake      = 0x00000008,
138};
139
140struct hibernate_bitmap_t
141{
142    uint32_t	first_page;
143    uint32_t	last_page;
144    uint32_t	bitmapwords;
145    uint32_t	bitmap[0];
146};
147typedef struct hibernate_bitmap_t hibernate_bitmap_t;
148
149struct hibernate_page_list_t
150{
151    uint32_t		  list_size;
152    uint32_t		  page_count;
153    uint32_t		  bank_count;
154    hibernate_bitmap_t    bank_bitmap[0];
155};
156typedef struct hibernate_page_list_t hibernate_page_list_t;
157
158#if defined(_AES_H)
159
160struct hibernate_cryptwakevars_t
161{
162    uint8_t aes_iv[AES_BLOCK_SIZE];
163};
164typedef struct hibernate_cryptwakevars_t hibernate_cryptwakevars_t;
165
166struct hibernate_cryptvars_t
167{
168    uint8_t aes_iv[AES_BLOCK_SIZE];
169    aes_ctx ctx;
170};
171typedef struct hibernate_cryptvars_t hibernate_cryptvars_t;
172
173#endif /* defined(_AES_H) */
174
175enum
176{
177    kIOHibernateHandoffType                 = 0x686f0000,
178    kIOHibernateHandoffTypeEnd              = kIOHibernateHandoffType + 0,
179    kIOHibernateHandoffTypeGraphicsInfo     = kIOHibernateHandoffType + 1,
180    kIOHibernateHandoffTypeCryptVars        = kIOHibernateHandoffType + 2,
181    kIOHibernateHandoffTypeMemoryMap        = kIOHibernateHandoffType + 3,
182    kIOHibernateHandoffTypeDeviceTree       = kIOHibernateHandoffType + 4,
183    kIOHibernateHandoffTypeDeviceProperties = kIOHibernateHandoffType + 5,
184    kIOHibernateHandoffTypeKeyStore         = kIOHibernateHandoffType + 6,
185};
186
187struct IOHibernateHandoff
188{
189    uint32_t type;
190    uint32_t bytecount;
191    uint8_t  data[];
192};
193typedef struct IOHibernateHandoff IOHibernateHandoff;
194
195enum
196{
197    kIOHibernateProgressCount         = 19,
198    kIOHibernateProgressWidth         = 7,
199    kIOHibernateProgressHeight        = 16,
200    kIOHibernateProgressSpacing       = 3,
201    kIOHibernateProgressOriginY       = 81,
202
203    kIOHibernateProgressSaveUnderSize = 2*5+14*2,
204
205    kIOHibernateProgressLightGray     = 230,
206    kIOHibernateProgressMidGray       = 174,
207    kIOHibernateProgressDarkGray      = 92
208};
209
210enum
211{
212    kIOHibernatePostWriteSleep   = 0,
213    kIOHibernatePostWriteWake    = 1,
214    kIOHibernatePostWriteHalt    = 2,
215    kIOHibernatePostWriteRestart = 3
216};
217
218
219struct hibernate_graphics_t
220{
221    uint32_t physicalAddress;	// Base address of video memory
222    int32_t  gfxStatus;         // EFI config restore status
223    uint32_t rowBytes;   		// Number of bytes per pixel row
224    uint32_t width;      		// Width
225    uint32_t height;     		// Height
226    uint32_t depth;      		// Pixel Depth
227
228    uint8_t progressSaveUnder[kIOHibernateProgressCount][kIOHibernateProgressSaveUnderSize];
229};
230typedef struct hibernate_graphics_t hibernate_graphics_t;
231
232#define DECLARE_IOHIBERNATEPROGRESSALPHA				\
233static const uint8_t gIOHibernateProgressAlpha			\
234[kIOHibernateProgressHeight][kIOHibernateProgressWidth] = 	\
235{								\
236    { 0x00,0x63,0xd8,0xf0,0xd8,0x63,0x00 },			\
237    { 0x51,0xff,0xff,0xff,0xff,0xff,0x51 },			\
238    { 0xae,0xff,0xff,0xff,0xff,0xff,0xae },			\
239    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
240    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
241    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
242    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
243    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
244    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
245    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
246    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
247    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
248    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
249    { 0xae,0xff,0xff,0xff,0xff,0xff,0xae },			\
250    { 0x54,0xff,0xff,0xff,0xff,0xff,0x54 },			\
251    { 0x00,0x66,0xdb,0xf3,0xdb,0x66,0x00 }			\
252};
253
254struct hibernate_preview_t
255{
256    uint32_t  imageCount;	// Number of images
257    uint32_t  width;      	// Width
258    uint32_t  height;     	// Height
259    uint32_t  depth;      	// Pixel Depth
260    uint32_t  lockTime;     // Lock time
261    uint32_t  reservedG[8]; // reserved
262    uint32_t  reservedK[8]; // reserved
263};
264typedef struct hibernate_preview_t hibernate_preview_t;
265
266struct hibernate_statistics_t
267{
268    uint64_t image1Size;
269    uint64_t imageSize;
270    uint32_t image1Pages;
271    uint32_t imagePages;
272    uint32_t booterStart;
273    uint32_t smcStart;
274    uint32_t booterDuration;
275    uint32_t booterConnectDisplayDuration;
276    uint32_t booterSplashDuration;
277    uint32_t booterDuration0;
278    uint32_t booterDuration1;
279    uint32_t booterDuration2;
280    uint32_t trampolineDuration;
281    uint32_t kernelImageReadDuration;
282
283    uint32_t graphicsReadyTime;
284    uint32_t wakeNotificationTime;
285    uint32_t lockScreenReadyTime;
286    uint32_t hidReadyTime;
287
288    uint32_t wakeCapability;
289    uint32_t resvA[15];
290};
291typedef struct hibernate_statistics_t hibernate_statistics_t;
292
293#define kIOSysctlHibernateStatistics	"kern.hibernatestatistics"
294#define kIOSysctlHibernateGraphicsReady	"kern.hibernategraphicsready"
295#define kIOSysctlHibernateWakeNotify	"kern.hibernatewakenotification"
296#define kIOSysctlHibernateScreenReady	"kern.hibernatelockscreenready"
297#define kIOSysctlHibernateHIDReady	"kern.hibernatehidready"
298
299#ifdef KERNEL
300
301#ifdef __cplusplus
302
303void     IOHibernateSystemInit(IOPMrootDomain * rootDomain);
304
305IOReturn IOHibernateSystemSleep(void);
306IOReturn IOHibernateOpenForDebugData(void);
307IOReturn IOHibernateIOKitSleep(void);
308IOReturn IOHibernateSystemHasSlept(void);
309IOReturn IOHibernateSystemWake(void);
310IOReturn IOHibernateSystemPostWake(void);
311bool     IOHibernateWasScreenLocked(void);
312void     IOHibernateSetScreenLocked(uint32_t lockState);
313void     IOHibernateSetWakeCapabilities(uint32_t capability);
314void     IOHibernateSystemRestart(void);
315
316#endif /* __cplusplus */
317
318#ifdef _SYS_CONF_H_
319typedef void (*kern_get_file_extents_callback_t)(void * ref, uint64_t start, uint64_t size);
320
321struct kern_direct_file_io_ref_t *
322kern_open_file_for_direct_io(const char * name, boolean_t create_file,
323			     kern_get_file_extents_callback_t callback,
324			     void * callback_ref,
325
326                             off_t set_file_size,
327
328                             off_t write_file_offset,
329                             caddr_t write_file_addr,
330                             vm_size_t write_file_len,
331
332			     dev_t * partition_device_result,
333			     dev_t * image_device_result,
334                             uint64_t * partitionbase_result,
335                             uint64_t * maxiocount_result,
336                             uint32_t * oflags);
337int
338kern_write_file(struct kern_direct_file_io_ref_t * ref, off_t offset, caddr_t addr, vm_size_t len, int ioflag);
339void
340kern_close_file_for_direct_io(struct kern_direct_file_io_ref_t * ref,
341			      off_t write_offset, caddr_t addr, vm_size_t write_length,
342			      off_t discard_offset, off_t discard_end);
343#endif /* _SYS_CONF_H_ */
344
345
346void
347vm_compressor_do_warmup(void);
348
349
350hibernate_page_list_t *
351hibernate_page_list_allocate(boolean_t log);
352
353kern_return_t
354hibernate_alloc_page_lists(
355		hibernate_page_list_t ** page_list_ret,
356		hibernate_page_list_t ** page_list_wired_ret,
357		hibernate_page_list_t ** page_list_pal_ret);
358
359kern_return_t
360hibernate_setup(IOHibernateImageHeader * header,
361                        uint32_t  free_page_ratio,
362                        uint32_t  free_page_time,
363                        boolean_t vmflush,
364			hibernate_page_list_t * page_list,
365			hibernate_page_list_t * page_list_wired,
366			hibernate_page_list_t * page_list_pal);
367
368kern_return_t
369hibernate_teardown(hibernate_page_list_t * page_list,
370                    hibernate_page_list_t * page_list_wired,
371                    hibernate_page_list_t * page_list_pal);
372
373kern_return_t
374hibernate_processor_setup(IOHibernateImageHeader * header);
375
376void
377hibernate_gobble_pages(uint32_t gobble_count, uint32_t free_page_time);
378void
379hibernate_free_gobble_pages(void);
380
381void
382hibernate_vm_lock_queues(void);
383void
384hibernate_vm_unlock_queues(void);
385
386void
387hibernate_vm_lock(void);
388void
389hibernate_vm_unlock(void);
390
391// mark pages not to be saved, based on VM system accounting
392void
393hibernate_page_list_setall(hibernate_page_list_t * page_list,
394			   hibernate_page_list_t * page_list_wired,
395			   hibernate_page_list_t * page_list_pal,
396			   boolean_t preflight,
397			   boolean_t discard_all,
398			   uint32_t * pagesOut);
399
400// mark pages to be saved, or pages not to be saved but available
401// for scratch usage during restore
402void
403hibernate_page_list_setall_machine(hibernate_page_list_t * page_list,
404                                    hibernate_page_list_t * page_list_wired,
405                                    boolean_t preflight,
406                                    uint32_t * pagesOut);
407
408// mark pages not to be saved and not for scratch usage during restore
409void
410hibernate_page_list_set_volatile( hibernate_page_list_t * page_list,
411				  hibernate_page_list_t * page_list_wired,
412				  uint32_t * pagesOut);
413
414void
415hibernate_page_list_discard(hibernate_page_list_t * page_list);
416
417int
418hibernate_should_abort(void);
419
420void
421hibernate_set_page_state(hibernate_page_list_t * page_list, hibernate_page_list_t * page_list_wired,
422				vm_offset_t ppnum, vm_offset_t count, uint32_t kind);
423
424void
425hibernate_page_bitset(hibernate_page_list_t * list, boolean_t set, uint32_t page);
426
427boolean_t
428hibernate_page_bittst(hibernate_page_list_t * list, uint32_t page);
429
430hibernate_bitmap_t *
431hibernate_page_bitmap_pin(hibernate_page_list_t * list, uint32_t * page);
432
433uint32_t
434hibernate_page_bitmap_count(hibernate_bitmap_t * bitmap, uint32_t set, uint32_t page);
435
436uintptr_t
437hibernate_restore_phys_page(uint64_t src, uint64_t dst, uint32_t len, uint32_t procFlags);
438
439void
440hibernate_machine_init(void);
441
442uint32_t
443hibernate_write_image(void);
444
445long
446hibernate_machine_entrypoint(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
447long
448hibernate_kernel_entrypoint(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
449void
450hibernate_newruntime_map(void * map, vm_size_t map_size,
451			    uint32_t system_table_offset);
452
453
454extern uint32_t    gIOHibernateState;
455extern uint32_t    gIOHibernateMode;
456extern uint32_t    gIOHibernateDebugFlags;
457extern uint32_t    gIOHibernateFreeTime;	// max time to spend freeing pages (ms)
458extern uint8_t     gIOHibernateRestoreStack[];
459extern uint8_t     gIOHibernateRestoreStackEnd[];
460extern IOHibernateImageHeader *    gIOHibernateCurrentHeader;
461
462#define HIBLOG(fmt, args...)	\
463    { kprintf(fmt, ## args); printf(fmt, ## args); }
464
465#define HIBPRINT(fmt, args...)	\
466    { kprintf(fmt, ## args); }
467
468#endif /* KERNEL */
469
470// gIOHibernateState, kIOHibernateStateKey
471enum
472{
473    kIOHibernateStateInactive            = 0,
474    kIOHibernateStateHibernating 	 = 1,	/* writing image */
475    kIOHibernateStateWakingFromHibernate = 2	/* booted and restored image */
476};
477
478// gIOHibernateMode, kIOHibernateModeKey
479enum
480{
481    kIOHibernateModeOn      = 0x00000001,
482    kIOHibernateModeSleep   = 0x00000002,
483    kIOHibernateModeEncrypt = 0x00000004,
484    kIOHibernateModeDiscardCleanInactive = 0x00000008,
485    kIOHibernateModeDiscardCleanActive   = 0x00000010,
486    kIOHibernateModeSwitch	= 0x00000020,
487    kIOHibernateModeRestart	= 0x00000040,
488    kIOHibernateModeSSDInvert	= 0x00000080,
489    kIOHibernateModeFileResize	= 0x00000100,
490};
491
492// IOHibernateImageHeader.signature
493enum
494{
495    kIOHibernateHeaderSignature        = 0x73696d65,
496    kIOHibernateHeaderInvalidSignature = 0x7a7a7a7a,
497    kIOHibernateHeaderOpenSignature    = 0xf1e0be9d,
498    kIOHibernateHeaderDebugDataSignature = 0xfcddfcdd
499};
500
501// kind for hibernate_set_page_state()
502enum
503{
504    kIOHibernatePageStateFree        = 0,
505    kIOHibernatePageStateWiredSave   = 1,
506    kIOHibernatePageStateUnwiredSave = 2
507};
508
509#define kIOHibernateModeKey		"Hibernate Mode"
510#define kIOHibernateFileKey		"Hibernate File"
511#define kIOHibernateFileMinSizeKey	"Hibernate File Min"
512#define kIOHibernateFileMaxSizeKey	"Hibernate File Max"
513#define kIOHibernateFreeRatioKey	"Hibernate Free Ratio"
514#define kIOHibernateFreeTimeKey		"Hibernate Free Time"
515
516#define kIOHibernateStateKey		"IOHibernateState"
517#define kIOHibernateFeatureKey		"Hibernation"
518#define kIOHibernatePreviewBufferKey	"IOPreviewBuffer"
519
520#ifndef kIOHibernatePreviewActiveKey
521#define kIOHibernatePreviewActiveKey	"IOHibernatePreviewActive"
522// values for kIOHibernatePreviewActiveKey
523enum {
524    kIOHibernatePreviewActive  = 0x00000001,
525    kIOHibernatePreviewUpdates = 0x00000002
526};
527#endif
528
529#define kIOHibernateOptionsKey      "IOHibernateOptions"
530#define kIOHibernateGfxStatusKey    "IOHibernateGfxStatus"
531enum {
532    kIOHibernateGfxStatusUnknown = ((int32_t) 0xFFFFFFFF)
533};
534
535#define kIOHibernateBootImageKey	"boot-image"
536#define kIOHibernateBootImageKeyKey	"boot-image-key"
537#define kIOHibernateBootSignatureKey	"boot-signature"
538
539#define kIOHibernateMemorySignatureKey	  "memory-signature"
540#define kIOHibernateMemorySignatureEnvKey "mem-sig"
541#define kIOHibernateMachineSignatureKey	  "machine-signature"
542
543#define kIOHibernateRTCVariablesKey	"IOHibernateRTCVariables"
544#define kIOHibernateSMCVariablesKey	"IOHibernateSMCVariables"
545
546#define kIOHibernateBootSwitchVarsKey	"boot-switch-vars"
547
548#define kIOHibernateBootNoteKey		"boot-note"
549
550
551#define kIOHibernateUseKernelInterpreter    0x80000000
552
553enum
554{
555	kIOPreviewImageIndexDesktop = 0,
556	kIOPreviewImageIndexLockScreen = 1,
557	kIOPreviewImageCount = 2
558};
559
560enum
561{
562	kIOScreenLockNoLock          = 1,
563	kIOScreenLockUnlocked        = 2,
564	kIOScreenLockLocked          = 3,
565	kIOScreenLockFileVaultDialog = 4,
566};
567
568#define kIOScreenLockStateKey      "IOScreenLockState"
569
570#endif /* ! __IOKIT_IOHIBERNATEPRIVATE_H */
571
572#ifdef __cplusplus
573}
574#endif
575