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 IOHibernateIOKitSleep(void);
307IOReturn IOHibernateSystemHasSlept(void);
308IOReturn IOHibernateSystemWake(void);
309IOReturn IOHibernateSystemPostWake(void);
310bool     IOHibernateWasScreenLocked(void);
311void     IOHibernateSetScreenLocked(uint32_t lockState);
312void     IOHibernateSetWakeCapabilities(uint32_t capability);
313void     IOHibernateSystemRestart(void);
314
315#endif /* __cplusplus */
316
317#ifdef _SYS_CONF_H_
318typedef void (*kern_get_file_extents_callback_t)(void * ref, uint64_t start, uint64_t size);
319
320struct kern_direct_file_io_ref_t *
321kern_open_file_for_direct_io(const char * name,
322			     kern_get_file_extents_callback_t callback,
323			     void * callback_ref,
324
325                             off_t set_file_size,
326
327                             off_t write_file_offset,
328                             caddr_t write_file_addr,
329                             vm_size_t write_file_len,
330
331			     dev_t * partition_device_result,
332			     dev_t * image_device_result,
333                             uint64_t * partitionbase_result,
334                             uint64_t * maxiocount_result,
335                             uint32_t * oflags);
336void
337kern_close_file_for_direct_io(struct kern_direct_file_io_ref_t * ref,
338			      off_t write_offset, caddr_t addr, vm_size_t write_length,
339			      off_t discard_offset, off_t discard_end);
340#endif /* _SYS_CONF_H_ */
341
342void
343vm_compressor_do_warmup(void);
344
345hibernate_page_list_t *
346hibernate_page_list_allocate(boolean_t log);
347
348kern_return_t
349hibernate_alloc_page_lists(
350		hibernate_page_list_t ** page_list_ret,
351		hibernate_page_list_t ** page_list_wired_ret,
352		hibernate_page_list_t ** page_list_pal_ret);
353
354kern_return_t
355hibernate_setup(IOHibernateImageHeader * header,
356                        uint32_t  free_page_ratio,
357                        uint32_t  free_page_time,
358                        boolean_t vmflush,
359			hibernate_page_list_t * page_list,
360			hibernate_page_list_t * page_list_wired,
361			hibernate_page_list_t * page_list_pal);
362
363kern_return_t
364hibernate_teardown(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_processor_setup(IOHibernateImageHeader * header);
370
371void
372hibernate_gobble_pages(uint32_t gobble_count, uint32_t free_page_time);
373void
374hibernate_free_gobble_pages(void);
375
376void
377hibernate_vm_lock_queues(void);
378void
379hibernate_vm_unlock_queues(void);
380
381void
382hibernate_vm_lock(void);
383void
384hibernate_vm_unlock(void);
385
386// mark pages not to be saved, based on VM system accounting
387void
388hibernate_page_list_setall(hibernate_page_list_t * page_list,
389			   hibernate_page_list_t * page_list_wired,
390			   hibernate_page_list_t * page_list_pal,
391			   boolean_t preflight,
392			   boolean_t discard_all,
393			   uint32_t * pagesOut);
394
395// mark pages to be saved, or pages not to be saved but available
396// for scratch usage during restore
397void
398hibernate_page_list_setall_machine(hibernate_page_list_t * page_list,
399                                    hibernate_page_list_t * page_list_wired,
400                                    boolean_t preflight,
401                                    uint32_t * pagesOut);
402
403// mark pages not to be saved and not for scratch usage during restore
404void
405hibernate_page_list_set_volatile( hibernate_page_list_t * page_list,
406				  hibernate_page_list_t * page_list_wired,
407				  uint32_t * pagesOut);
408
409void
410hibernate_page_list_discard(hibernate_page_list_t * page_list);
411
412int
413hibernate_should_abort(void);
414
415void
416hibernate_set_page_state(hibernate_page_list_t * page_list, hibernate_page_list_t * page_list_wired,
417				vm_offset_t ppnum, vm_offset_t count, uint32_t kind);
418
419void
420hibernate_page_bitset(hibernate_page_list_t * list, boolean_t set, uint32_t page);
421
422boolean_t
423hibernate_page_bittst(hibernate_page_list_t * list, uint32_t page);
424
425hibernate_bitmap_t *
426hibernate_page_bitmap_pin(hibernate_page_list_t * list, uint32_t * page);
427
428uint32_t
429hibernate_page_bitmap_count(hibernate_bitmap_t * bitmap, uint32_t set, uint32_t page);
430
431uintptr_t
432hibernate_restore_phys_page(uint64_t src, uint64_t dst, uint32_t len, uint32_t procFlags);
433
434void
435hibernate_machine_init(void);
436
437uint32_t
438hibernate_write_image(void);
439
440long
441hibernate_machine_entrypoint(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
442long
443hibernate_kernel_entrypoint(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
444void
445hibernate_newruntime_map(void * map, vm_size_t map_size,
446			    uint32_t system_table_offset);
447
448
449extern uint32_t    gIOHibernateState;
450extern uint32_t    gIOHibernateMode;
451extern uint32_t    gIOHibernateDebugFlags;
452extern uint32_t    gIOHibernateFreeTime;	// max time to spend freeing pages (ms)
453extern uint8_t     gIOHibernateRestoreStack[];
454extern uint8_t     gIOHibernateRestoreStackEnd[];
455extern IOHibernateImageHeader *    gIOHibernateCurrentHeader;
456
457#define HIBLOG(fmt, args...)	\
458    { kprintf(fmt, ## args); printf(fmt, ## args); }
459
460#define HIBPRINT(fmt, args...)	\
461    { kprintf(fmt, ## args); }
462
463#endif /* KERNEL */
464
465// gIOHibernateState, kIOHibernateStateKey
466enum
467{
468    kIOHibernateStateInactive            = 0,
469    kIOHibernateStateHibernating 	 = 1,	/* writing image */
470    kIOHibernateStateWakingFromHibernate = 2	/* booted and restored image */
471};
472
473// gIOHibernateMode, kIOHibernateModeKey
474enum
475{
476    kIOHibernateModeOn      = 0x00000001,
477    kIOHibernateModeSleep   = 0x00000002,
478    kIOHibernateModeEncrypt = 0x00000004,
479    kIOHibernateModeDiscardCleanInactive = 0x00000008,
480    kIOHibernateModeDiscardCleanActive   = 0x00000010,
481    kIOHibernateModeSwitch	= 0x00000020,
482    kIOHibernateModeRestart	= 0x00000040,
483    kIOHibernateModeSSDInvert	= 0x00000080,
484    kIOHibernateModeFileResize	= 0x00000100,
485};
486
487// IOHibernateImageHeader.signature
488enum
489{
490    kIOHibernateHeaderSignature        = 0x73696d65,
491    kIOHibernateHeaderInvalidSignature = 0x7a7a7a7a
492};
493
494// kind for hibernate_set_page_state()
495enum
496{
497    kIOHibernatePageStateFree        = 0,
498    kIOHibernatePageStateWiredSave   = 1,
499    kIOHibernatePageStateUnwiredSave = 2
500};
501
502#define kIOHibernateModeKey		"Hibernate Mode"
503#define kIOHibernateFileKey		"Hibernate File"
504#define kIOHibernateFileMinSizeKey	"Hibernate File Min"
505#define kIOHibernateFileMaxSizeKey	"Hibernate File Max"
506#define kIOHibernateFreeRatioKey	"Hibernate Free Ratio"
507#define kIOHibernateFreeTimeKey		"Hibernate Free Time"
508
509#define kIOHibernateStateKey		"IOHibernateState"
510#define kIOHibernateFeatureKey		"Hibernation"
511#define kIOHibernatePreviewBufferKey	"IOPreviewBuffer"
512
513#ifndef kIOHibernatePreviewActiveKey
514#define kIOHibernatePreviewActiveKey	"IOHibernatePreviewActive"
515// values for kIOHibernatePreviewActiveKey
516enum {
517    kIOHibernatePreviewActive  = 0x00000001,
518    kIOHibernatePreviewUpdates = 0x00000002
519};
520#endif
521
522#define kIOHibernateOptionsKey      "IOHibernateOptions"
523#define kIOHibernateGfxStatusKey    "IOHibernateGfxStatus"
524enum {
525    kIOHibernateGfxStatusUnknown = ((int32_t) 0xFFFFFFFF)
526};
527
528#define kIOHibernateBootImageKey	"boot-image"
529#define kIOHibernateBootImageKeyKey	"boot-image-key"
530#define kIOHibernateBootSignatureKey	"boot-signature"
531
532#define kIOHibernateMemorySignatureKey	  "memory-signature"
533#define kIOHibernateMemorySignatureEnvKey "mem-sig"
534#define kIOHibernateMachineSignatureKey	  "machine-signature"
535
536#define kIOHibernateRTCVariablesKey	"IOHibernateRTCVariables"
537#define kIOHibernateSMCVariablesKey	"IOHibernateSMCVariables"
538
539#define kIOHibernateBootSwitchVarsKey	"boot-switch-vars"
540
541#define kIOHibernateBootNoteKey		"boot-note"
542
543
544#define kIOHibernateUseKernelInterpreter    0x80000000
545
546enum
547{
548	kIOPreviewImageIndexDesktop = 0,
549	kIOPreviewImageIndexLockScreen = 1,
550	kIOPreviewImageCount = 2
551};
552
553enum
554{
555	kIOScreenLockNoLock          = 1,
556	kIOScreenLockUnlocked        = 2,
557	kIOScreenLockLocked          = 3,
558	kIOScreenLockFileVaultDialog = 4,
559};
560
561#define kIOScreenLockStateKey      "IOScreenLockState"
562
563#endif /* ! __IOKIT_IOHIBERNATEPRIVATE_H */
564
565#ifdef __cplusplus
566}
567#endif
568