Chameleon

Chameleon Svn Source Tree

Root/tags/2.3/i386/boot2/resume.c

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

Archive Download this file

Revision: 2862