Root/
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 | * 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 |