Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 1468