Root/
Source at commit 1158 created 13 years 16 days ago. By azimutz, Match nvidia.c with the one on my branch (Chazi) adding dev id's from issue 99 and Asus G74SX (0DF4, 1251). | |
---|---|
1 | /*␊ |
2 | * edid.c␊ |
3 | * ␊ |
4 | *␊ |
5 | * Created by Evan Lojewski on 12/1/09.␊ |
6 | * Copyright 2009. All rights reserved.␊ |
7 | *␊ |
8 | */␊ |
9 | ␊ |
10 | ␊ |
11 | #include "libsaio.h"␊ |
12 | #include "edid.h"␊ |
13 | #include "vbe.h"␊ |
14 | #include "graphics.h"␊ |
15 | #include "boot.h"␊ |
16 | ␊ |
17 | void getResolution(UInt32* x, UInt32* y, UInt32* bp)␊ |
18 | {␊ |
19 | ␉int val;␊ |
20 | ␉static UInt32 xResolution, yResolution, bpResolution;␊ |
21 | ␊ |
22 | ␉if(getIntForKey(kScreenWidth, &val, &bootInfo->bootConfig))␊ |
23 | ␉{␊ |
24 | ␉␉xResolution = val;␊ |
25 | ␉}␊ |
26 | ␉␊ |
27 | ␉if(getIntForKey(kScreenHeight, &val, &bootInfo->bootConfig))␊ |
28 | ␉{␊ |
29 | ␉␉yResolution = val;␊ |
30 | ␉}␊ |
31 | ␊ |
32 | ␉bpResolution = 32;␉// assume 32bits␊ |
33 | ␊ |
34 | ␉␊ |
35 | ␉if(!xResolution || !yResolution || !bpResolution)␊ |
36 | ␉{␊ |
37 | ␉␉␊ |
38 | ␉␉char* edidInfo = readEDID();␊ |
39 | ␉␉␊ |
40 | ␉␉if(!edidInfo) return;␊ |
41 | ␉␉␊ |
42 | ␉␉// TODO: check *all* resolutions reported and either use the highest, or the native resolution (if there is a flag for that)␊ |
43 | ␉␉xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);␊ |
44 | ␉␉yResolution = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);␊ |
45 | ␉␉␊ |
46 | ␉␉//printf("H Active = %d", edidInfo[56] | ((edidInfo[58] & 0xF0) << 4) );␊ |
47 | ␉␉//printf("V Active = %d", edidInfo[59] | ((edidInfo[61] & 0xF0) << 4) );␊ |
48 | ␉␉␊ |
49 | ␉␉free( edidInfo );␊ |
50 | ␉␉␊ |
51 | ␉␉if(!xResolution) xResolution = DEFAULT_SCREEN_WIDTH;␊ |
52 | ␉␉if(!yResolution) yResolution = DEFAULT_SCREEN_HEIGHT;␊ |
53 | ␊ |
54 | ␉}␊ |
55 | ␊ |
56 | ␉*x = xResolution;␊ |
57 | ␉*y = yResolution;␊ |
58 | ␉*bp = bpResolution;␊ |
59 | ␊ |
60 | }␊ |
61 | ␊ |
62 | char* readEDID()␊ |
63 | {␊ |
64 | ␉SInt16 last_reported = -1;␊ |
65 | ␉UInt8 edidInfo[EDID_BLOCK_SIZE];␊ |
66 | ␊ |
67 | ␉UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};␊ |
68 | ␉UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};␊ |
69 | ␉␊ |
70 | ␉SInt16 status;␊ |
71 | ␉UInt16 blocks_left = 1;␊ |
72 | ␉␊ |
73 | ␉do␊ |
74 | ␉{␊ |
75 | ␉␉// TODO: This currently only retrieves the *last* block, make the block buffer expand as needed / calculated from the first block␊ |
76 | ␊ |
77 | ␉␉bzero( edidInfo, EDID_BLOCK_SIZE);␊ |
78 | ␊ |
79 | ␉␉status = getEDID(edidInfo, blocks_left);␊ |
80 | ␉␉␊ |
81 | ␉␉␊ |
82 | ␉␉//printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer));␊ |
83 | ␉␉/*␊ |
84 | ␉␉int j, i;␊ |
85 | ␉␉for (j = 0; j < 8; j++) {␊ |
86 | ␉␉␉for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]);␊ |
87 | ␊ |
88 | ␉␉}␊ |
89 | ␉␉printf("\n");␊ |
90 | ␉␉*/␊ |
91 | ␉␉␊ |
92 | ␉␉if(status == 0)␊ |
93 | ␉␉{␊ |
94 | ␉␉␉//if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF)␊ |
95 | ␉␉␉if((memcmp(edidInfo, header1, sizeof(header1)) != 0) ||␊ |
96 | ␉␉␉ (memcmp(edidInfo, header2, sizeof(header2)) != 0) )␊ |
97 | ␉␉␉{␊ |
98 | ␉␉␉␉blocks_left--;␊ |
99 | ␉␉␉␉int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ];␊ |
100 | ␉␉␉␉␊ |
101 | ␉␉␉␉if ( reported > blocks_left )␊ |
102 | ␉␉␉␉{␊ |
103 | ␉␉␉␉␉␊ |
104 | ␉␉␉␉␉printf("EDID claims %d more blocks left\n", reported);␊ |
105 | ␉␉␉␉}␊ |
106 | ␉␉␉␉␊ |
107 | ␉␉␉␉if ( (last_reported <= reported && last_reported != -1)␊ |
108 | ␉␉␉␉␉|| reported == 0xff␊ |
109 | ␉␉␉␉␉/* 0xff frequently comes up in corrupt edids */␊ |
110 | ␉␉␉␉␉//|| reported == MAGIC␊ |
111 | ␉␉␉␉␉)␊ |
112 | ␉␉␉␉{␊ |
113 | ␉␉␉␉␉printf("Last reported %d\n", last_reported);␊ |
114 | ␉␉␉␉␉printf( "EDID blocks left is wrong.\n"␊ |
115 | ␉␉␉␉␉␉ "Your EDID is probably invalid.\n");␊ |
116 | ␉␉␉␉␉return 0;␊ |
117 | ␉␉␉␉}␊ |
118 | ␉␉␉␉else␊ |
119 | ␉␉␉␉{␊ |
120 | ␉␉␉␉␉//printf("Reading EDID block\n");␊ |
121 | ␉␉␉␉␉//printf("H Active = %d", ebiosInfo[56] | ((ebiosInfo[58] & 0xF0) << 4) );␊ |
122 | ␉␉␉␉␉//printf("V Active = %d", ebiosInfo[59] | ((ebiosInfo[61] & 0xF0) << 4) );␊ |
123 | ␊ |
124 | ␉␉␉␉␉last_reported = reported;␊ |
125 | ␉␉␉␉␉blocks_left = reported;␊ |
126 | ␉␉␉␉}␊ |
127 | ␉␉␉} ␊ |
128 | ␉␉␉else␊ |
129 | ␉␉␉{␊ |
130 | ␉␉␉␉printf("Invalid block %d\n", blocks_left);␊ |
131 | ␉␉␉␉printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) );␊ |
132 | ␉␉␉␉printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );␊ |
133 | ␉␉␉␉return 0;␊ |
134 | ␉␉␉}␊ |
135 | ␉␉}␊ |
136 | ␉␉blocks_left = 0;␉␊ |
137 | ␉} while(blocks_left);␊ |
138 | ␊ |
139 | ␉char* ret = malloc(sizeof(edidInfo));␊ |
140 | ␉memcpy(ret, edidInfo, sizeof(edidInfo));␊ |
141 | ␉return ret;␊ |
142 | }␊ |
143 |