Chameleon

Chameleon Svn Source Tree

Root/branches/meklortOld/i386/boot2/resume.c

Source at commit 1146 created 12 years 10 months ago.
By azimutz, Sync with trunk (r1145). Add nVidia dev id's, 0DF4 for "GeForce GT 450M" (issue 99) and 1251 for "GeForce GTX 560M" (thanks to oSxFr33k for testing).
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
54verbose("\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));
108verbose("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");
122getc ();
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();
140
141if (mem_base < ((1024 * bootInfo->extmem) + 0x100000))
142{
143printf ("Not enough space to restore image. Press any key to proceed with normal boot.\n");
144getc ();
145return;
146}
147mem_base -= allocSize;//TODO: lower this
148verbose("mem_base %x\n", mem_base);
149
150
151bcopy(header, (void *) mem_base, sizeof(IOHibernateImageHeader));
152header = (IOHibernateImageHeader *) mem_base;
153
154imageSize -= sizeof(IOHibernateImageHeader);
155buffer = (long)(header + 1);
156
157if (header->previewSize)
158{
159uint64_t preview_offset = header->fileExtentMapSize - sizeof(header->fileExtentMap) + codeSize;
160uint8_t progressSaveUnder[kIOHibernateProgressCount][kIOHibernateProgressSaveUnderSize];
161
162ReadFileAtOffset (image_filename, (char *)buffer, sizeof(IOHibernateImageHeader), preview_offset+header->previewSize);
163#ifndef OPTION_ROM
164drawPreview ((void *)(long)(buffer+preview_offset + header->previewPageListSize), &(progressSaveUnder[0][0]));
165#endif
166previewTotalSectors = (imageSize-(preview_offset+header->previewSize))/512;
167previewLoadedSectors = 0;
168previewSaveunder = &(progressSaveUnder[0][0]);
169if (preview_offset+header->previewSize<imageSize)
170ReadFileAtOffset (image_filename, (char *)(long)(buffer+preview_offset+header->previewSize),
171 sizeof(IOHibernateImageHeader)+preview_offset+header->previewSize,
172 imageSize-(preview_offset+header->previewSize));
173previewTotalSectors = 0;
174previewLoadedSectors = 0;
175previewSaveunder = 0;
176#if 0
177AsereBLN:
178check_vga_nvidia() didn''t work as expected (recursion level > 0 & return value).
179Unforutnaltely I cannot find a note why to switch back to text mode for nVidia cards only
180and because it check_vga_nvidia does not work (cards normally are behind a bridge) I will
181remove it completely
182setVideoMode( VGA_TEXT_MODE, 0 );
183#endif
184}
185else
186ReadFileAtOffset (image_filename, (char *)buffer, sizeof(IOHibernateImageHeader), imageSize);
187
188// Depends on NVRAM
189#if 0
190if (header->encryptStart) {
191// decryption data
192static const unsigned char first_iv[AES_BLOCK_SIZE]
193= { 0xa3, 0x63, 0x65, 0xa9, 0x0b, 0x71, 0x7b, 0x1c,
1940xdf, 0x9e, 0x5f, 0x32, 0xd7, 0x61, 0x63, 0xda };
195hibernate_cryptvars_t _cryptvars;
196hibernate_cryptvars_t * cryptvars = &_cryptvars;
197
198aes_decrypt_key(&decryptkey,
199decryptkeysize,
200&cryptvars->ctx.decrypt);
201
202// set the vector for the following decryptions
203bcopy(((uint8_t *) header) + header->image1Size - AES_BLOCK_SIZE,
204&cryptvars->aes_iv[0], AES_BLOCK_SIZE);
205
206// decrypt the buffer
207uint32_t len = (uint32_t)(header->image1Size - header->encryptStart);
208aes_decrypt_cbc(((uint8_t *) header) + header->encryptStart,
209&first_iv[0],
210len >> 4,
211((uint8_t *) header) + header->encryptStart,
212&cryptvars->ctx.decrypt);
213bzero(&cryptvars->aes_iv[0], sizeof(cryptvars));
214bzero(&decryptkey, sizeof(decryptkey));
215}
216#endif
217
218WakeKernel(header);
219}
220

Archive Download this file

Revision: 1146