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[68];		// make sizeof == 512
106
107    uint64_t	encryptEnd __attribute__ ((packed));
108    uint64_t	deviceBase __attribute__ ((packed));
109
110    uint32_t		fileExtentMapSize;
111    IOPolledFileExtent	fileExtentMap[2];
112};
113typedef struct IOHibernateImageHeader IOHibernateImageHeader;
114
115enum
116{
117    kIOHibernateDebugRestoreLogs = 0x00000001
118};
119
120// options & IOHibernateOptions property
121enum
122{
123    kIOHibernateOptionSSD           = 0x00000001,
124    kIOHibernateOptionColor         = 0x00000002,
125    kIOHibernateOptionProgress      = 0x00000004,
126    kIOHibernateOptionDarkWake      = 0x00000008,
127};
128
129struct hibernate_bitmap_t
130{
131    uint32_t	first_page;
132    uint32_t	last_page;
133    uint32_t	bitmapwords;
134    uint32_t	bitmap[0];
135};
136typedef struct hibernate_bitmap_t hibernate_bitmap_t;
137
138struct hibernate_page_list_t
139{
140    uint32_t		  list_size;
141    uint32_t		  page_count;
142    uint32_t		  bank_count;
143    hibernate_bitmap_t    bank_bitmap[0];
144};
145typedef struct hibernate_page_list_t hibernate_page_list_t;
146
147#if defined(_AES_H)
148
149struct hibernate_cryptwakevars_t
150{
151    uint8_t aes_iv[AES_BLOCK_SIZE];
152};
153typedef struct hibernate_cryptwakevars_t hibernate_cryptwakevars_t;
154
155struct hibernate_cryptvars_t
156{
157    uint8_t aes_iv[AES_BLOCK_SIZE];
158    aes_ctx ctx;
159};
160typedef struct hibernate_cryptvars_t hibernate_cryptvars_t;
161
162#endif /* defined(_AES_H) */
163
164enum
165{
166    kIOHibernateHandoffType                 = 0x686f0000,
167    kIOHibernateHandoffTypeEnd              = kIOHibernateHandoffType + 0,
168    kIOHibernateHandoffTypeGraphicsInfo     = kIOHibernateHandoffType + 1,
169    kIOHibernateHandoffTypeCryptVars        = kIOHibernateHandoffType + 2,
170    kIOHibernateHandoffTypeMemoryMap        = kIOHibernateHandoffType + 3,
171    kIOHibernateHandoffTypeDeviceTree       = kIOHibernateHandoffType + 4,
172    kIOHibernateHandoffTypeDeviceProperties = kIOHibernateHandoffType + 5,
173    kIOHibernateHandoffTypeKeyStore         = kIOHibernateHandoffType + 6,
174};
175
176struct IOHibernateHandoff
177{
178    uint32_t type;
179    uint32_t bytecount;
180    uint8_t  data[];
181};
182typedef struct IOHibernateHandoff IOHibernateHandoff;
183
184enum
185{
186    kIOHibernateProgressCount         = 19,
187    kIOHibernateProgressWidth         = 7,
188    kIOHibernateProgressHeight        = 16,
189    kIOHibernateProgressSpacing       = 3,
190    kIOHibernateProgressOriginY       = 81,
191
192    kIOHibernateProgressSaveUnderSize = 2*5+14*2,
193
194    kIOHibernateProgressLightGray     = 230,
195    kIOHibernateProgressMidGray       = 174,
196    kIOHibernateProgressDarkGray      = 92
197};
198
199enum
200{
201    kIOHibernatePostWriteSleep   = 0,
202    kIOHibernatePostWriteWake    = 1,
203    kIOHibernatePostWriteHalt    = 2,
204    kIOHibernatePostWriteRestart = 3
205};
206
207
208struct hibernate_graphics_t
209{
210    uint32_t physicalAddress;	// Base address of video memory
211    int32_t  gfxStatus;         // EFI config restore status
212    uint32_t rowBytes;   		// Number of bytes per pixel row
213    uint32_t width;      		// Width
214    uint32_t height;     		// Height
215    uint32_t depth;      		// Pixel Depth
216
217    uint8_t progressSaveUnder[kIOHibernateProgressCount][kIOHibernateProgressSaveUnderSize];
218};
219typedef struct hibernate_graphics_t hibernate_graphics_t;
220
221#define DECLARE_IOHIBERNATEPROGRESSALPHA				\
222static const uint8_t gIOHibernateProgressAlpha			\
223[kIOHibernateProgressHeight][kIOHibernateProgressWidth] = 	\
224{								\
225    { 0x00,0x63,0xd8,0xf0,0xd8,0x63,0x00 },			\
226    { 0x51,0xff,0xff,0xff,0xff,0xff,0x51 },			\
227    { 0xae,0xff,0xff,0xff,0xff,0xff,0xae },			\
228    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
229    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
230    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
231    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
232    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
233    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
234    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
235    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
236    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
237    { 0xc3,0xff,0xff,0xff,0xff,0xff,0xc3 },			\
238    { 0xae,0xff,0xff,0xff,0xff,0xff,0xae },			\
239    { 0x54,0xff,0xff,0xff,0xff,0xff,0x54 },			\
240    { 0x00,0x66,0xdb,0xf3,0xdb,0x66,0x00 }			\
241};
242
243struct hibernate_preview_t
244{
245    uint32_t  imageCount;	// Number of images
246    uint32_t  width;      	// Width
247    uint32_t  height;     	// Height
248    uint32_t  depth;      	// Pixel Depth
249    uint32_t  lockTime;     // Lock time
250    uint32_t  reservedG[8]; // reserved
251    uint32_t  reservedK[8]; // reserved
252};
253typedef struct hibernate_preview_t hibernate_preview_t;
254
255#ifdef KERNEL
256
257#ifdef __cplusplus
258
259void     IOHibernateSystemInit(IOPMrootDomain * rootDomain);
260
261IOReturn IOHibernateSystemSleep(void);
262IOReturn IOHibernateIOKitSleep(void);
263IOReturn IOHibernateSystemHasSlept(void);
264IOReturn IOHibernateSystemWake(void);
265IOReturn IOHibernateSystemPostWake(void);
266bool     IOHibernateWasScreenLocked(void);
267void     IOHibernateSetScreenLocked(uint32_t lockState);
268void     IOHibernateSystemRestart(void);
269
270#endif /* __cplusplus */
271
272#ifdef _SYS_CONF_H_
273typedef void (*kern_get_file_extents_callback_t)(void * ref, uint64_t start, uint64_t size);
274
275struct kern_direct_file_io_ref_t *
276kern_open_file_for_direct_io(const char * name,
277			     kern_get_file_extents_callback_t callback,
278			     void * callback_ref,
279
280                             off_t set_file_size,
281
282                             off_t write_file_offset,
283                             caddr_t write_file_addr,
284                             vm_size_t write_file_len,
285
286			     dev_t * partition_device_result,
287			     dev_t * image_device_result,
288                             uint64_t * partitionbase_result,
289                             uint64_t * maxiocount_result,
290                             uint32_t * oflags);
291void
292kern_close_file_for_direct_io(struct kern_direct_file_io_ref_t * ref,
293			      off_t write_offset, caddr_t addr, vm_size_t write_length,
294			      off_t discard_offset, off_t discard_end);
295#endif /* _SYS_CONF_H_ */
296
297hibernate_page_list_t *
298hibernate_page_list_allocate(boolean_t log);
299
300kern_return_t
301hibernate_setup(IOHibernateImageHeader * header,
302                        uint32_t  free_page_ratio,
303                        uint32_t  free_page_time,
304                        boolean_t vmflush,
305			hibernate_page_list_t ** page_list_ret,
306			hibernate_page_list_t ** page_list_wired_ret,
307			hibernate_page_list_t ** page_list_pal_ret);
308kern_return_t
309hibernate_teardown(hibernate_page_list_t * page_list,
310                    hibernate_page_list_t * page_list_wired,
311                    hibernate_page_list_t * page_list_pal);
312
313kern_return_t
314hibernate_processor_setup(IOHibernateImageHeader * header);
315
316void
317hibernate_gobble_pages(uint32_t gobble_count, uint32_t free_page_time);
318void
319hibernate_free_gobble_pages(void);
320
321void
322hibernate_vm_lock_queues(void);
323void
324hibernate_vm_unlock_queues(void);
325
326void
327hibernate_vm_lock(void);
328void
329hibernate_vm_unlock(void);
330
331// mark pages not to be saved, based on VM system accounting
332void
333hibernate_page_list_setall(hibernate_page_list_t * page_list,
334			   hibernate_page_list_t * page_list_wired,
335			   hibernate_page_list_t * page_list_pal,
336			   boolean_t preflight,
337			   uint32_t * pagesOut);
338
339// mark pages to be saved, or pages not to be saved but available
340// for scratch usage during restore
341void
342hibernate_page_list_setall_machine(hibernate_page_list_t * page_list,
343                                    hibernate_page_list_t * page_list_wired,
344                                    boolean_t preflight,
345                                    uint32_t * pagesOut);
346
347// mark pages not to be saved and not for scratch usage during restore
348void
349hibernate_page_list_set_volatile( hibernate_page_list_t * page_list,
350				  hibernate_page_list_t * page_list_wired,
351				  uint32_t * pagesOut);
352
353void
354hibernate_page_list_discard(hibernate_page_list_t * page_list);
355
356int
357hibernate_should_abort(void);
358
359void
360hibernate_set_page_state(hibernate_page_list_t * page_list, hibernate_page_list_t * page_list_wired,
361				vm_offset_t ppnum, vm_offset_t count, uint32_t kind);
362
363void
364hibernate_page_bitset(hibernate_page_list_t * list, boolean_t set, uint32_t page);
365
366boolean_t
367hibernate_page_bittst(hibernate_page_list_t * list, uint32_t page);
368
369hibernate_bitmap_t *
370hibernate_page_bitmap_pin(hibernate_page_list_t * list, uint32_t * page);
371
372uint32_t
373hibernate_page_bitmap_count(hibernate_bitmap_t * bitmap, uint32_t set, uint32_t page);
374
375uintptr_t
376hibernate_restore_phys_page(uint64_t src, uint64_t dst, uint32_t len, uint32_t procFlags);
377
378void
379hibernate_machine_init(void);
380
381uint32_t
382hibernate_write_image(void);
383
384long
385hibernate_machine_entrypoint(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
386long
387hibernate_kernel_entrypoint(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
388void
389hibernate_newruntime_map(void * map, vm_size_t map_size,
390			    uint32_t system_table_offset);
391
392
393extern uint32_t    gIOHibernateState;
394extern uint32_t    gIOHibernateMode;
395extern uint32_t    gIOHibernateDebugFlags;
396extern uint32_t    gIOHibernateFreeTime;	// max time to spend freeing pages (ms)
397extern uint8_t     gIOHibernateRestoreStack[];
398extern uint8_t     gIOHibernateRestoreStackEnd[];
399extern IOHibernateImageHeader *    gIOHibernateCurrentHeader;
400
401#define HIBLOG(fmt, args...)	\
402    { kprintf(fmt, ## args); printf(fmt, ## args); }
403
404#define HIBPRINT(fmt, args...)	\
405    { kprintf(fmt, ## args); }
406
407#endif /* KERNEL */
408
409// gIOHibernateState, kIOHibernateStateKey
410enum
411{
412    kIOHibernateStateInactive            = 0,
413    kIOHibernateStateHibernating 	 = 1,	/* writing image */
414    kIOHibernateStateWakingFromHibernate = 2	/* booted and restored image */
415};
416
417// gIOHibernateMode, kIOHibernateModeKey
418enum
419{
420    kIOHibernateModeOn      = 0x00000001,
421    kIOHibernateModeSleep   = 0x00000002,
422    kIOHibernateModeEncrypt = 0x00000004,
423    kIOHibernateModeDiscardCleanInactive = 0x00000008,
424    kIOHibernateModeDiscardCleanActive   = 0x00000010,
425    kIOHibernateModeSwitch	= 0x00000020,
426    kIOHibernateModeRestart	= 0x00000040,
427    kIOHibernateModeSSDInvert	= 0x00000080,
428    kIOHibernateModeFileResize	= 0x00000100,
429};
430
431// IOHibernateImageHeader.signature
432enum
433{
434    kIOHibernateHeaderSignature        = 0x73696d65,
435    kIOHibernateHeaderInvalidSignature = 0x7a7a7a7a
436};
437
438// kind for hibernate_set_page_state()
439enum
440{
441    kIOHibernatePageStateFree        = 0,
442    kIOHibernatePageStateWiredSave   = 1,
443    kIOHibernatePageStateUnwiredSave = 2
444};
445
446#define kIOHibernateModeKey		"Hibernate Mode"
447#define kIOHibernateFileKey		"Hibernate File"
448#define kIOHibernateFileMinSizeKey	"Hibernate File Min"
449#define kIOHibernateFileMaxSizeKey	"Hibernate File Max"
450#define kIOHibernateFreeRatioKey	"Hibernate Free Ratio"
451#define kIOHibernateFreeTimeKey		"Hibernate Free Time"
452
453#define kIOHibernateStateKey		"IOHibernateState"
454#define kIOHibernateFeatureKey		"Hibernation"
455#define kIOHibernatePreviewBufferKey	"IOPreviewBuffer"
456
457#ifndef kIOHibernatePreviewActiveKey
458#define kIOHibernatePreviewActiveKey	"IOHibernatePreviewActive"
459// values for kIOHibernatePreviewActiveKey
460enum {
461    kIOHibernatePreviewActive  = 0x00000001,
462    kIOHibernatePreviewUpdates = 0x00000002
463};
464#endif
465
466#define kIOHibernateOptionsKey      "IOHibernateOptions"
467#define kIOHibernateGfxStatusKey    "IOHibernateGfxStatus"
468enum {
469    kIOHibernateGfxStatusUnknown = ((int32_t) 0xFFFFFFFF)
470};
471
472#define kIOHibernateBootImageKey	"boot-image"
473#define kIOHibernateBootImageKeyKey	"boot-image-key"
474#define kIOHibernateBootSignatureKey	"boot-signature"
475
476#define kIOHibernateMemorySignatureKey	  "memory-signature"
477#define kIOHibernateMemorySignatureEnvKey "mem-sig"
478#define kIOHibernateMachineSignatureKey	  "machine-signature"
479
480#define kIOHibernateRTCVariablesKey	"IOHibernateRTCVariables"
481#define kIOHibernateSMCVariablesKey	"IOHibernateSMCVariables"
482
483#define kIOHibernateBootSwitchVarsKey	"boot-switch-vars"
484
485#define kIOHibernateBootNoteKey		"boot-note"
486
487
488#define kIOHibernateUseKernelInterpreter    0x80000000
489
490enum
491{
492	kIOPreviewImageIndexDesktop = 0,
493	kIOPreviewImageIndexLockScreen = 1,
494	kIOPreviewImageCount = 2
495};
496
497enum
498{
499	kIOScreenLockNoLock          = 1,
500	kIOScreenLockUnlocked        = 2,
501	kIOScreenLockLocked          = 3,
502	kIOScreenLockFileVaultDialog = 4,
503};
504
505#define kIOScreenLockStateKey      "IOScreenLockState"
506
507#endif /* ! __IOKIT_IOHIBERNATEPRIVATE_H */
508
509#ifdef __cplusplus
510}
511#endif
512