1 | /* Copied from 915 resolution created by steve tomljenovic␊ |
2 | *␊ |
3 | * This code is based on the techniques used in :␊ |
4 | *␊ |
5 | * - 855patch. Many thanks to Christian Zietz (czietz gmx net)␊ |
6 | * for demonstrating how to shadow the VBIOS into system RAM␊ |
7 | * and then modify it.␊ |
8 | *␊ |
9 | * - 1280patch by Andrew Tipton (andrewtipton null li).␊ |
10 | *␊ |
11 | * - 855resolution by Alain Poirier␊ |
12 | *␊ |
13 | * This source code is into the public domain.␊ |
14 | */␊ |
15 | ␊ |
16 | #include "libsaio.h"␊ |
17 | //#include "autoresolution.h"␊ |
18 | #include "nvidia_resolution.h"␊ |
19 | #include "ati_resolution.h"␊ |
20 | #include "gma_resolution.h"␊ |
21 | #include "../boot2/graphics.h"␊ |
22 | ␊ |
23 | char * chipsetTypeNames[] = {␊ |
24 | ␉"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",␊ |
25 | ␉"946GZ", "950GM", "955X", "G965", "Q965", "965GM", "975X",␊ |
26 | ␉"P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500", "3150"␊ |
27 | };␊ |
28 | ␊ |
29 | uint32_t getChipsetId(void)␊ |
30 | {␊ |
31 | ␉outl(0xcf8, 0x80000000);␊ |
32 | ␉return inl(0xcfc);␊ |
33 | }␊ |
34 | ␊ |
35 | chipsetType getChipset(uint32_t id)␊ |
36 | {␊ |
37 | ␉chipsetType type;␊ |
38 | ␉␊ |
39 | ␉switch (id)␊ |
40 | ␉{␊ |
41 | ␉␉case 0x35758086:␊ |
42 | ␉␉␉type = CT_830;␊ |
43 | ␉␉␉break;␊ |
44 | ␉␉␊ |
45 | ␉␉case 0x25608086:␊ |
46 | ␉␉␉type = CT_845G;␊ |
47 | ␉␉␉break;␊ |
48 | ␉␉␉␉␊ |
49 | ␉␉case 0x35808086:␊ |
50 | ␉␉␉type = CT_855GM;␊ |
51 | ␉␉␉break;␊ |
52 | ␉␉␉␉␊ |
53 | ␉␉case 0x25708086:␊ |
54 | ␉␉␉type = CT_865G;␊ |
55 | ␉␉␉break;␊ |
56 | ␉␉␊ |
57 | ␉␉case 0x25808086:␊ |
58 | ␉␉␉type = CT_915G;␊ |
59 | ␉␉␉break;␊ |
60 | ␉␉␉␊ |
61 | ␉␉case 0x25908086:␊ |
62 | ␉␉␉type = CT_915GM;␊ |
63 | ␉␉␉break;␊ |
64 | ␉␉␉␊ |
65 | ␉␉case 0x27708086:␊ |
66 | ␉␉␉type = CT_945G;␊ |
67 | ␉␉␉break;␊ |
68 | ␉␉␉␊ |
69 | ␉␉case 0x27748086:␊ |
70 | ␉␉␉type = CT_955X;␊ |
71 | ␉␉␉break;␊ |
72 | ␉␉␉␊ |
73 | ␉␉case 0x277c8086:␊ |
74 | ␉␉␉type = CT_975X;␊ |
75 | ␉␉␉break;␊ |
76 | ␉␉␊ |
77 | ␉␉case 0x27a08086:␊ |
78 | ␉␉␉type = CT_945GM;␊ |
79 | ␉␉␉break;␊ |
80 | ␉␉␉␊ |
81 | ␉␉case 0x27ac8086:␊ |
82 | ␉␉␉type = CT_945GME;␊ |
83 | ␉␉␉break;␊ |
84 | ␊ |
85 | ␉␉case 0x27ae8086:␊ |
86 | ␉␉␉type = CT_950GM;␊ |
87 | ␉␉␉break;␊ |
88 | ␊ |
89 | ␉␉case 0x29708086:␊ |
90 | ␉␉␉type = CT_946GZ;␊ |
91 | ␉␉␉break;␊ |
92 | ␉␉␉␊ |
93 | ␉␉case 0x29a08086:␊ |
94 | ␉␉␉type = CT_G965;␊ |
95 | ␉␉␉break;␊ |
96 | ␉␉␉␊ |
97 | ␉␉case 0x29908086:␊ |
98 | ␉␉␉type = CT_Q965;␊ |
99 | ␉␉␉break;␊ |
100 | ␉␉␉␊ |
101 | ␉␉case 0x2a008086:␊ |
102 | ␉␉␉type = CT_965GM;␊ |
103 | ␉␉␉break;␊ |
104 | ␉␉␉␊ |
105 | ␉␉case 0x29e08086:␊ |
106 | ␉␉␉type = CT_X48;␊ |
107 | ␉␉␉break;␉␉␉␊ |
108 | ␉␉␉␊ |
109 | ␉␉case 0x2a408086:␊ |
110 | ␉␉␉type = CT_GM45;␊ |
111 | ␉␉␉break;␊ |
112 | ␉␉␉␊ |
113 | ␉␉case 0x2e108086:␊ |
114 | ␉␉case 0X2e908086:␊ |
115 | ␉␉␉type = CT_B43;␊ |
116 | ␉␉␉break;␊ |
117 | ␉␉␉␊ |
118 | ␉␉case 0x2e208086:␊ |
119 | ␉␉␉type = CT_P45;␊ |
120 | ␉␉␉break;␊ |
121 | ␉␉␉␊ |
122 | ␉␉case 0x2e308086:␊ |
123 | ␉␉␉type = CT_G41;␊ |
124 | ␉␉␉break;␊ |
125 | ␉␉␉␊ |
126 | ␉␉case 0x29c08086:␊ |
127 | ␉␉␉type = CT_G31;␊ |
128 | ␉␉␉break;␊ |
129 | ␉␉␉␊ |
130 | ␉␉case 0x29208086:␊ |
131 | ␉␉␉type = CT_G45;␊ |
132 | ␉␉␉break;␊ |
133 | ␉␉␉␊ |
134 | ␉␉case 0x81008086:␊ |
135 | ␉␉␉type = CT_500;␊ |
136 | ␉␉␉break;␊ |
137 | ␊ |
138 | ␉␉case 0xA0108086:␊ |
139 | ␉␉␉type = CT_3150;␊ |
140 | ␉␉␉break;␊ |
141 | ␊ |
142 | ␉␉default:␊ |
143 | ␉␉␉type = CT_UNKWN;␊ |
144 | ␉␉␉break;␊ |
145 | ␉}␊ |
146 | ␉return type;␊ |
147 | }␊ |
148 | ␊ |
149 | ␊ |
150 | void gtfTimings(uint32_t x, uint32_t y, uint32_t freq,␊ |
151 | ␉␉␉␉ uint32_t *clock,␊ |
152 | ␉␉␉␉ uint16_t *hSyncStart, uint16_t *hSyncEnd, uint16_t *hBlank,␊ |
153 | ␉␉␉␉ uint16_t *vSyncStart, uint16_t *vSyncEnd, uint16_t *vBlank)␊ |
154 | {␊ |
155 | ␉uint32_t hbl, vbl, vfreq;␊ |
156 | ␉␊ |
157 | ␉vbl = y + (y+1)/(20000/(11*freq) - 1) + 1;␊ |
158 | ␉␊ |
159 | ␉vfreq = vbl * freq;␊ |
160 | ␉hbl = 16 * (int)(x * (30 - 300000 / vfreq) /␊ |
161 | ␉␉␉␉␉ + (70 + 300000 / vfreq) / 16 + 0);␊ |
162 | ␉␊ |
163 | ␉*vSyncStart = y;␊ |
164 | ␉*vSyncEnd = y + 3;␊ |
165 | ␉*vBlank = vbl;␉␊ |
166 | ␉*hSyncStart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 ;␉␊ |
167 | ␉*hSyncEnd = x + hbl / 2;␉␊ |
168 | ␉*hBlank = x + hbl;␉␊ |
169 | ␉*clock = (x + hbl) * vfreq / 1000;␊ |
170 | }␊ |
171 | ␊ |
172 | ␊ |
173 | void getAspectRatio(sAspect* aspect, uint32_t x, uint32_t y)␊ |
174 | {␊ |
175 | ␉if ((y * 16 / 9) == x)␊ |
176 | ␉{␊ |
177 | ␉␉aspect->width = 16;␊ |
178 | ␉␉aspect->height = 9;␊ |
179 | ␉}␊ |
180 | ␉else if ((y * 16 / 10) == x)␊ |
181 | ␉{␊ |
182 | ␉␉aspect->width = 16;␊ |
183 | ␉␉aspect->height = 10;␊ |
184 | ␉}␊ |
185 | ␉else if ((y * 5 / 4) == x)␊ |
186 | ␉{␊ |
187 | ␉␉aspect->width = 5;␊ |
188 | ␉␉aspect->height = 4;␊ |
189 | ␉}␊ |
190 | ␉else if ((y * 15 / 9) == x)␊ |
191 | ␉{␊ |
192 | ␉␉aspect->width = 15;␊ |
193 | ␉␉aspect->height = 9;␊ |
194 | ␉}␊ |
195 | ␉else␊ |
196 | ␉{␊ |
197 | ␉␉aspect->width = 4;␊ |
198 | ␉␉aspect->height = 3;␊ |
199 | ␉}␊ |
200 | ␉PRINT("Aspect Ratio is %d/%d\n", aspect->width, aspect->height);␊ |
201 | }␊ |
202 | ␊ |
203 | ␊ |
204 | /*␊ |
205 | * initialize the mode tables chain␊ |
206 | * tablesCount represents the number of VESA tables in the vBios␊ |
207 | * return value is a pointer to the first table␊ |
208 | */␊ |
209 | sModeTable * intializeTables(vBiosMap * map, int tablesCount) {␊ |
210 | ␉map->modeTables = (sModeTable *)malloc(sizeof(sModeTable));␊ |
211 | ␉sModeTable * table = map->modeTables;␊ |
212 | ␉␊ |
213 | ␉PRINT("Creating %d Mode Tables\n", tablesCount);␊ |
214 | ␉␊ |
215 | ␉int i = tablesCount;␊ |
216 | ␉while ( i != 0 )␊ |
217 | ␉{␉␉␊ |
218 | ␉␉table->id = tablesCount - i;␊ |
219 | ␉␉PRINT("New table with id: %d\n", table->id);␊ |
220 | ␉␉␊ |
221 | ␉␉// opening the chain if it's the first table␊ |
222 | ␉␉if (i == tablesCount)␊ |
223 | ␉␉␉table->prev = NULL;␊ |
224 | ␉␉else // attache the table to the chain␊ |
225 | ␉␉␉table->prev = table; ␊ |
226 | ␉␉␊ |
227 | ␉␉//if there is more than one table, alloc the next one␊ |
228 | ␉␉if (i > 1)␊ |
229 | ␉␉{␊ |
230 | ␉␉␉table->next = (sModeTable *)malloc(sizeof(sModeTable));␊ |
231 | ␉␉␉table = table->next;␊ |
232 | ␉␉}␊ |
233 | ␉␉else // no more table, close the chain␊ |
234 | ␉␉␉table->next = NULL;␊ |
235 | ␉␉␊ |
236 | ␉␉i--;␊ |
237 | ␉}␊ |
238 | ␉␊ |
239 | ␉return map->modeTables;␊ |
240 | }␊ |
241 | ␊ |
242 | ␊ |
243 | //void closeVbios(vBiosMap * map); azi: dup - declared on header␊ |
244 | ␊ |
245 | vBiosMap * openVbios(chipsetType forcedChipset)␊ |
246 | {␊ |
247 | ␉uint32_t z;␊ |
248 | ␉vBiosMap * map = NEW(vBiosMap);␊ |
249 | ␉␊ |
250 | ␉for(z = 0; z < sizeof(vBiosMap); z++)␊ |
251 | ␉␉((char*)map)[z] = 0;␊ |
252 | ␉␊ |
253 | ␉/*␊ |
254 | ␉ * Determine chipset␊ |
255 | ␉ */␊ |
256 | ␉␊ |
257 | ␉if (forcedChipset == CT_UNKWN)␊ |
258 | ␉{␊ |
259 | ␉␉map->chipsetId = getChipsetId();␊ |
260 | ␉␉map->chipset = getChipset(map->chipsetId);␊ |
261 | ␉␉PRINT("Chipset is %s (pci id 0x%x)\n",chipsetTypeNames[map->chipset], map->chipsetId);␊ |
262 | ␉}␊ |
263 | ␉else if (forcedChipset != CT_UNKWN)␊ |
264 | ␉{␊ |
265 | ␉␉map->chipset = forcedChipset;␊ |
266 | ␉}␊ |
267 | ␉else␊ |
268 | ␉{␊ |
269 | ␉␉map->chipset = CT_915GM;␊ |
270 | ␉}␊ |
271 | ␉ ␊ |
272 | ␉/*␊ |
273 | ␉ * Map the video bios to memory␊ |
274 | ␉ */␊ |
275 | ␉␊ |
276 | ␉map->biosPtr=(uint8_t*)VBIOS_START;␊ |
277 | ␉␊ |
278 | ␉/*␊ |
279 | ␉ * Common initialisation␊ |
280 | ␉ */␊ |
281 | ␉␊ |
282 | ␉map->hasSwitched = false;␊ |
283 | ␉␊ |
284 | ␉/*␊ |
285 | ␉ * check if we have ATI Radeon and open atombios␊ |
286 | ␉ */␊ |
287 | ␉atiBiosTables atiTables;␊ |
288 | ␉␊ |
289 | ␉atiTables.base = map->biosPtr;␊ |
290 | ␉atiTables.atomRomHeader = (atomRomHeader *) (map->biosPtr + *(uint16_t *) (map->biosPtr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER)); ␊ |
291 | ␉␊ |
292 | ␉if (strcmp ((char *) atiTables.atomRomHeader->firmWareSignature, "ATOM") == 0)␊ |
293 | ␉{␊ |
294 | ␉␉map->bios = BT_ATI_1;␊ |
295 | ␉␉PRINT("We have an AtomBios Card\n");␊ |
296 | ␉␉return openAtiVbios(map, atiTables);␊ |
297 | ␉}␊ |
298 | ␊ |
299 | ␊ |
300 | ␉/*␊ |
301 | ␉ * check if we have NVidia␊ |
302 | ␉ */␊ |
303 | ␉if (map->bios != BT_ATI_1)␊ |
304 | ␉{␊ |
305 | ␉␉int i = 0;␊ |
306 | ␉␉while (i < 512) // we don't need to look through the whole bios, just the first 512 bytes␊ |
307 | ␉␉{␊ |
308 | ␉␉␉if ((map->biosPtr[i] == 'N') ␊ |
309 | ␉␉␉␉&& (map->biosPtr[i+1] == 'V') ␊ |
310 | ␉␉␉␉&& (map->biosPtr[i+2] == 'I') ␊ |
311 | ␉␉␉␉&& (map->biosPtr[i+3] == 'D')) ␊ |
312 | ␉␉␉{␊ |
313 | ␉␉␉␉map->bios = BT_NVDA;␊ |
314 | ␉␉␉␉PRINT("We have an NVIDIA Card\n");␊ |
315 | ␉␉␉␉return openNvidiaVbios(map);␊ |
316 | ␉␉␉␉break;␊ |
317 | ␉␉␉}␊ |
318 | ␉␉␉i++;␊ |
319 | ␉␉}␊ |
320 | ␉}␊ |
321 | ␉␊ |
322 | ␉/*␊ |
323 | ␉ * check if we have Intel␊ |
324 | ␉ */␊ |
325 | ␉ ␊ |
326 | ␉if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA))␊ |
327 | ␉{␊ |
328 | ␉␉int i = 0;␊ |
329 | ␉␉while (i < VBIOS_SIZE)␊ |
330 | ␉␉{␊ |
331 | ␉␉␉if ((map->biosPtr[i] == 'I') ␊ |
332 | ␉␉␉␉&& (map->biosPtr[i+1] == 'n') ␊ |
333 | ␉␉␉␉&& (map->biosPtr[i+2] == 't') ␊ |
334 | ␉␉␉␉&& (map->biosPtr[i+3] == 'e') ␊ |
335 | ␉␉␉␉&& (map->biosPtr[i+4] == 'l')) ␊ |
336 | ␉␉␉{␊ |
337 | ␉␉␉␉map->bios = BT_1;␊ |
338 | ␉␉␉␉PRINT("We have an Intel Card\n");␊ |
339 | ␉␉␉␉saveVbios(map);␊ |
340 | ␉␉␉␉return openIntelVbios(map);␊ |
341 | ␉␉␉␉break;␊ |
342 | ␉␉␉}␊ |
343 | ␉␉␉i++;␊ |
344 | ␉␉}␊ |
345 | ␉}␊ |
346 | ␉␊ |
347 | ␉/*␊ |
348 | ␉ * Unidentified Chipset␊ |
349 | ␉ */␊ |
350 | ␉␊ |
351 | ␉if ( (map->chipset == CT_UNKWN) || ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA) && (map->bios != BT_1)) )␊ |
352 | ␉{␊ |
353 | ␉␉PRINT("Unknown chipset type and unrecognized bios.\n");␊ |
354 | ␉␉␊ |
355 | ␉␉PRINT("autoresolution only works with Intel 800/900 series graphic chipsets.\n");␊ |
356 | ␉␉␊ |
357 | ␉␉PRINT("Chipset Id: %x\n", map->chipsetId);␊ |
358 | ␉␉closeVbios(map);␊ |
359 | ␉␉return 0;␊ |
360 | ␉}␊ |
361 | ␊ |
362 | ␉/*␊ |
363 | ␉ * Should never get there ␊ |
364 | ␉ */␊ |
365 | ␉return 0;␊ |
366 | }␊ |
367 | ␊ |
368 | void closeVbios(vBiosMap * map)␊ |
369 | {␊ |
370 | ␉PRINT("Closing VBios\n");␊ |
371 | ␉//make sure to turn autoResolution off␊ |
372 | ␉if (gAutoResolution == true)␊ |
373 | ␉␉gAutoResolution = false;␊ |
374 | ␉␊ |
375 | ␉// if we saved the vBios, free the copy␊ |
376 | ␉if (map->biosBackupPtr != NULL)␊ |
377 | ␉{␊ |
378 | ␉␉PRINT("Freeing biosBackupPtr\t");␊ |
379 | ␉␉FREE(map->biosBackupPtr);␊ |
380 | ␉␉PRINT("[OK]\n");␊ |
381 | ␉}␊ |
382 | ␉␊ |
383 | ␉// free table backups if any␊ |
384 | ␉sModeTable * table = map->modeTables;␊ |
385 | ␉while (table != NULL)␊ |
386 | ␉{␉␉␊ |
387 | ␉␉if (table->backup != NULL)␊ |
388 | ␉␉{␊ |
389 | ␉␉␉PRINT("Table #%d: Freeing backup\t", table->id);␊ |
390 | ␉␉␉FREE(table->backup);␊ |
391 | ␉␉␉PRINT("[OK]\n");␊ |
392 | ␉␉}␊ |
393 | ␉␉␊ |
394 | ␉␉if (table != NULL)␊ |
395 | ␉␉{ ␊ |
396 | ␉␉␉PRINT("Table #%d: Freeing\t\t", table->id);␊ |
397 | ␉␉␉FREE(table);␊ |
398 | ␉␉␉PRINT("[OK]\n");␊ |
399 | ␉␉}␊ |
400 | ␉␉␊ |
401 | ␉␉if (table->next == NULL)␊ |
402 | ␉␉␉break;␊ |
403 | ␉␉␊ |
404 | ␉␉table = table->next;␊ |
405 | ␉}␊ |
406 | ␉␊ |
407 | ␉PRINT("Freeing map\t\t\t");␊ |
408 | ␉FREE(map);␊ |
409 | ␉PRINT("[OK]\n");␊ |
410 | }␊ |
411 | ␊ |
412 | void unlockVbios(vBiosMap * map)␊ |
413 | {␊ |
414 | ␊ |
415 | ␉map->unlocked = true;␊ |
416 | ␉ ␊ |
417 | ␉switch (map->chipset)␊ |
418 | ␉{␊ |
419 | ␉␉case CT_UNKWN:␊ |
420 | ␉␉␉break;␊ |
421 | ␉␉case CT_830:␊ |
422 | ␉␉case CT_855GM:␊ |
423 | ␉␉␉outl(0xcf8, 0x8000005a);␊ |
424 | ␉␉␉map->b1 = inb(0xcfe);␊ |
425 | ␉␉␉␉␊ |
426 | ␉␉␉outl(0xcf8, 0x8000005a);␊ |
427 | ␉␉␉outb(0xcfe, 0x33);␊ |
428 | ␉␉␉break;␊ |
429 | ␉␉case CT_845G:␊ |
430 | ␉␉case CT_865G:␊ |
431 | ␉␉case CT_915G:␊ |
432 | ␉␉case CT_915GM:␊ |
433 | ␉␉case CT_945G:␊ |
434 | ␉␉case CT_945GM:␊ |
435 | ␉␉case CT_945GME:␊ |
436 | ␉␉case CT_946GZ:␊ |
437 | ␉␉case CT_950GM:␊ |
438 | ␉␉case CT_955X:␊ |
439 | ␉␉case CT_G965:␊ |
440 | ␉␉case CT_Q965:␊ |
441 | ␉␉case CT_965GM:␊ |
442 | ␉␉case CT_975X:␊ |
443 | ␉␉case CT_P35:␊ |
444 | ␉␉case CT_X48:␊ |
445 | ␉␉case CT_B43:␊ |
446 | ␉␉case CT_Q45:␊ |
447 | ␉␉case CT_P45:␊ |
448 | ␉␉case CT_GM45:␊ |
449 | ␉␉case CT_G41:␊ |
450 | ␉␉case CT_G31:␊ |
451 | ␉␉case CT_G45:␊ |
452 | ␉␉case CT_500:␊ |
453 | ␉␉case CT_3150:␊ |
454 | ␊ |
455 | ␉␉␉outl(0xcf8, 0x80000090);␊ |
456 | ␉␉␉map->b1 = inb(0xcfd);␊ |
457 | ␉␉␉map->b2 = inb(0xcfe);␊ |
458 | ␉␉␉outl(0xcf8, 0x80000090);␊ |
459 | ␉␉␉outb(0xcfd, 0x33);␊ |
460 | ␉␉␉outb(0xcfe, 0x33);␊ |
461 | ␉␉break;␊ |
462 | ␉}␊ |
463 | ␉␊ |
464 | ␉#if DEBUG␊ |
465 | ␉{␊ |
466 | ␉␉uint32_t t = inl(0xcfc);␊ |
467 | ␉␉PRINT("unlock PAM: (0x%08x)\n", t);␊ |
468 | ␉}␊ |
469 | #endif␊ |
470 | }␊ |
471 | ␊ |
472 | void relockVbios(vBiosMap * map)␊ |
473 | {␊ |
474 | ␊ |
475 | ␉map->unlocked = false;␊ |
476 | ␉␊ |
477 | ␉switch (map->chipset)␊ |
478 | ␉{␊ |
479 | ␉␉case CT_UNKWN:␊ |
480 | ␉␉␉break;␊ |
481 | ␉␉case CT_830:␊ |
482 | ␉␉case CT_855GM:␊ |
483 | ␉␉␉outl(0xcf8, 0x8000005a);␊ |
484 | ␉␉␉outb(0xcfe, map->b1);␊ |
485 | ␉␉␉break;␊ |
486 | ␉␉case CT_845G:␊ |
487 | ␉␉case CT_865G:␊ |
488 | ␉␉case CT_915G:␊ |
489 | ␉␉case CT_915GM:␊ |
490 | ␉␉case CT_945G:␊ |
491 | ␉␉case CT_945GM:␊ |
492 | ␉␉case CT_945GME:␊ |
493 | ␉␉case CT_946GZ:␊ |
494 | ␉␉case CT_950GM:␊ |
495 | ␉␉case CT_955X:␊ |
496 | ␉␉case CT_G965:␊ |
497 | ␉␉case CT_Q965:␊ |
498 | ␉␉case CT_965GM:␊ |
499 | ␉␉case CT_975X:␊ |
500 | ␉␉case CT_P35:␊ |
501 | ␉␉case CT_X48:␊ |
502 | ␉␉case CT_B43:␊ |
503 | ␉␉case CT_Q45:␊ |
504 | ␉␉case CT_P45:␊ |
505 | ␉␉case CT_GM45:␊ |
506 | ␉␉case CT_G41:␊ |
507 | ␉␉case CT_G31:␊ |
508 | ␉␉case CT_G45:␊ |
509 | ␉␉case CT_500:␊ |
510 | ␉␉case CT_3150:␊ |
511 | ␉␉␉outl(0xcf8, 0x80000090);␊ |
512 | ␉␉␉outb(0xcfd, map->b1);␊ |
513 | ␉␉␉outb(0xcfe, map->b2);␊ |
514 | ␉␉␉break;␊ |
515 | ␉}␊ |
516 | ␉␊ |
517 | ␉#if DEBUG␊ |
518 | ␉{␊ |
519 | uint32_t t = inl(0xcfc);␊ |
520 | ␉␉PRINT("relock PAM: (0x%08x)\n", t);␊ |
521 | ␉}␊ |
522 | ␉#endif␊ |
523 | }␊ |
524 | ␊ |
525 | /*␊ |
526 | * saveVbios - save the entire vBios in case the patch has to be removed␊ |
527 | */␊ |
528 | void saveVbios(vBiosMap * map)␊ |
529 | {␊ |
530 | ␉map->biosBackupPtr = malloc(VBIOS_SIZE);␊ |
531 | ␉bcopy((const uint8_t *)0xC0000, map->biosBackupPtr, VBIOS_SIZE);␊ |
532 | }␊ |
533 | ␊ |
534 | /*␊ |
535 | * restoreVbios - restore the vBios backup or table backups if any␊ |
536 | */␊ |
537 | void restoreVbios(vBiosMap * map)␊ |
538 | {␊ |
539 | ␉if ((map->bios == BT_ATI_1) || (map->bios == BT_ATI_2) || (map->bios == BT_NVDA))␊ |
540 | ␉{␊ |
541 | ␉␉restoreTables(map, map->modeTables);␊ |
542 | ␉}␊ |
543 | ␉else␊ |
544 | ␉{␊ |
545 | ␉␉unlockVbios(map);␊ |
546 | ␉␉bcopy(map->biosBackupPtr,(uint8_t *)0xC0000, VBIOS_SIZE);␊ |
547 | ␉␉relockVbios(map);␊ |
548 | ␉}␊ |
549 | }␊ |
550 | ␊ |
551 | /*␊ |
552 | * saveTables - save the tables in case the patch has to be removed␊ |
553 | */␊ |
554 | void saveTables(sModeTable * table)␊ |
555 | {␊ |
556 | ␉while (table != NULL)␊ |
557 | ␉{␊ |
558 | ␉␉table->backup = (uint8_t *)malloc(table->size);␊ |
559 | ␉␉bcopy((const uint8_t *)table->pointer, table->backup, table->size);␊ |
560 | ␉␉table = table->next;␊ |
561 | ␉}␊ |
562 | }␊ |
563 | ␊ |
564 | /*␊ |
565 | * restoreTables - restore tables backup ␊ |
566 | */␊ |
567 | void restoreTables(vBiosMap * map, sModeTable * table)␊ |
568 | {␊ |
569 | ␉unlockVbios(map);␊ |
570 | ␉while (table != NULL)␊ |
571 | ␉{␊ |
572 | ␉␉bcopy(table->backup, (uint8_t *)table->pointer, table->size);␊ |
573 | ␉␉table = table->next;␊ |
574 | ␉}␊ |
575 | ␉relockVbios(map);␊ |
576 | }␊ |
577 | ␊ |
578 | /*␊ |
579 | * patchVbios - call the vendor specific function to patch the VESA tables␊ |
580 | * x & y are horizontal and vertical dimensions respectively, in pixels␊ |
581 | * for GMA and ATI, only first mode in Table is patched␊ |
582 | *␊ |
583 | * each vendor specific function have the same form :␊ |
584 | * bool vendorSetMode_type(sModeTable * table, uint8_t index, uint32_t * x, uint32_t * y);␊ |
585 | * where 'table' is the VESA table to patch, 'index' is the index of the mode in table,␊ |
586 | * 'x' & 'y' are pointer to the target resolution and return the next resolution in table.␊ |
587 | */␊ |
588 | void patchVbios(vBiosMap * map, uint32_t x, uint32_t y, uint32_t bp, uint32_t hTotal, uint32_t vTotal)␊ |
589 | {␊ |
590 | ␉uint32_t i = 0;␊ |
591 | ␉␊ |
592 | ␉sModeTable * table = map->modeTables;␊ |
593 | ␉␊ |
594 | ␉// save the target resolution for future use␊ |
595 | ␉map->currentX = x;␊ |
596 | ␉map->currentY = y;␊ |
597 | ␉␊ |
598 | ␉unlockVbios(map);␊ |
599 | ␉␊ |
600 | ␉// Get the aspect ratio for the requested mode␊ |
601 | ␉getAspectRatio(&map->aspectRatio, x, y);␊ |
602 | ␉␊ |
603 | ␉i = 0;␊ |
604 | ␉␊ |
605 | ␉// Call the vendor specific function for each available VESA Table␊ |
606 | ␉table = map->modeTables;␊ |
607 | ␉while (table != NULL)␊ |
608 | ␉{␊ |
609 | ␉␉//reset resolution value before treating a new table␊ |
610 | ␉␉x = map->currentX;␊ |
611 | ␉␉y = map->currentY;␊ |
612 | ␉␉␊ |
613 | ␉␉PRINT("Patching Table #%d: \n", table->id);␊ |
614 | ␉␉␊ |
615 | ␉␉map->setMode(table, i, &x, &y);␊ |
616 | #ifdef AUTORES_DEBUG␊ |
617 | ␉␉pause();␊ |
618 | #endif␊ |
619 | ␊ |
620 | ␉␉table = table->next;␊ |
621 | ␉}␊ |
622 | ␉␊ |
623 | ␉relockVbios(map);␊ |
624 | ␉return;␊ |
625 | }␊ |
626 | |