Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 962