Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch_Modules/i386/modules/Resolution/915resolution.c

1/*
2 * resolution.h
3 *
4 *NOTE: I don't beleive this code is production ready / should be in trunk
5 * Atleast, not in it's current state.
6 *
7 * Created by Evan Lojewski on 3/4/10.
8 * Copyright 2009. All rights reserved.
9 *
10 */
11#ifndef _RESOLUTION_H_
12#define _RESOLUTION_H_
13
14//#include "libsaio.h"
15//#include "edid.h" //included
16#include "915resolution.h"
17
18
19void patchVideoBios()
20{
21UInt32 x = 0, y = 0, bp = 0;
22
23getResolution(&x, &y, &bp);
24verbose("getResolution: %dx%dx%d\n", (int)x, (int)y, (int)bp);
25
26if (x != 0 && y != 0 && bp != 0)
27{
28vbios_map * map;
29
30map = open_vbios(CT_UNKNOWN);
31//if(map)
32{
33unlock_vbios(map);
34 char* bytes = (char *)VBIOS_START;
35 int patchlocation = 0x0254;
36 verbose("Addr: %X Before patch: %x - ", patchlocation, bytes[patchlocation] );
37 bytes[patchlocation] = 0x8A;
38 verbose("after patch: %x \n", bytes[patchlocation++] );
39 bytes[patchlocation++] = 0x25;
40 bytes[patchlocation++] = 0xA0;
41 bytes[patchlocation++] = 0x20;
42 bytes[patchlocation++] = 0x51;
43 bytes[patchlocation++] = 0x84;
44 bytes[patchlocation++] = 0x1A;
45 bytes[patchlocation++] = 0x30;
46 bytes[patchlocation++] = 0x30;
47 bytes[patchlocation++] = 0x40;
48 bytes[patchlocation++] = 0x36;
49 bytes[patchlocation++] = 0x00;
50 bytes[patchlocation++] = 0x30;
51 bytes[patchlocation++] = 0xBE;
52 bytes[patchlocation++] = 0x10;
53 bytes[patchlocation++] = 0x00;
54 bytes[patchlocation++] = 0x00;
55 bytes[patchlocation++] = 0x1E;
56
57 int i=0;
58/* verbose("unlocked, patching starting at: %X \n", bytes );
59 for (i=0; i< 0xfffe; i++){
60 char origbytes [] = {0x00, 0x05};
61 if ( bytes[i] == origbytes[0] && bytes[i+1] == origbytes[1])
62 {
63 verbose("Addr: %X Before patch: %x %x - ", bytes + i, bytes[i], bytes[i+1]);
64
65 bytes[i] = 0xA0;
66 bytes[i+1] = 0x05;
67 verbose("after patch: %x %x \n", bytes[i], bytes[i+1]);
68
69 }
70 }
71 for (i=0; i< 0xfffe; i++){
72 char origbytes [] = {0x20, 0x03};
73 if ( bytes[i] == origbytes[0] && bytes[i+1] == origbytes[1])
74 {
75 verbose("Addr: %X Before patch: %x %x - ", bytes + i, bytes[i], bytes[i+1]);
76
77 bytes[i] = 0x84;
78 bytes[i+1] = 0x03;
79 verbose("after patch: %x %x \n", bytes[i], bytes[i+1]);
80
81 }
82 }
83
84*/
85//set_mode(map, x, y, bp, 0, 0);
86 verbose("\nFinished Patching at %X locking bios.\n", bytes + i );
87
88relock_vbios(map);
89
90close_vbios(map);
91}
92}
93}
94
95
96/* Copied from 915 resolution created by steve tomljenovic
97 *
98 * This code is based on the techniques used in :
99 *
100 * - 855patch. Many thanks to Christian Zietz (czietz gmx net)
101 * for demonstrating how to shadow the VBIOS into system RAM
102 * and then modify it.
103 *
104 * - 1280patch by Andrew Tipton (andrewtipton null li).
105 *
106 * - 855resolution by Alain Poirier
107 *
108 * This source code is into the public domain.
109 */
110
111/**
112 **
113 **/
114
115#define CONFIG_MECH_ONE_ADDR0xCF8
116#define CONFIG_MECH_ONE_DATA0xCFC
117
118int freqs[] = { 60, 75, 85 };
119
120UInt8memDevBus = 0;
121
122UInt32 get_chipset_id(void)
123{
124outl(CONFIG_MECH_ONE_ADDR, 0x80000000);
125return inl(CONFIG_MECH_ONE_DATA);
126}
127
128chipset_type get_chipset(UInt32 id)
129{
130chipset_type type;
131
132switch (id) {
133case 0x35758086:
134type = CT_830;
135break;
136
137case 0x25608086:
138type = CT_845G;
139break;
140
141case 0x35808086:
142type = CT_855GM;
143break;
144
145case 0x25708086:
146type = CT_865G;
147break;
148
149case 0x25808086:
150type = CT_915G;
151break;
152
153case 0x25908086:
154type = CT_915GM;
155break;
156
157case 0x27708086:
158type = CT_945G;
159break;
160
161case 0x27a08086:
162type = CT_945GM;
163break;
164
165case 0x27ac8086:
166type = CT_945GME;
167break;
168
169case 0x29708086:
170type = CT_946GZ;
171break;
172
173case 0x27748086:
174type = CT_955X;
175break;
176
177case 0x277c8086:
178type = CT_975X;
179break;
180
181case 0x29a08086:
182type = CT_G965;
183break;
184
185case 0x29908086:
186type = CT_Q965;
187break;
188
189case 0x81008086:
190type = CT_500;
191break;
192
193case 0x2e108086:
194case 0X2e908086:
195type = CT_B43;
196break;
197
198case 0x2e208086:
199type = CT_P45;
200break;
201
202case 0x2e308086:
203type = CT_G41;
204break;
205
206case 0x29c08086:
207type = CT_G31;
208break;
209
210case 0x29208086:
211type = CT_G45;
212break;
213
214case 0xA0108086:// mobile
215case 0xA0008086:// desktop
216type = CT_3150;
217break;
218
219case 0x2a008086:
220type = CT_965GM;
221break;
222
223case 0x29e08086:
224type = CT_X48;
225break;
226
227case 0x2a408086:
228type = CT_GM45;
229break;
230
231//
232// Core processors
233// http://pci-ids.ucw.cz/read/PC/8086
234//
235/*case 0x00408086: // Core Processor DRAM Controller
236case 0x00448086: // Core Processor DRAM Controller
237case 0x00488086: // Core Processor DRAM Controller
238case 0x00698086: // Core Processor DRAM Controller
239verbose(" core proc 1st gen identified\n");
240type = CT_CORE_PROC_1;
241break;
242*/
243case 0x01008086: // 2nd Generation Core Processor Family DRAM Controller
244case 0x01048086: // 2nd Generation Core Processor Family DRAM Controller
245case 0x01088086: // Xeon E3-1200 2nd Generation Core Processor Family DRAM Controller
246case 0x010c8086: // Xeon E3-1200 2nd Generation Core Processor Family DRAM Controller
247
248case 0x01508086: // 3rd Generation Core Processor Family DRAM Controller
249case 0x01548086: // 3rd Generation Core Processor Family DRAM Controller
250case 0x01588086: // 3rd Generation Core Processor Family DRAM Controller
251case 0x015c8086: // 3rd Generation Core Processor Family DRAM Controller
252verbose(" core proc identified\n");
253type = CT_CORE_PROC_2_3;
254break;
255
256default:
257if((id & 0x0000FFFF) == 0x00008086) // Intel chipset
258{
259//
260// http://www.intel.com/content/www/us/en/processors/core/CoreTechnicalResources.html
261// Core procs 1st gen: Bus (ff or 7f or 3f), Device 0, Func 1 contains
262// System address decoder (SAD) with devId:
263// 2c01 - Core i7-900 and Extreme Edition, Desktop
264// 2c81 - CoreTM i7-800 and i5-700 Desktop
265// 2c81 - CoreTM i7-900 Mobile Processor Extreme Edition Series, Intel Core i7-800 and i7-700 Mobile
266// 2d01 - Core-i5-600, i3-500 desktop, Pentium 6000, Desktop
267// 2d81 - Core i7-900 and Extreme Edition, Desktop, 32 nm
268// 2cc1 - Xeon Processor C5500/C3500 Series
269// SAD regs 40h-46h are PAM regs
270//
271UInt8 buses[] = {0xff, 0x7f, 0x3f};
272UInt8 bus;
273UInt32 i;
274UInt16 devId;
275
276for (i = 0; i < sizeof(buses)/sizeof(buses[0]); i++)
277{
278// 1 << 31 | bus << 16 | device << 11 | function << 8 | offset
279//verbose(" reading %x", (1 << 31 | buses[i] << 16 | 0 << 11 | 1 << 8 | 0));
280outl(CONFIG_MECH_ONE_ADDR, (1 << 31 | buses[i] << 16 | 0 << 11 | 1 << 8 | 0));
281devId = inw(CONFIG_MECH_ONE_DATA + 2);
282//verbose(" = %x\n", devId);
283if (devId == 0x2c01 || devId == 0x2c81 ||
284devId == 0x2d01 || devId == 0x2d81 || devId == 0x2cc1)
285{
286verbose(" core proc identified\n");
287memDevBus = buses[i];
288type = CT_CORE_PROC_1;
289break; // from for
290}
291}
292if (type != CT_UNKNOWN) {
293break; // from switch
294}
295
296//
297// Core i7 Processor Family for the LGA-2011
298// http://www.intel.com/content/www/us/en/processors/core/core-i7-lga-2011-datasheet-vol-2.html
299// Bus 0, Dev 5, Func 0, DevId=3c28 contains reg CPUBUSNO at 108h, bits 15:8 = Uncore bus
300// Bus "Uncore bus", Dev 12, Func 6, DevId=3CF4 is System Address Decoder and PAM regs are at 40h-46h
301//
302outl(CONFIG_MECH_ONE_ADDR, (1 << 31 | 0 << 16 | 5 << 11 | 0 << 8 | 0));
303devId = inw(CONFIG_MECH_ONE_DATA + 2);
304if (devId == 0x3c28)
305{
306outl(CONFIG_MECH_ONE_ADDR, (1 << 31 | 0 << 16 | 5 << 11 | 0 << 8 | 0x108));
307bus = inb(CONFIG_MECH_ONE_DATA + 1); // "Uncore bus"
308
309outl(CONFIG_MECH_ONE_ADDR, (1 << 31 | bus << 16 | 12 << 11 | 6 << 8 | 0));
310devId = inw(CONFIG_MECH_ONE_DATA + 2);
311if (devId == 0x3cf4) {
312verbose(" core proc for the LGA-2011 identified\n");
313memDevBus = bus;
314type = CT_CORE_PROC_2011;
315break; // from switch
316}
317}
318
319verbose(" unknown Intel chipset/proc\n");
320//printf("Unknown chipset 0x%llX, please email id to meklort@gmail.com", id);
321//getc();
322//type = CT_UNKNOWN_INTEL;
323type = CT_UNKNOWN;
324
325}
326else
327{
328type = CT_UNKNOWN;
329}
330break;
331}
332
333return type;
334}
335
336vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res)
337{
338vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
339return ptr;
340}
341
342vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res)
343{
344vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
345return ptr;
346}
347
348vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res)
349{
350vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
351return ptr;
352}
353
354char detect_bios_type(vbios_map * map, char modeline, int entry_size);
355char detect_bios_type(vbios_map * map, char modeline, int entry_size)
356{
357UInt32 i;
358UInt16 r1, r2;
359
360r1 = r2 = 32000;
361
362for (i=0; i < map->mode_table_size; i++)
363{
364//msglog(" 0x%X", map->mode_table[i].resolution );
365
366if (map->mode_table[i].resolution <= r1)
367{
368r1 = map->mode_table[i].resolution;
369}
370else
371{
372if (map->mode_table[i].resolution <= r2)
373{
374r2 = map->mode_table[i].resolution;
375}
376}
377
378//printf("r1 = %d r2 = %d\n", r1, r2);
379}
380
381return (r2-r1-6) % entry_size == 0;
382}
383
384void close_vbios(vbios_map * map);
385
386char detect_ati_bios_type(vbios_map * map)
387{
388return map->mode_table_size % sizeof(ATOM_MODE_TIMING) == 0;
389}
390
391
392vbios_map * open_vbios(chipset_type forced_chipset)
393{
394UInt32 z;
395vbios_map * map = malloc(sizeof(vbios_map));
396if (!map)
397{
398return 0;
399}
400for(z=0; z<sizeof(vbios_map); z++) ((char*)map)[z]=0;
401/*
402 * Determine chipset
403 */
404
405if (forced_chipset == CT_UNKNOWN)
406{
407map->chipset_id = get_chipset_id();
408map->chipset = get_chipset(map->chipset_id);
409}
410else if (forced_chipset != CT_UNKNOWN)
411{
412map->chipset = forced_chipset;
413}
414
415
416if (map->chipset == CT_UNKNOWN)
417{
418verbose(" Unknown chipset type: %08x.\n", map->chipset_id);
419//verbose("915resolution only works with Intel 800/900 series graphic chipsets.\n");
420//verbose("Chipset Id: %x\n", map->chipset_id);
421close_vbios(map);
422return 0;
423}
424else
425{
426verbose(" Detected chipset/proc id (DRAM controller): %08x\n", map->chipset_id);
427}
428
429
430verbose(" VBios: ");
431/*
432 * Map the video bios to memory
433 */
434map->bios_ptr=(char*)VBIOS_START;
435
436/*
437 * check if we have ATI Radeon
438 */
439map->ati_tables.base = map->bios_ptr;
440map->ati_tables.AtomRomHeader = (ATOM_ROM_HEADER *) (map->bios_ptr + *(unsigned short *) (map->bios_ptr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER));
441if (strcmp ((char *) map->ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM") == 0)
442{
443verbose("ATI");
444// ATI Radeon Card
445map->bios = BT_ATI_1;
446
447map->ati_tables.MasterDataTables = (unsigned short *) &((ATOM_MASTER_DATA_TABLE *) (map->bios_ptr + map->ati_tables.AtomRomHeader->usMasterDataTableOffset))->ListOfDataTables;
448unsigned short std_vesa_offset = (unsigned short) ((ATOM_MASTER_LIST_OF_DATA_TABLES *)map->ati_tables.MasterDataTables)->StandardVESA_Timing;
449ATOM_STANDARD_VESA_TIMING * std_vesa = (ATOM_STANDARD_VESA_TIMING *) (map->bios_ptr + std_vesa_offset);
450
451map->ati_mode_table = (char *) &std_vesa->aModeTimings;
452if (map->ati_mode_table == 0)
453{
454printf("Unable to locate the mode table.\n");
455printf("Please run the program 'dump_bios' as root and\n");
456printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
457printf("Chipset: %d\n", map->chipset);
458close_vbios(map);
459return 0;
460}
461map->mode_table_size = std_vesa->sHeader.usStructureSize - sizeof(ATOM_COMMON_TABLE_HEADER);
462
463if (!detect_ati_bios_type(map))
464{
465map->bios = BT_ATI_2;
466}
467
468if (map->bios == BT_ATI_1)
469{
470verbose(", BT_ATI_1\n");
471}
472else
473{
474verbose(", BT_ATI_2\n");
475}
476}
477else
478{
479
480/*
481 * check if we have NVIDIA
482 */
483
484int i = 0;
485while (i < 512)
486{ // we don't need to look through the whole bios, just the first 512 bytes
487if ((map->bios_ptr[i] == 'N')
488&& (map->bios_ptr[i+1] == 'V')
489&& (map->bios_ptr[i+2] == 'I')
490&& (map->bios_ptr[i+3] == 'D'))
491{
492verbose("nVidia\n");
493map->bios = BT_NVDA;
494unsigned short nv_data_table_offset = 0;
495unsigned short * nv_data_table;
496NV_VESA_TABLE * std_vesa;
497
498int i = 0;
499
500while (i < 0x300)
501{ //We don't need to look for the table in the whole bios, the 768 first bytes only
502if ((map->bios_ptr[i] == 0x44)
503&& (map->bios_ptr[i+1] == 0x01)
504&& (map->bios_ptr[i+2] == 0x04)
505&& (map->bios_ptr[i+3] == 0x00))
506{
507nv_data_table_offset = (unsigned short) (map->bios_ptr[i+4] | (map->bios_ptr[i+5] << 8));
508break;
509}
510i++;
511}
512
513nv_data_table = (unsigned short *) (map->bios_ptr + (nv_data_table_offset + OFFSET_TO_VESA_TABLE_INDEX));
514std_vesa = (NV_VESA_TABLE *) (map->bios_ptr + *nv_data_table);
515
516map->nv_mode_table = (char *) std_vesa->sModelines;
517if (map->nv_mode_table == 0)
518{
519printf("Unable to locate the mode table.\n");
520printf("Please run the program 'dump_bios' as root and\n");
521printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
522printf("Chipset: %s\n", map->chipset);
523close_vbios(map);
524return 0;
525}
526map->mode_table_size = std_vesa->sHeader.usTable_Size;
527
528break;
529}
530i++;
531}
532}
533
534
535/*
536 * check if we have Intel
537 */
538
539/*if (map->chipset == CT_UNKNOWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {
540 printf( "Intel chipset detected. However, 915resolution was unable to determine the chipset type.\n");
541
542 printf("Chipset Id: %x\n", map->chipset_id);
543
544 printf("Please report this problem to stomljen@yahoo.com\n");
545
546 close_vbios(map);
547 return 0;
548 }*/
549
550/*
551 * check for others
552 */
553
554/*
555 * Figure out where the mode table is
556 */
557if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA))
558{
559char* p = map->bios_ptr + 16;
560char* limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
561
562verbose("Other");
563msglog("Started mode table scan at: 0x%X\n", p );
564while (p < limit && map->mode_table == 0)
565{
566vbios_mode * mode_ptr = (vbios_mode *) p;
567
568if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
569((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30))
570{
571map->mode_table = mode_ptr;
572}
573
574p++;
575}
576msglog("Ended mode table scan at: 0x%X\n", p );
577if (map->mode_table == 0)
578{
579close_vbios(map);
580return 0;
581}
582}
583
584
585/*
586 * Determine size of mode table
587 */
588if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA))
589{
590vbios_mode * mode_ptr = map->mode_table;
591
592while (mode_ptr->mode != 0xff)
593{
594map->mode_table_size++;
595mode_ptr++;
596}
597msglog("Table size: 0x%X\n", map->mode_table_size );
598}
599
600/*
601 * Figure out what type of bios we have
602 * order of detection is important
603 */
604if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA))
605{
606if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3)))
607{
608map->bios = BT_3;
609verbose(", BT_3\n");
610}
611else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2)))
612{
613map->bios = BT_2;
614verbose(", BT_2\n");
615}
616else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1)))
617{
618map->bios = BT_1;
619verbose(", BT_1\n");
620}
621else {
622verbose(" - unknown\n");
623//return 0;
624}
625}
626
627return map;
628}
629
630void close_vbios(vbios_map * map)
631{
632free(map);
633}
634
635void unlock_vbios(vbios_map * map)
636{
637map->unlocked = TRUE;
638
639switch (map->chipset) {
640case CT_UNKNOWN:
641break;
642case CT_830:
643case CT_855GM:
644outl(CONFIG_MECH_ONE_ADDR, 0x8000005a);
645map->b1 = inb(CONFIG_MECH_ONE_DATA + 2);
646
647outl(CONFIG_MECH_ONE_ADDR, 0x8000005a);
648outb(CONFIG_MECH_ONE_DATA + 2, 0x33);
649break;
650case CT_845G:
651case CT_865G:
652case CT_915G:
653case CT_915GM:
654case CT_945G:
655case CT_945GM:
656case CT_945GME:
657case CT_946GZ:
658case CT_G965:
659case CT_Q965:
660case CT_965GM:
661case CT_975X:
662case CT_P35:
663case CT_955X:
664case CT_X48:
665case CT_B43:
666case CT_Q45:
667case CT_P45:
668case CT_GM45:
669case CT_G45:
670case CT_G41:
671case CT_G31:
672case CT_500:
673case CT_3150:
674outl(CONFIG_MECH_ONE_ADDR, 0x80000090);
675map->b1 = inb(CONFIG_MECH_ONE_DATA + 1);
676map->b2 = inb(CONFIG_MECH_ONE_DATA + 2);
677outl(CONFIG_MECH_ONE_ADDR, 0x80000090);
678outb(CONFIG_MECH_ONE_DATA + 1, 0x33);
679outb(CONFIG_MECH_ONE_DATA + 2, 0x33);
680break;
681case CT_CORE_PROC_1: // Core procs - PAM regs are Bus=memDevBus, Dev=0, Func=1, 40h - 46h
682outl(CONFIG_MECH_ONE_ADDR, (1 << 31 | memDevBus << 16 | 0 << 11 | 1 << 8 | 0x40));
683map->b1 = inb(CONFIG_MECH_ONE_DATA + 1);
684map->b2 = inb(CONFIG_MECH_ONE_DATA + 2);
685outl(CONFIG_MECH_ONE_ADDR, (1 << 31 | memDevBus << 16 | 0 << 11 | 1 << 8 | 0x40));
686outb(CONFIG_MECH_ONE_DATA + 1, 0x33);
687outb(CONFIG_MECH_ONE_DATA + 2, 0x33);
688break;
689case CT_CORE_PROC_2011: // Core procs LGA-2011 - PAM regs are Bus=memDevBus, Dev=12, Func=6, 40h - 46h
690outl(CONFIG_MECH_ONE_ADDR, (1 << 31 | memDevBus << 16 | 12 << 11 | 6 << 8 | 0x40));
691map->b1 = inb(CONFIG_MECH_ONE_DATA + 1);
692map->b2 = inb(CONFIG_MECH_ONE_DATA + 2);
693outl(CONFIG_MECH_ONE_ADDR, (1 << 31 | memDevBus << 16 | 12 << 11 | 6 << 8 | 0x40));
694outb(CONFIG_MECH_ONE_DATA + 1, 0x33);
695outb(CONFIG_MECH_ONE_DATA + 2, 0x33);
696break;
697case CT_CORE_PROC_2_3: // Core procs - PAM regs are 80h - 86h
698//case CT_UNKNOWN_INTEL:// Assume newer intel chipset is the same as before
699outl(CONFIG_MECH_ONE_ADDR, 0x80000080);
700map->b1 = inb(CONFIG_MECH_ONE_DATA + 1);
701map->b2 = inb(CONFIG_MECH_ONE_DATA + 2);
702outl(CONFIG_MECH_ONE_ADDR, 0x80000080);
703outb(CONFIG_MECH_ONE_DATA + 1, 0x33);
704outb(CONFIG_MECH_ONE_DATA + 2, 0x33);
705break;
706default:
707break;
708}
709
710// test if vbios is unlocked
711UInt8 *ptr8 = (UInt8*)(VBIOS_START + 0xa123);
712UInt8 val8 = *ptr8;
713*ptr8 = *ptr8 + 1;
714if (val8 != *ptr8) {
715*ptr8 = val8;
716map->unlocked = TRUE;
717verbose(" vbios unlocked\n");
718}
719#if DEBUG
720{
721UInt32 t = inl(CONFIG_MECH_ONE_DATA);
722verbose("unlock PAM: (0x%08x)\n", t);
723}
724#endif
725}
726
727void relock_vbios(vbios_map * map)
728{
729
730map->unlocked = FALSE;
731
732switch (map->chipset)
733{
734case CT_UNKNOWN:
735break;
736case CT_830:
737case CT_855GM:
738outl(CONFIG_MECH_ONE_ADDR, 0x8000005a);
739outb(CONFIG_MECH_ONE_DATA + 2, map->b1);
740break;
741case CT_845G:
742case CT_865G:
743case CT_915G:
744case CT_915GM:
745case CT_945G:
746case CT_945GM:
747case CT_945GME:
748case CT_946GZ:
749case CT_G965:
750case CT_955X:
751case CT_G45:
752case CT_Q965:
753case CT_965GM:
754case CT_975X:
755case CT_P35:
756case CT_X48:
757case CT_B43:
758case CT_Q45:
759case CT_P45:
760case CT_GM45:
761case CT_G41:
762case CT_G31:
763case CT_500:
764case CT_3150:
765outl(CONFIG_MECH_ONE_ADDR, 0x80000090);
766outb(CONFIG_MECH_ONE_DATA + 1, map->b1);
767outb(CONFIG_MECH_ONE_DATA + 2, map->b2);
768break;
769case CT_CORE_PROC_1:
770outl(CONFIG_MECH_ONE_ADDR, (1 << 31 | memDevBus << 16 | 0 << 11 | 1 << 8 | 0x40));
771outb(CONFIG_MECH_ONE_DATA + 1, map->b1);
772outb(CONFIG_MECH_ONE_DATA + 2, map->b2);
773break;
774case CT_CORE_PROC_2011:
775outl(CONFIG_MECH_ONE_ADDR, (1 << 31 | memDevBus << 16 | 12 << 11 | 6 << 8 | 0x40));
776outb(CONFIG_MECH_ONE_DATA + 1, map->b1);
777outb(CONFIG_MECH_ONE_DATA + 2, map->b2);
778break;
779case CT_CORE_PROC_2_3:
780//case CT_UNKNOWN_INTEL:
781outl(CONFIG_MECH_ONE_ADDR, 0x80000080);
782outb(CONFIG_MECH_ONE_DATA + 1, map->b1);
783outb(CONFIG_MECH_ONE_DATA + 2, map->b2);
784default:
785break;
786}
787
788#if DEBUG
789{
790 UInt32 t = inl(CONFIG_MECH_ONE_DATA);
791verbose("relock PAM: (0x%08x)\n", t);
792}
793#endif
794}
795
796
797int getMode(edid_mode *mode)
798{
799char* edidInfo = readEDID();
800
801if(!edidInfo) return 1;
802//Slice
803if(!fb_parse_edid((struct EDID *)edidInfo, mode))
804{
805//free( edidInfo );
806return 1;
807}
808/*mode->pixel_clock = (edidInfo[55] << 8) | edidInfo[54];
809mode->h_active = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);
810mode->h_blanking = ((edidInfo[58] & 0x0F) << 8) | edidInfo[57];
811mode->v_active = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);
812mode->v_blanking = ((edidInfo[61] & 0x0F) << 8) | edidInfo[60];
813mode->h_sync_offset = ((edidInfo[65] & 0xC0) >> 2) | edidInfo[62];
814mode->h_sync_width = (edidInfo[65] & 0x30) | edidInfo[63];
815mode->v_sync_offset = (edidInfo[65] & 0x0C) | ((edidInfo[64] & 0x0C) >> 2);
816mode->v_sync_width = ((edidInfo[65] & 0x3) << 2) | (edidInfo[64] & 0x03);
817*/
818if(!mode->h_active) return 1;
819//free( edidInfo );
820
821return 0;
822
823}
824
825
826static void gtf_timings(UInt32 x, UInt32 y, UInt32 freq,
827unsigned long *clock,
828UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
829UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank)
830{
831UInt32 hbl, vbl, vfreq;
832
833vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5;
834vfreq = vbl * freq;
835hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) /
836 + (70.0 + 300000.0 / vfreq) / 16.0 + 0.5);
837
838*vsyncstart = y;
839*vsyncend = y + 3;
840*vblank = vbl - 1;
841*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
842*hsyncend = x + hbl / 2 - 1;
843*hblank = x + hbl - 1;
844*clock = (x + hbl) * vfreq / 1000;
845}
846
847void set_mode(vbios_map * map, /*UInt32 mode,*/ UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) {
848UInt32 xprev, yprev;
849UInt32 i = 0, j;
850// patch first available mode
851
852//for (i=0; i < map->mode_table_size; i++) {
853//if (map->mode_table[0].mode == mode) {
854verbose(" Patching: ");
855switch(map->bios) {
856case BT_INTEL:
857verbose("BT_INTEL - not supported\n");
858return;
859
860case BT_1:
861{
862verbose("BT_1 patched.\n");
863vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
864
865if (bp)
866{
867map->mode_table[i].bits_per_pixel = (uint8_t)bp;
868}
869
870res->x2 = (htotal?(((htotal-x) >> 8) & 0x0f) : (res->x2 & 0x0f)) | ((x >> 4) & 0xf0);
871res->x1 = (x & 0xff);
872
873res->y2 = (vtotal?(((vtotal-y) >> 8) & 0x0f) : (res->y2 & 0x0f)) | ((y >> 4) & 0xf0);
874res->y1 = (y & 0xff);
875if (htotal)
876{
877res->x_total = ((htotal-x) & 0xff);
878}
879if (vtotal)
880{
881res->y_total = ((vtotal-y) & 0xff);
882}
883break;
884}
885case BT_2:
886{
887vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
888
889res->xchars = (uint8_t)(x / 8);
890res->ychars = (uint8_t)(y / 16 - 1);
891xprev = res->modelines[0].x1;
892yprev = res->modelines[0].y1;
893
894for(j=0; j < 3; j++) {
895vbios_modeline_type2 * modeline = &res->modelines[j];
896
897if (modeline->x1 == xprev && modeline->y1 == yprev) {
898modeline->x1 = modeline->x2 = (uint16_t)(x-1);
899modeline->y1 = modeline->y2 = (uint16_t)(y-1);
900
901gtf_timings(x, y, freqs[j], &modeline->clock,
902&modeline->hsyncstart, &modeline->hsyncend,
903&modeline->hblank, &modeline->vsyncstart,
904&modeline->vsyncend, &modeline->vblank);
905
906if (htotal)
907{
908modeline->htotal = (uint16_t)htotal;
909}
910else
911{
912modeline->htotal = modeline->hblank;
913}
914if (vtotal)
915{
916modeline->vtotal = (uint16_t)vtotal;
917}
918else
919{
920modeline->vtotal = modeline->vblank;
921}
922}
923}
924verbose("BT_1 patched.\n");
925break;
926}
927case BT_3:
928{
929vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
930
931xprev = res->modelines[0].x1;
932yprev = res->modelines[0].y1;
933
934for (j=0; j < 3; j++) {
935vbios_modeline_type3 * modeline = &res->modelines[j];
936
937if (modeline->x1 == xprev && modeline->y1 == yprev) {
938modeline->x1 = modeline->x2 = (uint16_t)(x-1);
939modeline->y1 = modeline->y2 = (uint16_t)(y-1);
940
941gtf_timings(x, y, freqs[j], &modeline->clock,
942&modeline->hsyncstart, &modeline->hsyncend,
943&modeline->hblank, &modeline->vsyncstart,
944&modeline->vsyncend, &modeline->vblank);
945if (htotal)
946{
947modeline->htotal = (uint16_t)htotal;
948}
949else
950{
951modeline->htotal = modeline->hblank;
952}
953if (vtotal)
954{
955modeline->vtotal = (uint16_t)vtotal;
956}
957else
958{
959modeline->vtotal = modeline->vblank;
960}
961modeline->timing_h = (uint16_t)(y-1);
962modeline->timing_v = (uint16_t)(x-1);
963}
964}
965verbose("BT_3 patched.\n");
966break;
967}
968case BT_ATI_1:
969{
970verbose("BT_ATI_1");
971edid_mode mode;
972
973ATOM_MODE_TIMING *mode_timing = (ATOM_MODE_TIMING *) map->ati_mode_table;
974
975//if (mode.pixel_clock && (mode.h_active == x) && (mode.v_active == y) && !force){
976if (!getMode(&mode))
977{
978verbose("\n Edid detailed timing descriptor found: %dx%d\n vbios mode 0 patched!\n", mode.h_active, mode.v_active);
979mode_timing->usCRTC_H_Total = mode.h_active + mode.h_blanking;
980mode_timing->usCRTC_H_Disp = mode.h_active;
981mode_timing->usCRTC_H_SyncStart = mode.h_active + mode.h_sync_offset;
982mode_timing->usCRTC_H_SyncWidth = mode.h_sync_width;
983
984mode_timing->usCRTC_V_Total = mode.v_active + mode.v_blanking;
985mode_timing->usCRTC_V_Disp = mode.v_active;
986mode_timing->usCRTC_V_SyncStart = mode.v_active + mode.v_sync_offset;
987mode_timing->usCRTC_V_SyncWidth = mode.v_sync_width;
988
989mode_timing->usPixelClock = mode.pixel_clock;
990}
991else
992{
993verbose(" Edid not found or invalid - vbios not patched!\n");
994}
995/*else
996{
997vbios_modeline_type2 modeline;
998
999cvt_timings(x, y, freqs[0], &modeline.clock,
1000&modeline.hsyncstart, &modeline.hsyncend,
1001&modeline.hblank, &modeline.vsyncstart,
1002&modeline.vsyncend, &modeline.vblank, 0);
1003
1004mode_timing->usCRTC_H_Total = x + modeline.hblank;
1005mode_timing->usCRTC_H_Disp = x;
1006mode_timing->usCRTC_H_SyncStart = modeline.hsyncstart;
1007mode_timing->usCRTC_H_SyncWidth = modeline.hsyncend - modeline.hsyncstart;
1008
1009mode_timing->usCRTC_V_Total = y + modeline.vblank;
1010mode_timing->usCRTC_V_Disp = y;
1011mode_timing->usCRTC_V_SyncStart = modeline.vsyncstart;
1012mode_timing->usCRTC_V_SyncWidth = modeline.vsyncend - modeline.vsyncstart;
1013
1014mode_timing->usPixelClock = modeline.clock;
1015 }*/
1016
1017break;
1018}
1019case BT_ATI_2:
1020{
1021verbose("BT_ATI_2");
1022edid_mode mode;
1023
1024ATOM_DTD_FORMAT *mode_timing = (ATOM_DTD_FORMAT *) map->ati_mode_table;
1025
1026/*if (mode.pixel_clock && (mode.h_active == x) && (mode.v_active == y) && !force) {*/
1027if (!getMode(&mode)) {
1028verbose("\n Edid detailed timing descriptor found: %dx%d\n vbios mode 0 patched!\n", mode.h_active, mode.v_active);
1029mode_timing->usHBlanking_Time = mode.h_blanking;
1030mode_timing->usHActive = mode.h_active;
1031mode_timing->usHSyncOffset = mode.h_sync_offset;
1032mode_timing->usHSyncWidth = mode.h_sync_width;
1033
1034mode_timing->usVBlanking_Time = mode.v_blanking;
1035mode_timing->usVActive = mode.v_active;
1036mode_timing->usVSyncOffset = mode.v_sync_offset;
1037mode_timing->usVSyncWidth = mode.v_sync_width;
1038
1039mode_timing->usPixClk = mode.pixel_clock;
1040}
1041else
1042{
1043verbose(" Edid not found or invalid - vbios not patched!\n");
1044}
1045/*else
1046{
1047vbios_modeline_type2 modeline;
1048
1049cvt_timings(x, y, freqs[0], &modeline.clock,
1050&modeline.hsyncstart, &modeline.hsyncend,
1051&modeline.hblank, &modeline.vsyncstart,
1052&modeline.vsyncend, &modeline.vblank, 0);
1053
1054mode_timing->usHBlanking_Time = modeline.hblank;
1055mode_timing->usHActive = x;
1056mode_timing->usHSyncOffset = modeline.hsyncstart - x;
1057mode_timing->usHSyncWidth = modeline.hsyncend - modeline.hsyncstart;
1058
1059mode_timing->usVBlanking_Time = modeline.vblank;
1060mode_timing->usVActive = y;
1061mode_timing->usVSyncOffset = modeline.vsyncstart - y;
1062mode_timing->usVSyncWidth = modeline.hsyncend - modeline.hsyncstart;
1063
1064mode_timing->usPixClk = modeline.clock;
1065}*/
1066
1067break;
1068}
1069case BT_NVDA:
1070{
1071verbose("BT_NVDA");
1072edid_mode mode;
1073NV_MODELINE *mode_timing = (NV_MODELINE *) map->nv_mode_table;
1074
1075/*if (mode.pixel_clock && (mode.h_active == x) && (mode.v_active == y) && !force) {*/
1076if (!getMode(&mode))
1077{
1078verbose("\n Edid detailed timing descriptor found: %dx%d\n vbios mode %d patched!\n", mode.h_active, mode.v_active, i);
1079mode_timing[i].usH_Total = mode.h_active + mode.h_blanking;
1080mode_timing[i].usH_Active = mode.h_active;
1081mode_timing[i].usH_SyncStart = mode.h_active + mode.h_sync_offset;
1082mode_timing[i].usH_SyncEnd = mode.h_active + mode.h_sync_offset + mode.h_sync_width;
1083
1084mode_timing[i].usV_Total = mode.v_active + mode.v_blanking;
1085mode_timing[i].usV_Active = mode.v_active;
1086mode_timing[i].usV_SyncStart = mode.v_active + mode.v_sync_offset;
1087mode_timing[i].usV_SyncEnd = mode.v_active + mode.v_sync_offset + mode.v_sync_width;
1088
1089mode_timing[i].usPixel_Clock = mode.pixel_clock;
1090}
1091 else
1092{
1093verbose(" Edid not found or invalid - vbios not patched!\n");
1094}
1095/*else
1096 {
1097 vbios_modeline_type2 modeline;
1098 cvt_timings(x, y, freqs[0], &modeline.clock,
1099 &modeline.hsyncstart, &modeline.hsyncend,
1100 &modeline.hblank, &modeline.vsyncstart,
1101 &modeline.vsyncend, &modeline.vblank, 0);
1102
1103 mode_timing[i].usH_Total = x + modeline.hblank - 1;
1104 mode_timing[i].usH_Active = x;
1105 mode_timing[i].usH_SyncStart = modeline.hsyncstart - 1;
1106 mode_timing[i].usH_SyncEnd = modeline.hsyncend - 1;
1107
1108 mode_timing[i].usV_Total = y + modeline.vblank - 1;
1109 mode_timing[i].usV_Active = y;
1110 mode_timing[i].usV_SyncStart = modeline.vsyncstart - 1;
1111 mode_timing[i].usV_SyncEnd = modeline.vsyncend - 1;
1112
1113 mode_timing[i].usPixel_Clock = modeline.clock;
1114 }*/
1115break;
1116}
1117case BT_UNKNOWN:
1118{
1119verbose(" Unknown - vbios not patched\n");
1120break;
1121}
1122default:
1123break;
1124}
1125//}
1126//}
1127}
1128
1129#endif // _RESOLUTION_H_
1130

Archive Download this file

Revision: 2238