Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch_Modules/i386/boot2/resume.c

1/*
2 * resume.c
3 *
4 *
5 * Created by mackerintel on 1/22/09.
6 * Copyright 2009 mackerintel. All rights reserved.
7 *
8 */
9
10#include "saio_internal.h"
11#include "libsa.h"
12#include "IOHibernatePrivate.h"
13#include "memory.h"
14#include "bootstruct.h"
15#include "boot.h"
16#include "pci.h"
17
18extern int previewTotalSectors;
19extern int previewLoadedSectors;
20extern uint8_t *previewSaveunder;
21
22static unsigned long getmemorylimit(void)
23{
24int line;
25int i;
26MemoryRange *mp = bootInfo->memoryMap;
27
28// Activate and clear page 1
29line = 1;
30for (i = 0; i < bootInfo->memoryMapCount; i++)
31{
32if((mp->type == 1) && ((unsigned long)mp->base == 0x100000))
33{
34return (unsigned long)(mp->base + mp->length);
35}
36mp++;
37}
38return 0x10000000;
39}
40
41static void WakeKernel(IOHibernateImageHeader * header)
42{
43uint32_t proc;
44unsigned long cnt, newSP;
45unsigned long *src, *dst;
46unsigned int count;
47unsigned int page;
48unsigned int compressedSize;
49int32_t byteCnt;
50u_int32_t lowHalf, highHalf;
51u_int32_t sum;
52
53printf("\nWake Kernel!\n");
54
55dst = (unsigned long *) (header->restore1CodePage << 12);
56count = header->restore1PageCount;
57proc = (header->restore1CodeOffset + ((uint32_t) dst));
58newSP = header->restore1StackOffset + (header->restore1CodePage << 12);
59
60src = (unsigned long *) (((u_int32_t) &header->fileExtentMap[0])
61 + header->fileExtentMapSize);
62sum = 0;
63
64for (page = 0; page < count; page++)
65{
66compressedSize = 4096;
67
68lowHalf = 1;
69highHalf = 0;
70
71for (cnt = 0; cnt < compressedSize; cnt += 0x20)
72{
73dst[0] = src[0];
74dst[1] = src[1];
75dst[2] = src[2];
76dst[3] = src[3];
77dst[4] = src[4];
78dst[5] = src[5];
79dst[6] = src[6];
80dst[7] = src[7];
81for (byteCnt = 0; byteCnt < 0x20; byteCnt++)
82{
83lowHalf += ((u_int8_t *) dst)[byteCnt];
84highHalf += lowHalf;
85}
86src += 8;
87dst += 8;
88}
89
90lowHalf %= 65521L;
91highHalf %= 65521L;
92sum += (highHalf << 16) | lowHalf;
93}
94header->actualRestore1Sum = sum;
95startprog (proc, header);
96
97return;
98}
99
100void HibernateBoot(char *image_filename)
101{
102long long size, imageSize, codeSize, allocSize;
103long mem_base;
104IOHibernateImageHeader _header;
105IOHibernateImageHeader * header = &_header;
106long buffer;
107
108size = ReadFileAtOffset (image_filename, header, 0, sizeof(IOHibernateImageHeader));
109printf("header read size %x\n", size);
110
111imageSize = header->image1Size;
112codeSize = header->restore1PageCount << 12;
113if (kIOHibernateHeaderSignature != header->signature)
114{
115printf ("Incorrect image signature\n");
116return;
117}
118if (header->encryptStart)
119{
120printf ("Resuming from Encrypted image is unsupported.\n"
121"Uncheck \"Use secure virtual memory\" in \"Security\" pane on system preferences.\n"
122"Press any key to proceed with normal boot.\n");
123getchar();
124return;
125}
126// depends on NVRAM
127#if 0
128{
129uint32_t machineSignature;
130size = GetProp(gChosenPH, kIOHibernateMachineSignatureKey,
131 (char *)&machineSignature, sizeof(machineSignature));
132if (size != sizeof(machineSignature))
133{
134machineSignature = 0;
135}
136if (machineSignature != header->machineSignature)
137{
138break;
139}
140}
141#endif
142
143allocSize = imageSize + ((4095 + sizeof(hibernate_graphics_t)) & ~4095);
144
145mem_base = getmemorylimit() - allocSize;//TODO: lower this
146
147printf("mem_base %x\n", mem_base);
148if (((long long)mem_base + allocSize) < (1024 * bootInfo->extmem + 0x100000))
149{
150printf ("Not enough space to restore image. Press any key to proceed with normal boot.\n");
151getchar();
152return;
153}
154
155bcopy(header, (void *) mem_base, sizeof(IOHibernateImageHeader));
156header = (IOHibernateImageHeader *) mem_base;
157
158imageSize -= sizeof(IOHibernateImageHeader);
159buffer = (long)(header + 1);
160
161if (header->previewSize)
162{
163uint64_t preview_offset = header->fileExtentMapSize - sizeof(header->fileExtentMap) + codeSize;
164uint8_t progressSaveUnder[kIOHibernateProgressCount][kIOHibernateProgressSaveUnderSize];
165
166ReadFileAtOffset (image_filename, (char *)buffer, sizeof(IOHibernateImageHeader), preview_offset+header->previewSize);
167drawPreview ((void *)(long)(buffer+preview_offset + header->previewPageListSize), &(progressSaveUnder[0][0]));
168previewTotalSectors = (imageSize-(preview_offset+header->previewSize))/512;
169previewLoadedSectors = 0;
170previewSaveunder = &(progressSaveUnder[0][0]);
171if (preview_offset+header->previewSize<imageSize)
172{
173ReadFileAtOffset (image_filename, (char *)(long)(buffer+preview_offset+header->previewSize),
174 sizeof(IOHibernateImageHeader)+preview_offset+header->previewSize,
175 imageSize-(preview_offset+header->previewSize));
176}
177previewTotalSectors = 0;
178previewLoadedSectors = 0;
179previewSaveunder = 0;
180#if 0
181AsereBLN:
182check_vga_nvidia() didn't work as expected (recursion level > 0 & return value).
183Unforutnaltely I cannot find a note why to switch back to text mode for nVidia cards only
184and because it check_vga_nvidia does not work (cards normally are behind a bridge) I will
185remove it completely
186setVideoMode( VGA_TEXT_MODE, 0 );
187#endif
188}
189else
190ReadFileAtOffset (image_filename, (char *)buffer, sizeof(IOHibernateImageHeader), imageSize);
191
192// Depends on NVRAM
193#if 0
194if (header->encryptStart)
195{
196// decryption data
197static const unsigned char first_iv[AES_BLOCK_SIZE]
198= { 0xa3, 0x63, 0x65, 0xa9, 0x0b, 0x71, 0x7b, 0x1c,
1990xdf, 0x9e, 0x5f, 0x32, 0xd7, 0x61, 0x63, 0xda };
200hibernate_cryptvars_t _cryptvars;
201hibernate_cryptvars_t * cryptvars = &_cryptvars;
202
203aes_decrypt_key(&decryptkey,
204decryptkeysize,
205&cryptvars->ctx.decrypt);
206
207// set the vector for the following decryptions
208bcopy(((uint8_t *) header) + header->image1Size - AES_BLOCK_SIZE,
209&cryptvars->aes_iv[0], AES_BLOCK_SIZE);
210
211// decrypt the buffer
212uint32_t len = (uint32_t)(header->image1Size - header->encryptStart);
213aes_decrypt_cbc(((uint8_t *) header) + header->encryptStart,
214&first_iv[0],
215len >> 4,
216((uint8_t *) header) + header->encryptStart,
217&cryptvars->ctx.decrypt);
218bzero(&cryptvars->aes_iv[0], sizeof(cryptvars));
219bzero(&decryptkey, sizeof(decryptkey));
220}
221#endif
222
223WakeKernel(header);
224}
225

Archive Download this file

Revision: 2238