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

Archive Download this file

Revision: 789