Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Modules/i386/modules/NVIDIAGraphicsEnabler/nvidia.c

1/*
2 *NVidia injector
3 *
4 *Copyright (C) 2009Jasmin Fazlic, iNDi
5 *
6 *NVidia injector is free software: you can redistribute it and/or modify
7 *it under the terms of the GNU General Public License as published by
8 *the Free Software Foundation, either version 3 of the License, or
9 *(at your option) any later version.
10 *
11 *NVidia driver and injector is distributed in the hope that it will be useful,
12 *but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *GNU General Public License for more details.
15 *
16 *You should have received a copy of the GNU General Public License
17 *along with NVidia injector. If not, see <http://www.gnu.org/licenses/>.
18 */
19/*
20 * Alternatively you can choose to comply with APSL
21 */
22
23
24/*
25 * DCB-Table parsing is based on software (nouveau driver) originally distributed under following license:
26 *
27 *
28 * Copyright 2005-2006 Erik Waling
29 * Copyright 2006 Stephane Marchesin
30 * Copyright 2007-2009 Stuart Bennett
31 *
32 * Permission is hereby granted, free of charge, to any person obtaining a
33 * copy of this software and associated documentation files (the "Software"),
34 * to deal in the Software without restriction, including without limitation
35 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
36 * and/or sell copies of the Software, and to permit persons to whom the
37 * Software is furnished to do so, subject to the following conditions:
38 *
39 * The above copyright notice and this permission notice shall be included in
40 * all copies or substantial portions of the Software.
41 *
42 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
45 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
46 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
47 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
48 * SOFTWARE.
49 */
50
51//#include "boot.h"
52#include "libsa.h"
53#include "saio_internal.h"
54#include "bootstruct.h"
55#include "pci.h"
56#include "platform.h"
57#include "device_inject.h"
58#include "nvidia.h"
59
60#ifndef DEBUG_NVIDIA
61#define DEBUG_NVIDIA 0
62#endif
63
64#if DEBUG_NVIDIA
65#define DBG(x...)printf(x)
66#else
67#define DBG(x...)
68#endif
69
70#define kUseNvidiaROM"UseNvidiaROM"
71#define kVBIOS"VBIOS"
72#define kDcfg0"display_0"
73#define kDcfg1"display_1"
74
75#define NVIDIA_ROM_SIZE0x10000
76#define PATCH_ROM_SUCCESS1
77#define PATCH_ROM_SUCCESS_HAS_LVDS2
78#define PATCH_ROM_FAILED0
79#define MAX_NUM_DCB_ENTRIES16
80#define TYPE_GROUPED0xff
81
82extern uint32_t devices_number;
83
84const char *nvidia_compatible_0[]={ "@0,compatible","NVDA,NVMac" };
85const char *nvidia_compatible_1[]={ "@1,compatible","NVDA,NVMac" };
86const char *nvidia_device_type_0[]={ "@0,device_type", "display" };
87const char *nvidia_device_type_1[]={ "@1,device_type", "display" };
88const char *nvidia_device_type[]={ "device_type","NVDA,Parent" };
89/*
90 TODO: http://forge.voodooprojects.org/p/chameleon/issues/193/
91 const char *nvidia_device_type[]={ "device_type","NVDA,Child" };
92 */
93const char *nvidia_name_0[]={ "@0,name","NVDA,Display-A" };
94const char *nvidia_name_1[]={ "@1,name","NVDA,Display-B" };
95const char *nvidia_slot_name[]={ "AAPL,slot-name", "Slot-1" };
96
97// uint8_t display_cfg_0[]={0x03, 0x01, 0x03, 0x00};
98// uint8_t display_cfg_1[]={0xff, 0xff, 0x00, 0x01};
99// uint8_t connector_type_1[] ={0x00, 0x08, 0x00, 0x00};
100
101static uint8_t default_NVCAP[]= {
1020x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
1030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
1040x00, 0x00, 0x00, 0x00
105};
106
107static uint8_t default_NVPM[]= {
108 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00
112};
113
114#define NVCAP_LEN ( sizeof(default_NVCAP) / sizeof(uint8_t) )
115#define NVPM_LEN ( sizeof(default_NVPM) / sizeof(uint8_t) )
116
117static uint8_t default_dcfg_0[]={0xff, 0xff, 0xff, 0xff};
118static uint8_t default_dcfg_1[]={0xff, 0xff, 0xff, 0xff};
119
120#define DCFG0_LEN ( sizeof(default_dcfg_0) / sizeof(uint8_t) )
121#define DCFG1_LEN ( sizeof(default_dcfg_1) / sizeof(uint8_t) )
122
123static struct nv_chipsets_t NVKnownChipsets[] = {
124{ 0x00000000, "Unknown" },
125// temporary placement
126// { 0x10DE0DF4, "GeForce GT 450M" }, //Azi + issue #99
127// { 0x10DE1251, "GeForce GTX 560M" }, // Asus G74SX
128//========================================
129// 0040 - 004F
130{ 0x10DE0040, "GeForce 6800 Ultra" },
131{ 0x10DE0041, "GeForce 6800" },
132{ 0x10DE0042, "GeForce 6800 LE" },
133{ 0x10DE0043, "GeForce 6800 XE" },
134{ 0x10DE0044, "GeForce 6800 XT" },
135{ 0x10DE0045, "GeForce 6800 GT" },
136{ 0x10DE0046, "GeForce 6800 GT" },
137{ 0x10DE0047, "GeForce 6800 GS" },
138{ 0x10DE0048, "GeForce 6800 XT" },
139{ 0x10DE004D, "Quadro FX 3400" },
140{ 0x10DE004E, "Quadro FX 4000" },
141// 0050 - 005F
142// 0060 - 006F
143// 0070 - 007F
144// 0080 - 008F
145// 0090 - 009F
146{ 0x10DE0090, "GeForce 7800 GTX" },
147{ 0x10DE0091, "GeForce 7800 GTX" },
148{ 0x10DE0092, "GeForce 7800 GT" },
149{ 0x10DE0093, "GeForce 7800 GS" },
150{ 0x10DE0095, "GeForce 7800 SLI" },
151{ 0x10DE0098, "GeForce Go 7800" },
152{ 0x10DE0099, "GeForce Go 7800 GTX" },
153{ 0x10DE009D, "Quadro FX 4500" },
154// 00A0 - 00AF
155// 00B0 - 00BF
156// 00C0 - 00CF
157{ 0x10DE00C0, "GeForce 6800 GS" },
158{ 0x10DE00C1, "GeForce 6800" },
159{ 0x10DE00C2, "GeForce 6800 LE" },
160{ 0x10DE00C3, "GeForce 6800 XT" },
161{ 0x10DE00C8, "GeForce Go 6800" },
162{ 0x10DE00C9, "GeForce Go 6800 Ultra" },
163{ 0x10DE00CC, "Quadro FX Go1400" },
164{ 0x10DE00CD, "Quadro FX 3450/4000 SDI" },
165{ 0x10DE00CE, "Quadro FX 1400" },
166// 00D0 - 00DF
167// 00E0 - 00EF
168// 00F0 - 00FF
169{ 0x10DE00F1, "GeForce 6600 GT" },
170{ 0x10DE00F2, "GeForce 6600" },
171{ 0x10DE00F3, "GeForce 6200" },
172{ 0x10DE00F4, "GeForce 6600 LE" },
173{ 0x10DE00F5, "GeForce 7800 GS" },
174{ 0x10DE00F6, "GeForce 6800 GS/XT" },
175{ 0x10DE00F8, "Quadro FX 3400/4400" },
176{ 0x10DE00F9, "GeForce 6800 Series GPU" },
177// 0100 - 010F
178// 0110 - 011F
179// 0120 - 012F
180// 0130 - 013F
181// 0140 - 014F
182{ 0x10DE0140, "GeForce 6600 GT" },
183{ 0x10DE0141, "GeForce 6600" },
184{ 0x10DE0142, "GeForce 6600 LE" },
185{ 0x10DE0143, "GeForce 6600 VE" },
186{ 0x10DE0144, "GeForce Go 6600" },
187{ 0x10DE0145, "GeForce 6610 XL" },
188{ 0x10DE0146, "GeForce Go 6600 TE/6200 TE" },
189{ 0x10DE0147, "GeForce 6700 XL" },
190{ 0x10DE0148, "GeForce Go 6600" },
191{ 0x10DE0149, "GeForce Go 6600 GT" },
192{ 0x10DE014A, "Quadro NVS 440" },
193{ 0x10DE014C, "Quadro FX 550" },
194{ 0x10DE014D, "Quadro FX 550" },
195{ 0x10DE014E, "Quadro FX 540" },
196{ 0x10DE014F, "GeForce 6200" },
197// 0150 - 015F
198// 0160 - 016F
199{ 0x10DE0160, "GeForce 6500" },
200{ 0x10DE0161, "GeForce 6200 TurboCache(TM)" },
201{ 0x10DE0162, "GeForce 6200SE TurboCache(TM)" },
202{ 0x10DE0163, "GeForce 6200 LE" },
203{ 0x10DE0164, "GeForce Go 6200" },
204{ 0x10DE0165, "Quadro NVS 285" },
205{ 0x10DE0166, "GeForce Go 6400" },
206{ 0x10DE0167, "GeForce Go 6200" },
207{ 0x10DE0168, "GeForce Go 6400" },
208{ 0x10DE0169, "GeForce 6250" },
209{ 0x10DE016A, "GeForce 7100 GS" },
210// 0170 - 017F
211// 0180 - 018F
212// 0190 - 019F
213{ 0x10DE0191, "GeForce 8800 GTX" },
214{ 0x10DE0193, "GeForce 8800 GTS" },
215{ 0x10DE0194, "GeForce 8800 Ultra" },
216{ 0x10DE0197, "Tesla C870" },
217{ 0x10DE019D, "Quadro FX 5600" },
218{ 0x10DE019E, "Quadro FX 4600" },
219// 01A0 - 01AF
220// 01B0 - 01BF
221// 01C0 - 01CF
222// 01D0 - 01DF
223{ 0x10DE01D0, "GeForce 7350 LE" },
224{ 0x10DE01D1, "GeForce 7300 LE" },
225{ 0x10DE01D2, "GeForce 7550 LE" },
226{ 0x10DE01D3, "GeForce 7300 SE/7200 GS" },
227{ 0x10DE01D6, "GeForce Go 7200" },
228{ 0x10DE01D7, "GeForce Go 7300" },
229{ 0x10DE01D8, "GeForce Go 7400" },
230{ 0x10DE01D9, "GeForce Go 7400 GS" },
231{ 0x10DE01DA, "Quadro NVS 110M" },
232{ 0x10DE01DB, "Quadro NVS 120M" },
233{ 0x10DE01DC, "Quadro FX 350M" },
234{ 0x10DE01DD, "GeForce 7500 LE" },
235{ 0x10DE01DE, "Quadro FX 350" },
236{ 0x10DE01DF, "GeForce 7300 GS" },
237// 01E0 - 01EF
238// 01F0 - 01FF
239// 0200 - 020F
240// 0210 - 021F
241{ 0x10DE0211, "GeForce 6800" },
242{ 0x10DE0212, "GeForce 6800 LE" },
243{ 0x10DE0215, "GeForce 6800 GT" },
244{ 0x10DE0218, "GeForce 6800 XT" },
245// 0220 - 022F
246{ 0x10DE0221, "GeForce 6200" },
247{ 0x10DE0222, "GeForce 6200 A-LE" },
248// 0230 - 023F
249// 0240 - 024F
250{ 0x10DE0240, "GeForce 6150" },
251{ 0x10DE0241, "GeForce 6150 LE" },
252{ 0x10DE0242, "GeForce 6100" },
253{ 0x10DE0244, "GeForce Go 6150" },
254{ 0x10DE0245, "Quadro NVS 210S / GeForce 6150LE" },
255{ 0x10DE0247, "GeForce Go 6100" },
256// 0250 - 025F
257// 0260 - 026F
258// 0270 - 027F
259// 0280 - 028F
260// 0290 - 029F
261{ 0x10DE0290, "GeForce 7900 GTX" },
262{ 0x10DE0291, "GeForce 7900 GT/GTO" },
263{ 0x10DE0292, "GeForce 7900 GS" },
264{ 0x10DE0293, "GeForce 7950 GX2" },
265{ 0x10DE0294, "GeForce 7950 GX2" },
266{ 0x10DE0295, "GeForce 7950 GT" },
267{ 0x10DE0298, "GeForce Go 7900 GS" },
268{ 0x10DE0299, "GeForce Go 7900 GTX" },
269{ 0x10DE029A, "Quadro FX 2500M" },
270{ 0x10DE029B, "Quadro FX 1500M" },
271{ 0x10DE029C, "Quadro FX 5500" },
272{ 0x10DE029D, "Quadro FX 3500" },
273{ 0x10DE029E, "Quadro FX 1500" },
274{ 0x10DE029F, "Quadro FX 4500 X2" },
275// 02A0 - 02AF
276// 02B0 - 02BF
277// 02C0 - 02CF
278// 02D0 - 02DF
279// 02E0 - 02EF
280{ 0x10DE02E0, "GeForce 7600 GT" },
281{ 0x10DE02E1, "GeForce 7600 GS" },
282{ 0x10DE02E2, "GeForce 7300 GT" },
283{ 0x10DE02E3, "GeForce 7900 GS" },
284{ 0x10DE02E4, "GeForce 7950 GT" },
285// 02F0 - 02FF
286// 0300 - 030F
287{ 0x10DE0301, "GeForce FX 5800 Ultra" },
288{ 0x10DE0302, "GeForce FX 5800" },
289{ 0x10DE0308, "Quadro FX 2000" },
290{ 0x10DE0309, "Quadro FX 1000" },
291// 0310 - 031F
292{ 0x10DE0311, "GeForce FX 5600 Ultra" },
293{ 0x10DE0312, "GeForce FX 5600" },
294{ 0x10DE0314, "GeForce FX 5600XT" },
295{ 0x10DE031A, "GeForce FX Go5600" },
296{ 0x10DE031B, "GeForce FX Go5650" },
297{ 0x10DE031C, "Quadro FX Go700" },
298// 0320 - 032F
299{ 0x10DE0324, "GeForce FX Go5200" },
300{ 0x10DE0325, "GeForce FX Go5250" },
301{ 0x10DE0326, "GeForce FX 5500" },
302{ 0x10DE0328, "GeForce FX Go5200 32M/64M" },
303{ 0x10DE032A, "Quadro NVS 55/280 PCI" },
304{ 0x10DE032B, "Quadro FX 500/600 PCI" },
305{ 0x10DE032C, "GeForce FX Go53xx Series" },
306{ 0x10DE032D, "GeForce FX Go5100" },
307// 0330 - 033F
308{ 0x10DE0330, "GeForce FX 5900 Ultra" },
309{ 0x10DE0331, "GeForce FX 5900" },
310{ 0x10DE0332, "GeForce FX 5900XT" },
311{ 0x10DE0333, "GeForce FX 5950 Ultra" },
312{ 0x10DE0334, "GeForce FX 5900ZT" },
313{ 0x10DE0338, "Quadro FX 3000" },
314{ 0x10DE033F, "Quadro FX 700" },
315// 0340 - 034F
316{ 0x10DE0341, "GeForce FX 5700 Ultra" },
317{ 0x10DE0342, "GeForce FX 5700" },
318{ 0x10DE0343, "GeForce FX 5700LE" },
319{ 0x10DE0344, "GeForce FX 5700VE" },
320{ 0x10DE0347, "GeForce FX Go5700" },
321{ 0x10DE0348, "GeForce FX Go5700" },
322{ 0x10DE034C, "Quadro FX Go1000" },
323{ 0x10DE034E, "Quadro FX 1100" },
324// 0350 - 035F
325// 0360 - 036F
326// 0370 - 037F
327// 0380 - 038F
328{ 0x10DE038B, "GeForce 7650 GS" },
329// 0390 - 039F
330{ 0x10DE0390, "GeForce 7650 GS" },
331{ 0x10DE0391, "GeForce 7600 GT" },
332{ 0x10DE0392, "GeForce 7600 GS" },
333{ 0x10DE0393, "GeForce 7300 GT" },
334{ 0x10DE0394, "GeForce 7600 LE" },
335{ 0x10DE0395, "GeForce 7300 GT" },
336{ 0x10DE0397, "GeForce Go 7700" },
337{ 0x10DE0398, "GeForce Go 7600" },
338{ 0x10DE0399, "GeForce Go 7600 GT"},
339{ 0x10DE039A, "Quadro NVS 300M" },
340{ 0x10DE039B, "GeForce Go 7900 SE" },
341{ 0x10DE039C, "Quadro FX 550M" },
342{ 0x10DE039E, "Quadro FX 560" },
343// 03A0 - 03AF
344// 03B0 - 03BF
345// 03C0 - 03CF
346// 03D0 - 03DF
347{ 0x10DE03D0, "GeForce 6150SE nForce 430" },
348{ 0x10DE03D1, "GeForce 6100 nForce 405" },
349{ 0x10DE03D2, "GeForce 6100 nForce 400" },
350{ 0x10DE03D5, "GeForce 6100 nForce 420" },
351{ 0x10DE03D6, "GeForce 7025 / nForce 630a" },
352// 03E0 - 03EF
353// 03F0 - 03FF
354// 0400 - 040F
355{ 0x10DE0400, "GeForce 8600 GTS" },
356{ 0x10DE0401, "GeForce 8600 GT" },
357{ 0x10DE0402, "GeForce 8600 GT" },
358{ 0x10DE0403, "GeForce 8600 GS" },
359{ 0x10DE0404, "GeForce 8400 GS" },
360{ 0x10DE0405, "GeForce 9500M GS" },
361{ 0x10DE0406, "GeForce 8300 GS" },
362{ 0x10DE0407, "GeForce 8600M GT" },
363{ 0x10DE0408, "GeForce 9650M GS" },
364{ 0x10DE0409, "GeForce 8700M GT" },
365{ 0x10DE040A, "Quadro FX 370" },
366{ 0x10DE040B, "Quadro NVS 320M" },
367{ 0x10DE040C, "Quadro FX 570M" },
368{ 0x10DE040D, "Quadro FX 1600M" },
369{ 0x10DE040E, "Quadro FX 570" },
370{ 0x10DE040F, "Quadro FX 1700" },
371// 0410 - 041F
372{ 0x10DE0410, "GeForce GT 330" },
373// 0420 - 042F
374{ 0x10DE0420, "GeForce 8400 SE" },
375{ 0x10DE0421, "GeForce 8500 GT" },
376{ 0x10DE0422, "GeForce 8400 GS" },
377{ 0x10DE0423, "GeForce 8300 GS" },
378{ 0x10DE0424, "GeForce 8400 GS" },
379{ 0x10DE0425, "GeForce 8600M GS" },
380{ 0x10DE0426, "GeForce 8400M GT" },
381{ 0x10DE0427, "GeForce 8400M GS" },
382{ 0x10DE0428, "GeForce 8400M G" },
383{ 0x10DE0429, "Quadro NVS 140M" },
384{ 0x10DE042A, "Quadro NVS 130M" },
385{ 0x10DE042B, "Quadro NVS 135M" },
386{ 0x10DE042C, "GeForce 9400 GT" },
387{ 0x10DE042D, "Quadro FX 360M" },
388{ 0x10DE042E, "GeForce 9300M G" },
389{ 0x10DE042F, "Quadro NVS 290" },
390// 0430 - 043F
391// 0440 - 044F
392// 0450 - 045F
393// 0460 - 046F
394// 0470 - 047F
395// 0480 - 048F
396// 0490 - 049F
397// 04A0 - 04AF
398// 04B0 - 04BF
399// 04C0 - 04CF
400// 04D0 - 04DF
401// 04E0 - 04EF
402// 04F0 - 04FF
403// 0500 - 050F
404// 0510 - 051F
405// 0520 - 052F
406// 0530 - 053F
407{ 0x10DE053A, "GeForce 7050 PV / nForce 630a" },
408{ 0x10DE053B, "GeForce 7050 PV / nForce 630a" },
409{ 0x10DE053E, "GeForce 7025 / nForce 630a" },
410// 0540 - 054F
411// 0550 - 055F
412// 0560 - 056F
413// 0570 - 057F
414// 0580 - 058F
415// 0590 - 059F
416// 05A0 - 05AF
417// 05B0 - 05BF
418// 05C0 - 05CF
419// 05D0 - 05DF
420// 05E0 - 05EF
421{ 0x10DE05E0, "GeForce GTX 295" },
422{ 0x10DE05E1, "GeForce GTX 280" },
423{ 0x10DE05E2, "GeForce GTX 260" },
424{ 0x10DE05E3, "GeForce GTX 285" },
425{ 0x10DE05E6, "GeForce GTX 275" },
426{ 0x10DE05E7, "Tesla C1060" },
427{ 0x10DE05EA, "GeForce GTX 260" },
428{ 0x10DE05EB, "GeForce GTX 295" },
429{ 0x10DE05ED, "Quadroplex 2200 D2" },
430// 05F0 - 05FF
431{ 0x10DE05F8, "Quadroplex 2200 S4" },
432{ 0x10DE05F9, "Quadro CX" },
433{ 0x10DE05FD, "Quadro FX 5800" },
434{ 0x10DE05FE, "Quadro FX 4800" },
435{ 0x10DE05FF, "Quadro FX 3800" },
436// 0600 - 060F
437{ 0x10DE0600, "GeForce 8800 GTS 512" },
438{ 0x10DE0601, "GeForce 9800 GT" },
439{ 0x10DE0602, "GeForce 8800 GT" },
440{ 0x10DE0603, "GeForce GT 230" },
441{ 0x10DE0604, "GeForce 9800 GX2" },
442{ 0x10DE0605, "GeForce 9800 GT" },
443{ 0x10DE0606, "GeForce 8800 GS" },
444{ 0x10DE0607, "GeForce GTS 240" },
445{ 0x10DE0608, "GeForce 9800M GTX" },
446{ 0x10DE0609, "GeForce 8800M GTS" },
447{ 0x10DE060A, "GeForce GTX 280M" },
448{ 0x10DE060B, "GeForce 9800M GT" },
449{ 0x10DE060C, "GeForce 8800M GTX" },
450{ 0x10DE060D, "GeForce 8800 GS" },
451{ 0x10DE060F, "GeForce GTX 285M" },
452// 0610 - 061F
453{ 0x10DE0610, "GeForce 9600 GSO" },
454{ 0x10DE0611, "GeForce 8800 GT" },
455{ 0x10DE0612, "GeForce 9800 GTX" },
456{ 0x10DE0613, "GeForce 9800 GTX+" },
457{ 0x10DE0614, "GeForce 9800 GT" },
458{ 0x10DE0615, "GeForce GTS 250" },
459{ 0x10DE0617, "GeForce 9800M GTX" },
460{ 0x10DE0618, "GeForce GTX 260M" },
461{ 0x10DE0619, "Quadro FX 4700 X2" },
462{ 0x10DE061A, "Quadro FX 3700" },
463{ 0x10DE061B, "Quadro VX 200" },
464{ 0x10DE061C, "Quadro FX 3600M" },
465{ 0x10DE061D, "Quadro FX 2800M" },
466{ 0x10DE061E, "Quadro FX 3700M" },
467{ 0x10DE061F, "Quadro FX 3800M" },
468// 0620 - 062F
469{ 0x10DE0621, "GeForce GT 230" },
470{ 0x10DE0622, "GeForce 9600 GT" },
471{ 0x10DE0623, "GeForce 9600 GS" },
472{ 0x10DE0625, "GeForce 9600 GSO 512"},
473{ 0x10DE0626, "GeForce GT 130" },
474{ 0x10DE0627, "GeForce GT 140" },
475{ 0x10DE0628, "GeForce 9800M GTS" },
476{ 0x10DE062A, "GeForce 9700M GTS" },
477{ 0x10DE062B, "GeForce 9800M GS" },
478{ 0x10DE062C, "GeForce 9800M GTS" },
479{ 0x10DE062D, "GeForce 9600 GT" },
480{ 0x10DE062E, "GeForce 9600 GT" },
481// 0630 - 063F
482{ 0x10DE0631, "GeForce GTS 160M" },
483{ 0x10DE0632, "GeForce GTS 150M" },
484{ 0x10DE0635, "GeForce 9600 GSO" },
485{ 0x10DE0637, "GeForce 9600 GT" },
486{ 0x10DE0638, "Quadro FX 1800" },
487{ 0x10DE063A, "Quadro FX 2700M" },
488// 0640 - 064F
489{ 0x10DE0640, "GeForce 9500 GT" },
490{ 0x10DE0641, "GeForce 9400 GT" },
491{ 0x10DE0642, "GeForce 8400 GS" },
492{ 0x10DE0643, "GeForce 9500 GT" },
493{ 0x10DE0644, "GeForce 9500 GS" },
494{ 0x10DE0645, "GeForce 9500 GS" },
495{ 0x10DE0646, "GeForce GT 120" },
496{ 0x10DE0647, "GeForce 9600M GT" },
497{ 0x10DE0648, "GeForce 9600M GS" },
498{ 0x10DE0649, "GeForce 9600M GT" },
499{ 0x10DE064A, "GeForce 9700M GT" },
500{ 0x10DE064B, "GeForce 9500M G" },
501{ 0x10DE064C, "GeForce 9650M GT" },
502// 0650 - 065F
503{ 0x10DE0651, "GeForce G 110M" },
504{ 0x10DE0652, "GeForce GT 130M" },
505{ 0x10DE0653, "GeForce GT 120M" },
506{ 0x10DE0654, "GeForce GT 220M" },
507{ 0x10DE0655, "GeForce GT 120" },
508{ 0x10DE0656, "GeForce 9650 S" },
509{ 0x10DE0658, "Quadro FX 380" },
510{ 0x10DE0659, "Quadro FX 580" },
511{ 0x10DE065A, "Quadro FX 1700M" },
512{ 0x10DE065B, "GeForce 9400 GT" },
513{ 0x10DE065C, "Quadro FX 770M" },
514{ 0x10DE065F, "GeForce G210" },
515// 0660 - 066F
516// 0670 - 067F
517// 0680 - 068F
518// 0690 - 069F
519// 06A0 - 06AF
520// 06B0 - 06BF
521// 06C0 - 06CF
522{ 0x10DE06C0, "GeForce GTX 480" },
523{ 0x10DE06C3, "GeForce GTX D12U" },
524{ 0x10DE06C4, "GeForce GTX 465" },
525{ 0x10DE06CA, "GeForce GTX 480M" },
526{ 0x10DE06CD, "GeForce GTX 470" },
527// 06D0 - 06DF
528{ 0x10DE06D1, "Tesla C2050" },// TODO: sub-device id: 0x0771
529{ 0x10DE06D1, "Tesla C2070" },// TODO: sub-device id: 0x0772
530{ 0x10DE06D2, "Tesla M2070" },
531{ 0x10DE06D8, "Quadro 6000" },
532{ 0x10DE06D9, "Quadro 5000" },
533{ 0x10DE06DA, "Quadro 5000M" },
534{ 0x10DE06DC, "Quadro 6000" },
535{ 0x10DE06DD, "Quadro 4000" },
536{ 0x10DE06DE, "Tesla M2050" },// TODO: sub-device id: 0x0846
537{ 0x10DE06DE, "Tesla M2070" },// TODO: sub-device id: ?
538{ 0x10DE06DF, "Tesla M2070-Q" },
539// 0x10DE06DE also applies to misc S2050, X2070, M2050, M2070
540// 06E0 - 06EF
541{ 0x10DE06E0, "GeForce 9300 GE" },
542{ 0x10DE06E1, "GeForce 9300 GS" },
543{ 0x10DE06E2, "GeForce 8400" },
544{ 0x10DE06E3, "GeForce 8400 SE" },
545{ 0x10DE06E4, "GeForce 8400 GS" },
546{ 0x10DE06E5, "GeForce 9300M GS" },
547{ 0x10DE06E6, "GeForce G100" },
548{ 0x10DE06E7, "GeForce 9300 SE" },
549{ 0x10DE06E8, "GeForce 9200M GS" },
550{ 0x10DE06E9, "GeForce 9300M GS" },
551{ 0x10DE06EA, "Quadro NVS 150M" },
552{ 0x10DE06EB, "Quadro NVS 160M" },
553{ 0x10DE06EC, "GeForce G 105M" },
554{ 0x10DE06EF, "GeForce G 103M" },
555// 06F0 - 06FF
556{ 0x10DE06F1, "GeForce G105M" },
557{ 0x10DE06F8, "Quadro NVS 420" },
558{ 0x10DE06F9, "Quadro FX 370 LP" },
559{ 0x10DE06FA, "Quadro NVS 450" },
560{ 0x10DE06FB, "Quadro FX 370M" },
561{ 0x10DE06FD, "Quadro NVS 295" },
562{ 0x10DE06FF, "HICx16 + Graphics" },
563// 0700 - 070F
564// 0710 - 071F
565// 0720 - 072F
566// 0730 - 073F
567// 0740 - 074F
568// 0750 - 075F
569// 0760 - 076F
570// 0770 - 077F
571// 0780 - 078F
572// 0790 - 079F
573// 07A0 - 07AF
574// 07B0 - 07BF
575// 07C0 - 07CF
576// 07D0 - 07DF
577// 07E0 - 07EF
578{ 0x10DE07E0, "GeForce 7150 / nForce 630i" },
579{ 0x10DE07E1, "GeForce 7100 / nForce 630i" },
580{ 0x10DE07E2, "GeForce 7050 / nForce 630i" },
581{ 0x10DE07E3, "GeForce 7050 / nForce 610i" },
582{ 0x10DE07E5, "GeForce 7050 / nForce 620i" },
583// 07F0 - 07FF
584// 0800 - 080F
585// 0810 - 081F
586// 0820 - 082F
587// 0830 - 083F
588// 0840 - 084F
589{ 0x10DE0840, "GeForce 8200M" },
590{ 0x10DE0844, "GeForce 9100M G" },
591{ 0x10DE0845, "GeForce 8200M G" },
592{ 0x10DE0846, "GeForce 9200" },
593{ 0x10DE0847, "GeForce 9100" },
594{ 0x10DE0848, "GeForce 8300" },
595{ 0x10DE0849, "GeForce 8200" },
596{ 0x10DE084A, "nForce 730a" },
597{ 0x10DE084B, "GeForce 9200" },
598{ 0x10DE084C, "nForce 980a/780a SLI" },
599{ 0x10DE084D, "nForce 750a SLI" },
600{ 0x10DE084F, "GeForce 8100 / nForce 720a" },
601// 0850 - 085F
602// 0860 - 086F
603{ 0x10DE0860, "GeForce 9400" },
604{ 0x10DE0861, "GeForce 9400" },
605{ 0x10DE0862, "GeForce 9400M G" },
606{ 0x10DE0863, "GeForce 9400M" },
607{ 0x10DE0864, "GeForce 9300" },
608{ 0x10DE0865, "ION" },
609{ 0x10DE0866, "GeForce 9400M G" },
610{ 0x10DE0867, "GeForce 9400" },
611{ 0x10DE0868, "nForce 760i SLI" },
612{ 0x10DE0869, "GeForce 9400" },
613{ 0x10DE086A, "GeForce 9400" },
614{ 0x10DE086C, "GeForce 9300 / nForce 730i" },
615{ 0x10DE086D, "GeForce 9200" },
616{ 0x10DE086E, "GeForce 9100M G" },
617{ 0x10DE086F, "GeForce 8200M G" },
618// 0870 - 087F
619{ 0x10DE0870, "GeForce 9400M" },
620{ 0x10DE0871, "GeForce 9200" },
621{ 0x10DE0872, "GeForce G102M" },
622{ 0x10DE0873, "GeForce G102M" },
623{ 0x10DE0874, "ION 9300M" },
624{ 0x10DE0876, "ION" },
625{ 0x10DE087A, "GeForce 9400" },
626{ 0x10DE087D, "ION 9400M" },
627{ 0x10DE087E, "ION LE" },
628{ 0x10DE087F, "ION LE" },
629// 0880 - 088F
630// 0890 - 089F
631// 08A0 - 08AF
632{ 0x10DE08A0, "GeForce 320M" },
633{ 0x10DE08A4, "GeForce 320M" },
634// 08B0 - 08BF
635// 08C0 - 08CF
636// 08D0 - 08DF
637// 08E0 - 08EF
638// 08F0 - 08FF
639// 0900 - 090F
640// 0910 - 091F
641// 0920 - 092F
642// 0930 - 093F
643// 0940 - 094F
644// 0950 - 095F
645// 0960 - 096F
646// 0970 - 097F
647// 0980 - 098F
648// 0990 - 099F
649// 09A0 - 09AF
650// 09B0 - 09BF
651// 09C0 - 09CF
652// 09D0 - 09DF
653// 09E0 - 09EF
654// 09F0 - 09FF
655// 0A00 - 0A0F
656// 0A10 - 0A1F
657// 0A20 - 0A2F
658{ 0x10DE0A20, "GeForce GT220" },
659{ 0x10DE0A22, "GeForce 315" },
660{ 0x10DE0A23, "GeForce 210" },
661{ 0x10DE0A26, "GeForce 405" },
662{ 0x10DE0A27, "GeForce 405" },
663{ 0x10DE0A28, "GeForce GT 230M" },
664{ 0x10DE0A29, "GeForce GT 330M" },
665{ 0x10DE0A2A, "GeForce GT 230M" },
666{ 0x10DE0A2B, "GeForce GT 330M" },
667{ 0x10DE0A2C, "NVS 5100M" },
668{ 0x10DE0A2D, "GeForce GT 320M" },
669// 0A30 - 0A3F
670{ 0x10DE0A34, "GeForce GT 240M" },
671{ 0x10DE0A35, "GeForce GT 325M" },
672{ 0x10DE0A38, "Quadro 400" },
673{ 0x10DE0A3C, "Quadro FX 880M" },
674// 0A40 - 0A4F
675// 0A50 - 0A5F
676// 0A60 - 0A6F
677{ 0x10DE0A60, "GeForce G210" },
678{ 0x10DE0A62, "GeForce 205" },
679{ 0x10DE0A63, "GeForce 310" },
680{ 0x10DE0A64, "ION" },
681{ 0x10DE0A65, "GeForce 210" },
682{ 0x10DE0A66, "GeForce 310" },
683{ 0x10DE0A67, "GeForce 315" },
684{ 0x10DE0A68, "GeForce G105M" },
685{ 0x10DE0A69, "GeForce G105M" },
686{ 0x10DE0A6A, "NVS 2100M" },
687{ 0x10DE0A6C, "NVS 3100M" },
688{ 0x10DE0A6E, "GeForce 305M" },
689{ 0x10DE0A6F, "ION" },
690// 0A70 - 0A7F
691{ 0x10DE0A70, "GeForce 310M" },
692{ 0x10DE0A71, "GeForce 305M" },
693{ 0x10DE0A72, "GeForce 310M" },
694{ 0x10DE0A73, "GeForce 305M" },
695{ 0x10DE0A74, "GeForce G210M" },
696{ 0x10DE0A75, "GeForce G310M" },
697{ 0x10DE0A76, "ION" },
698{ 0x10DE0A78, "Quadro FX 380 LP" },
699{ 0x10DE0A7A, "GeForce 315M" },
700{ 0x10DE0A7C, "Quadro FX 380M" },
701// 0A80 - 0A8F
702// 0A90 - 0A9F
703// 0AA0 - 0AAF
704// 0AB0 - 0ABF
705// 0AC0 - 0ACF
706// 0AD0 - 0ADF
707// 0AE0 - 0AEF
708// 0AF0 - 0AFF
709// 0B00 - 0B0F
710// 0B10 - 0B1F
711// 0B20 - 0B2F
712// 0B30 - 0B3F
713// 0B40 - 0B4F
714// 0B50 - 0B5F
715// 0B60 - 0B6F
716// 0B70 - 0B7F
717// 0B80 - 0B8F
718// 0B90 - 0B9F
719// 0BA0 - 0BAF
720// 0BB0 - 0BBF
721// 0BC0 - 0BCF
722// 0BD0 - 0BDF
723// 0BE0 - 0BEF
724// 0BF0 - 0BFF
725// 0C00 - 0C0F
726// 0C10 - 0C1F
727// 0C20 - 0C2F
728// 0C30 - 0C3F
729// 0C40 - 0C4F
730// 0C50 - 0C5F
731// 0C60 - 0C6F
732// 0C70 - 0C7F
733// 0C80 - 0C8F
734// 0C90 - 0C9F
735// 0CA0 - 0CAF
736{ 0x10DE0CA0, "GeForce GT 330 " },
737{ 0x10DE0CA2, "GeForce GT 320" },
738{ 0x10DE0CA3, "GeForce GT 240" },
739{ 0x10DE0CA4, "GeForce GT 340" },
740{ 0x10DE0CA5, "GeForce GT 220" },
741{ 0x10DE0CA7, "GeForce GT 330" },
742{ 0x10DE0CA8, "GeForce GTS 260M" },
743{ 0x10DE0CA9, "GeForce GTS 250M" },
744{ 0x10DE0CAC, "GeForce GT 220" },
745{ 0x10DE0CAF, "GeForce GT 335M" },
746// 0CB0 - 0CBF
747{ 0x10DE0CB0, "GeForce GTS 350M" },
748{ 0x10DE0CB1, "GeForce GTS 360M" },
749{ 0x10DE0CBC, "Quadro FX 1800M" },
750// 0CC0 - 0CCF
751// 0CD0 - 0CDF
752// 0CE0 - 0CEF
753// 0CF0 - 0CFF
754// 0D00 - 0D0F
755// 0D10 - 0D1F
756// 0D20 - 0D2F
757// 0D30 - 0D3F
758// 0D40 - 0D4F
759// 0D50 - 0D5F
760// 0D60 - 0D6F
761// 0D70 - 0D7F
762// 0D80 - 0D8F
763// 0D90 - 0D9F
764// 0DA0 - 0DAF
765// 0DB0 - 0DBF
766// 0DC0 - 0DCF
767{ 0x10DE0DC0, "GeForce GT 440" },
768{ 0x10DE0DC1, "D12-P1-35" },
769{ 0x10DE0DC2, "D12-P1-35" },
770{ 0x10DE0DC4, "GeForce GTS 450" },
771{ 0x10DE0DC5, "GeForce GTS 450" },
772{ 0x10DE0DC6, "GeForce GTS 450" },
773{ 0x10DE0DCA, "GF10x" },
774{ 0x10DE0DCD, "GeForce GT 555M" },
775{ 0x10DE0DCE, "GeForce GT 555M" },
776// 0DD0 - 0DDF
777{ 0x10DE0DD1, "GeForce GTX 460M" },
778{ 0x10DE0DD2, "GeForce GT 445M" },
779{ 0x10DE0DD3, "GeForce GT 435M" },
780{ 0x10DE0DD6, "GeForce GT 550M" },
781{ 0x10DE0DD8, "Quadro 2000" },
782{ 0x10DE0DDA, "Quadro 2000M" },
783{ 0x10DE0DDE, "GF106-ES" },
784{ 0x10DE0DDF, "GF106-INT" },
785// 0DE0 - 0DEF
786{ 0x10DE0DE0, "GeForce GT 440" },
787{ 0x10DE0DE1, "GeForce GT 430" },
788{ 0x10DE0DE2, "GeForce GT 420" },
789{ 0x10DE0DE5, "GeForce GT 530" },
790{ 0x10DE0DEB, "GeForce GT 555M" },
791{ 0x10DE0DEC, "GeForce GT 525M" },
792{ 0x10DE0DED, "GeForce GT 520M" },
793{ 0x10DE0DEE, "GeForce GT 415M" },
794// 0DF0 - 0DFF
795{ 0x10DE0DF0, "GeForce GT 425M" },
796{ 0x10DE0DF1, "GeForce GT 420M" },
797{ 0x10DE0DF2, "GeForce GT 435M" },
798{ 0x10DE0DF3, "GeForce GT 420M" },
799{ 0x10DE0DF4, "GeForce GT 540M" },
800{ 0x10DE0DF5, "GeForce GT 525M" },
801{ 0x10DE0DF6, "GeForce GT 550M" },
802{ 0x10DE0DF7, "GeForce GT 520M" },
803{ 0x10DE0DF8, "Quadro 600" },
804{ 0x10DE0DFA, "Quadro 1000M" },
805{ 0x10DE0DFE, "GF108 ES" },
806{ 0x10DE0DFF, "GF108 INT" },
807// 0E00 - 0E0F
808// 0E10 - 0E1F
809// 0E20 - 0E2F
810{ 0x10DE0E21, "D12U-25" },
811{ 0x10DE0E22, "GeForce GTX 460" },
812{ 0x10DE0E23, "GeForce GTX 460 SE" },
813{ 0x10DE0E24, "GeForce GTX 460" },
814{ 0x10DE0E25, "D12U-50" },
815// 0E30 - 0E3F
816{ 0x10DE0E30, "GeForce GTX 470M" },
817{ 0x10DE0E31, "GeForce GTX 485M" },
818{ 0x10DE0E38, "GF104GL" },
819{ 0x10DE0E3A, "Quadro 3000M" },
820{ 0x10DE0E3B, "Quadro 4000M" },
821{ 0x10DE0E3E, "GF104-ES" },
822{ 0x10DE0E3F, "GF104-INT" },
823// 0E40 - 0E4F
824// 0E50 - 0E5F
825// 0E60 - 0E6F
826// 0E70 - 0E7F
827// 0E80 - 0E8F
828// 0E90 - 0E9F
829// 0EA0 - 0EAF
830// 0EB0 - 0EBF
831// 0EC0 - 0ECF
832// 0ED0 - 0EDF
833// 0EE0 - 0EEF
834// 0EF0 - 0EFF
835// 0F00 - 0F0F
836// 0F10 - 0F1F
837// 0F20 - 0F2F
838// 0F30 - 0F3F
839// 0F40 - 0F4F
840// 0F50 - 0F5F
841// 0F60 - 0F6F
842// 0F70 - 0F7F
843// 0F80 - 0F8F
844// 0F90 - 0F9F
845// 0FA0 - 0FAF
846// 0FB0 - 0FBF
847// 0FC0 - 0FCF
848// 0FD0 - 0FDF
849// 0FE0 - 0FEF
850// 0FF0 - 0FFF
851// 1000 - 100F
852// 1010 - 101F
853// 1020 - 102F
854// 1030 - 103F
855// 1040 - 104F
856{ 0x10DE1040, "GeForce GT 520" },
857// 1050 - 105F
858{ 0x10DE1050, "GeForce GT 520M" },
859{ 0x10DE1051, "GeForce GT 520MX" },
860{ 0x10DE1054, "GeForce GT 410M" },
861{ 0x10DE1056, "NVS 4200M" },
862{ 0x10DE1057, "NVS 4200M" },
863// 1060 - 106F
864// 1070 - 107F
865{ 0x10DE107F, "NVIDIA GF119-ES" },
866// 1080 - 108F
867{ 0x10DE1080, "GeForce GTX 580" },
868{ 0x10DE1081, "GeForce GTX 570" },
869{ 0x10DE1082, "GeForce GTX 560 Ti" },
870{ 0x10DE1083, "D13U" },
871{ 0x10DE1084, "GeForce GTX 560" },
872{ 0x10DE1086, "GeForce GTX 570" },
873{ 0x10DE1087, "GeForce GTX 560 Ti-448" },
874{ 0x10DE1088, "GeForce GTX 590" },
875{ 0x10DE1089, "GeForce GTX 580" },
876{ 0x10DE108B, "GeForce GTX 590" },
877// 1090 - 109F
878{ 0x10DE1091, "Tesla M2090" },
879{ 0x10DE1098, "D13U" },
880{ 0x10DE109A, "Quadro 5010M" },
881{ 0x10DE109B, "Quadro 7000" },
882// 10A0 - 10AF
883// 10B0 - 10BF
884// 10C0 - 10CF
885{ 0x10DE10C0, "GeForce 9300 GS" },
886{ 0x10DE10C3, "GeForce 8400 GS" },
887{ 0x10DE10C5, "GeForce 405" },
888// 10D0 - 10DF
889{ 0x10DE10D8, "NVS 300" },
890// 1200 -
891{ 0x10DE1200, "GeForce GTX 560 Ti" },
892{ 0x10DE1201, "GeForce GTX 560" },
893{ 0x10DE1241, "GeForce GT 545" },
894{ 0x10DE1243, "GeForce GT 545" },
895{ 0x10DE1244, "GeForce GTX 550 Ti" },
896{ 0x10DE1245, "GeForce GTS 450" },
897{ 0x10DE1251, "GeForce GTX 560M" },
898};
899
900static uint16_t swap16(uint16_t x)
901{
902return (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8));
903}
904
905static uint16_t read16(uint8_t *ptr, uint16_t offset)
906{
907uint8_t ret[2];
908
909ret[0] = ptr[offset+1];
910ret[1] = ptr[offset];
911
912return *((uint16_t*)&ret);
913}
914
915#if 0
916static uint32_t swap32(uint32_t x)
917{
918return ((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8 ) | ((x & 0x00FF0000) >> 8 ) | ((x & 0xFF000000) >> 24);
919}
920
921static uint8_tread8(uint8_t *ptr, uint16_t offset)
922{
923return ptr[offset];
924}
925
926static uint32_t read32(uint8_t *ptr, uint16_t offset)
927{
928uint8_t ret[4];
929
930ret[0] = ptr[offset+3];
931ret[1] = ptr[offset+2];
932ret[2] = ptr[offset+1];
933ret[3] = ptr[offset];
934
935return *((uint32_t*)&ret);
936}
937#endif
938
939static int patch_nvidia_rom(uint8_t *rom)
940{
941if (!rom || (rom[0] != 0x55 && rom[1] != 0xaa)) {
942printf("False ROM signature: 0x%02x%02x\n", rom[0], rom[1]);
943return PATCH_ROM_FAILED;
944}
945
946uint16_t dcbptr = swap16(read16(rom, 0x36));
947
948if (!dcbptr) {
949printf("no dcb table found\n");
950return PATCH_ROM_FAILED;
951}
952//else
953//printf("dcb table at offset 0x%04x\n", dcbptr);
954
955uint8_t *dcbtable = &rom[dcbptr];
956uint8_t dcbtable_version = dcbtable[0];
957uint8_t headerlength = 0;
958uint8_t numentries = 0;
959uint8_t recordlength = 0;
960
961if (dcbtable_version >= 0x20)
962{
963uint32_t sig;
964
965if (dcbtable_version >= 0x30)
966{
967headerlength = dcbtable[1];
968numentries = dcbtable[2];
969recordlength = dcbtable[3];
970
971sig = *(uint32_t *)&dcbtable[6];
972}
973else
974{
975sig = *(uint32_t *)&dcbtable[4];
976headerlength = 8;
977}
978
979if (sig != 0x4edcbdcb)
980{
981printf("Bad display config block signature (0x%8x)\n", sig); //Azi: issue #48
982return PATCH_ROM_FAILED;
983}
984}
985else if (dcbtable_version >= 0x14) /* some NV15/16, and NV11+ */
986{
987char sig[8] = { 0 };
988
989strncpy(sig, (char *)&dcbtable[-7], 7);
990recordlength = 10;
991
992if (strcmp(sig, "DEV_REC"))
993{
994printf("Bad Display Configuration Block signature (%s)\n", sig);
995return PATCH_ROM_FAILED;
996}
997}
998else
999{
1000printf("ERROR: dcbtable_version is 0x%X\n", dcbtable_version);
1001return PATCH_ROM_FAILED;
1002}
1003
1004if (numentries >= MAX_NUM_DCB_ENTRIES)
1005numentries = MAX_NUM_DCB_ENTRIES;
1006
1007uint8_t num_outputs = 0, i = 0;
1008
1009struct dcbentry
1010{
1011uint8_t type;
1012uint8_t index;
1013uint8_t *heads;
1014} entries[numentries];
1015
1016for (i = 0; i < numentries; i++)
1017{
1018uint32_t connection;
1019connection = *(uint32_t *)&dcbtable[headerlength + recordlength * i];
1020
1021/* Should we allow discontinuous DCBs? Certainly DCB I2C tables can be discontinuous */
1022if ((connection & 0x0000000f) == 0x0000000f) /* end of records */
1023continue;
1024if (connection == 0x00000000) /* seen on an NV11 with DCB v1.5 */
1025continue;
1026if ((connection & 0xf) == 0x6) /* we skip type 6 as it doesnt appear on macbook nvcaps */
1027continue;
1028
1029entries[num_outputs].type = connection & 0xf;
1030entries[num_outputs].index = num_outputs;
1031entries[num_outputs++].heads = (uint8_t*)&(dcbtable[(headerlength + recordlength * i) + 1]);
1032}
1033
1034int has_lvds = false;
1035uint8_t channel1 = 0, channel2 = 0;
1036
1037for (i = 0; i < num_outputs; i++)
1038{
1039if (entries[i].type == 3)
1040{
1041has_lvds = true;
1042//printf("found LVDS\n");
1043channel1 |= ( 0x1 << entries[i].index);
1044entries[i].type = TYPE_GROUPED;
1045}
1046}
1047
1048// if we have a LVDS output, we group the rest to the second channel
1049if (has_lvds)
1050{
1051for (i = 0; i < num_outputs; i++)
1052{
1053if (entries[i].type == TYPE_GROUPED)
1054continue;
1055
1056channel2 |= ( 0x1 << entries[i].index);
1057entries[i].type = TYPE_GROUPED;
1058}
1059}
1060else
1061{
1062int x;
1063// we loop twice as we need to generate two channels
1064for (x = 0; x <= 1; x++)
1065{
1066for (i=0; i<num_outputs; i++)
1067{
1068if (entries[i].type == TYPE_GROUPED)
1069continue;
1070// if type is TMDS, the prior output is ANALOG
1071// we always group ANALOG and TMDS
1072// if there is a TV output after TMDS, we group it to that channel as well
1073if (i && entries[i].type == 0x2)
1074{
1075switch (x)
1076{
1077case 0:
1078//printf("group channel 1\n");
1079channel1 |= ( 0x1 << entries[i].index);
1080entries[i].type = TYPE_GROUPED;
1081
1082if ( entries[i-1].type == 0x0 )
1083{
1084channel1 |= ( 0x1 << entries[i-1].index);
1085entries[i-1].type = TYPE_GROUPED;
1086}
1087// group TV as well if there is one
1088if ( ((i+1) < num_outputs) && (entries[i+1].type == 0x1) )
1089{
1090//printf("group tv1\n");
1091channel1 |= ( 0x1 << entries[i+1].index);
1092entries[i+1].type = TYPE_GROUPED;
1093}
1094break;
1095
1096case 1:
1097//printf("group channel 2 : %d\n", i);
1098channel2 |= ( 0x1 << entries[i].index);
1099entries[i].type = TYPE_GROUPED;
1100
1101if ( entries[i - 1].type == 0x0 )
1102{
1103channel2 |= ( 0x1 << entries[i-1].index);
1104entries[i-1].type = TYPE_GROUPED;
1105}
1106// group TV as well if there is one
1107if ( ((i+1) < num_outputs) && (entries[i+1].type == 0x1) )
1108{
1109//printf("group tv2\n");
1110channel2 |= ( 0x1 << entries[i+1].index);
1111entries[i+1].type = TYPE_GROUPED;
1112}
1113break;
1114}
1115break;
1116}
1117}
1118}
1119}
1120
1121// if we have left ungrouped outputs merge them to the empty channel
1122uint8_t *togroup;// = (channel1 ? (channel2 ? NULL : &channel2) : &channel1);
1123togroup = &channel2;
1124
1125for (i = 0; i < num_outputs; i++)
1126{
1127if (entries[i].type != TYPE_GROUPED)
1128{
1129//printf("%d not grouped\n", i);
1130if (togroup)
1131{
1132*togroup |= ( 0x1 << entries[i].index);
1133}
1134entries[i].type = TYPE_GROUPED;
1135}
1136}
1137
1138if (channel1 > channel2)
1139{
1140uint8_t buff = channel1;
1141channel1 = channel2;
1142channel2 = buff;
1143}
1144
1145default_NVCAP[6] = channel1;
1146default_NVCAP[8] = channel2;
1147
1148// patching HEADS
1149for (i = 0; i < num_outputs; i++)
1150{
1151if (channel1 & (1 << i))
1152{
1153*entries[i].heads = 1;
1154}
1155else if(channel2 & (1 << i))
1156{
1157*entries[i].heads = 2;
1158}
1159}
1160return (has_lvds ? PATCH_ROM_SUCCESS_HAS_LVDS : PATCH_ROM_SUCCESS);
1161}
1162
1163static char *get_nvidia_model(uint32_t id)
1164{
1165int i;
1166
1167for (i = 1; i < (sizeof(NVKnownChipsets) / sizeof(NVKnownChipsets[0])); i++) {
1168if (NVKnownChipsets[i].device == id)
1169{
1170return NVKnownChipsets[i].name;
1171}
1172}
1173return NVKnownChipsets[0].name;
1174}
1175
1176static uint32_t load_nvidia_bios_file(const char *filename, uint8_t *buf, int bufsize)
1177{
1178int fd;
1179int size;
1180
1181if ((fd = open_bvdev("bt(0,0)", filename, 0)) < 0)
1182{
1183return 0;
1184}
1185
1186size = file_size(fd);
1187
1188if (size > bufsize)
1189{
1190printf("Filesize of %s is bigger than expected! Truncating to 0x%x Bytes!\n",
1191filename, bufsize);
1192size = bufsize;
1193}
1194size = read(fd, (char *)buf, size);
1195close(fd);
1196
1197return size > 0 ? size : 0;
1198}
1199
1200static int devprop_add_nvidia_template(struct DevPropDevice *device)
1201{
1202char tmp[16];
1203
1204if (!device)
1205return 0;
1206
1207if (!DP_ADD_TEMP_VAL(device, nvidia_compatible_0))
1208return 0;
1209if (!DP_ADD_TEMP_VAL(device, nvidia_device_type_0))
1210return 0;
1211if (!DP_ADD_TEMP_VAL(device, nvidia_name_0))
1212return 0;
1213if (!DP_ADD_TEMP_VAL(device, nvidia_compatible_1))
1214return 0;
1215if (!DP_ADD_TEMP_VAL(device, nvidia_device_type_1))
1216return 0;
1217if (!DP_ADD_TEMP_VAL(device, nvidia_name_1))
1218return 0;
1219if (!DP_ADD_TEMP_VAL(device, nvidia_device_type))
1220return 0;
1221
1222// Rek : Dont use sprintf return, it does not WORK !! our custom sprintf() always return 0!
1223// len = sprintf(tmp, "Slot-%x", devices_number);
1224sprintf(tmp, "Slot-%x",devices_number);
1225devprop_add_value(device, "AAPL,slot-name", (uint8_t *) tmp, strlen(tmp));
1226devices_number++;
1227
1228return 1;
1229}
1230
1231int hex2bin(const char *hex, uint8_t *bin, int len)
1232{
1233char*p;
1234inti;
1235charbuf[3];
1236
1237if (hex == NULL || bin == NULL || len <= 0 || strlen(hex) != len * 2) {
1238printf("[ERROR] bin2hex input error\n");
1239return -1;
1240}
1241
1242buf[2] = '\0';
1243p = (char *) hex;
1244
1245for (i = 0; i < len; i++)
1246{
1247if (p[0] == '\0' || p[1] == '\0' || !isxdigit(p[0]) || !isxdigit(p[1])) {
1248printf("[ERROR] bin2hex '%s' syntax error\n", hex);
1249return -2;
1250}
1251buf[0] = *p++;
1252buf[1] = *p++;
1253bin[i] = (unsigned char) strtoul(buf, NULL, 16);
1254}
1255return 0;
1256}
1257
1258unsigned long long mem_detect(volatile uint8_t *regs, uint8_t nvCardType, pci_dt_t *nvda_dev)
1259{
1260unsigned long long vram_size = 0;
1261
1262if (nvCardType < NV_ARCH_50)
1263{
1264vram_size = REG32(NV04_PFB_FIFO_DATA);
1265vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
1266}
1267else if (nvCardType < NV_ARCH_C0)
1268{
1269vram_size = REG32(NV04_PFB_FIFO_DATA);
1270vram_size |= (vram_size & 0xff) << 32;
1271vram_size &= 0xffffffff00ll;
1272}
1273else // >= NV_ARCH_C0
1274{
1275vram_size = REG32(NVC0_MEM_CTRLR_RAM_AMOUNT) << 20;
1276vram_size *= REG32(NVC0_MEM_CTRLR_COUNT);
1277}
1278
1279// Workaround for 9600M GT, GT 210/420/430/440 & GT 525M
1280switch (nvda_dev->device_id)
1281{
1282case 0x0649: vram_size = 512*1024*1024; break;// 9600M GT
1283case 0x0A65: vram_size = 1024*1024*1024; break; // GT 210
1284case 0x0DE0: vram_size = 1024*1024*1024; break; // GT 440
1285case 0x0DE1: vram_size = 1024*1024*1024; break; // GT 430
1286case 0x0DE2: vram_size = 1024*1024*1024; break; // GT 420
1287case 0x0DEC: vram_size = 1024*1024*1024; break; // GT 525M 0DEC
1288case 0x0DF5: vram_size = 1024*1024*1024; break; // GT 525M 0DF5
1289default: break;
1290}
1291
1292return vram_size;
1293}
1294
1295bool setup_nvidia_devprop(pci_dt_t *nvda_dev)
1296{
1297struct DevPropDevice*device;
1298char*devicepath;
1299option_rom_pci_header_t *rom_pci_header;
1300volatile uint8_t*regs;
1301uint8_t*rom;
1302uint8_t*nvRom;
1303uint8_tnvCardType;
1304unsigned long longvideoRam;
1305uint32_tnvBiosOveride;
1306uint32_tbar[7];
1307uint32_tboot_display;
1308intnvPatch;
1309intlen;
1310charbiosVersion[32];
1311charnvFilename[32];
1312charkNVCAP[12];
1313char*model;
1314const char*value;
1315booldoit;
1316
1317devicepath = get_pci_dev_path(nvda_dev);
1318bar[0] = pci_config_read32(nvda_dev->dev.addr, 0x10 );
1319regs = (uint8_t *) (bar[0] & ~0x0f);
1320
1321// get card type
1322nvCardType = (REG32(0) >> 20) & 0x1ff;
1323
1324// Amount of VRAM in kilobytes
1325videoRam = mem_detect(regs, nvCardType, nvda_dev);
1326model = get_nvidia_model((nvda_dev->vendor_id << 16) | nvda_dev->device_id);
1327
1328verbose("nVidia %s %dMB NV%02x [%04x:%04x] :: %s\n",
1329model, (uint32_t)(videoRam / 1024 / 1024),
1330(REG32(0) >> 20) & 0x1ff, nvda_dev->vendor_id, nvda_dev->device_id,
1331devicepath);
1332
1333rom = malloc(NVIDIA_ROM_SIZE);
1334sprintf(nvFilename, "/Extra/%04x_%04x.rom", (uint16_t)nvda_dev->vendor_id,
1335(uint16_t)nvda_dev->device_id);
1336
1337if (getBoolForKey(kUseNvidiaROM, &doit, &bootInfo->chameleonConfig) && doit)
1338{
1339verbose("Looking for nvidia video bios file %s\n", nvFilename);
1340nvBiosOveride = load_nvidia_bios_file(nvFilename, rom, NVIDIA_ROM_SIZE);
1341
1342if (nvBiosOveride > 0)
1343{
1344verbose("Using nVidia Video BIOS File %s (%d Bytes)\n", nvFilename, nvBiosOveride);
1345DBG("%s Signature 0x%02x%02x %d bytes\n", nvFilename, rom[0], rom[1], nvBiosOveride);
1346}
1347else
1348{
1349printf("ERROR: unable to open nVidia Video BIOS File %s\n", nvFilename);
1350return false;
1351}
1352}
1353else
1354{
1355// Otherwise read bios from card
1356nvBiosOveride = 0;
1357
1358// TODO: we should really check for the signature before copying the rom, i think.
1359
1360// PRAMIN first
1361nvRom = (uint8_t*)&regs[NV_PRAMIN_OFFSET];
1362bcopy((uint32_t *)nvRom, rom, NVIDIA_ROM_SIZE);
1363
1364// Valid Signature ?
1365if (rom[0] != 0x55 && rom[1] != 0xaa)
1366{
1367// PROM next
1368// Enable PROM access
1369(REG32(NV_PBUS_PCI_NV_20)) = NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED;
1370
1371nvRom = (uint8_t*)&regs[NV_PROM_OFFSET];
1372bcopy((uint8_t *)nvRom, rom, NVIDIA_ROM_SIZE);
1373
1374// disable PROM access
1375(REG32(NV_PBUS_PCI_NV_20)) = NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED;
1376
1377// Valid Signature ?
1378if (rom[0] != 0x55 && rom[1] != 0xaa)
1379{
1380// 0xC0000 last
1381bcopy((char *)0xc0000, rom, NVIDIA_ROM_SIZE);
1382
1383// Valid Signature ?
1384if (rom[0] != 0x55 && rom[1] != 0xaa)
1385{
1386printf("ERROR: Unable to locate nVidia Video BIOS\n");
1387return false;
1388}
1389else
1390{
1391DBG("ROM Address 0x%x Signature 0x%02x%02x\n", nvRom, rom[0], rom[1]);
1392}
1393}
1394else
1395{
1396DBG("PROM Address 0x%x Signature 0x%02x%02x\n", nvRom, rom[0], rom[1]);
1397}
1398}
1399else
1400{
1401DBG("PRAM Address 0x%x Signature 0x%02x%02x\n", nvRom, rom[0], rom[1]);
1402}
1403}
1404
1405if ((nvPatch = patch_nvidia_rom(rom)) == PATCH_ROM_FAILED) {
1406printf("ERROR: nVidia ROM Patching Failed!\n");
1407//return false;
1408}
1409
1410rom_pci_header = (option_rom_pci_header_t*)(rom + *(uint16_t *)&rom[24]);
1411
1412// check for 'PCIR' sig
1413if (rom_pci_header->signature == 0x50434952)
1414{
1415if (rom_pci_header->device_id != nvda_dev->device_id)
1416{
1417// Get Model from the OpROM
1418model = get_nvidia_model((rom_pci_header->vendor_id << 16) | rom_pci_header->device_id);
1419}
1420else
1421{
1422printf("nVidia incorrect PCI ROM signature: 0x%x\n", rom_pci_header->signature);
1423}
1424}
1425
1426if (!string) {
1427string = devprop_create_string();
1428}
1429device = devprop_add_device(string, devicepath);
1430
1431/* FIXME: for primary graphics card only */
1432boot_display = 1;
1433devprop_add_value(device, "@0,AAPL,boot-display", (uint8_t*)&boot_display, 4);
1434
1435if (nvPatch == PATCH_ROM_SUCCESS_HAS_LVDS) {
1436uint8_t built_in = 0x01;
1437devprop_add_value(device, "@0,built-in", &built_in, 1);
1438}
1439
1440// get bios version
1441const int MAX_BIOS_VERSION_LENGTH = 32;
1442char* version_str = (char*)malloc(MAX_BIOS_VERSION_LENGTH);
1443
1444memset(version_str, 0, MAX_BIOS_VERSION_LENGTH);
1445
1446int i, version_start;
1447int crlf_count = 0;
1448
1449// only search the first 384 bytes
1450for (i = 0; i < 0x180; i++)
1451{
1452if (rom[i] == 0x0D && rom[i+1] == 0x0A)
1453{
1454crlf_count++;
1455// second 0x0D0A was found, extract bios version
1456if (crlf_count == 2)
1457{
1458if (rom[i-1] == 0x20) i--; // strip last " "
1459
1460for (version_start = i; version_start > (i-MAX_BIOS_VERSION_LENGTH); version_start--)
1461{
1462// find start
1463if (rom[version_start] == 0x00)
1464{
1465version_start++;
1466
1467// strip "Version "
1468if (strncmp((const char*)rom+version_start, "Version ", 8) == 0)
1469{
1470version_start += 8;
1471}
1472
1473strncpy(version_str, (const char*)rom+version_start, i-version_start);
1474break;
1475}
1476}
1477break;
1478}
1479}
1480}
1481
1482sprintf(biosVersion, "%s", (nvBiosOveride > 0) ? nvFilename : version_str);
1483sprintf(kNVCAP, "NVCAP_%04x", nvda_dev->device_id);
1484
1485if (getValueForKey(kNVCAP, &value, &len, &bootInfo->chameleonConfig) && len == NVCAP_LEN * 2)
1486{
1487uint8_t new_NVCAP[NVCAP_LEN];
1488
1489if (hex2bin(value, new_NVCAP, NVCAP_LEN) == 0)
1490{
1491verbose("Using user supplied NVCAP for %s :: %s\n", model, devicepath);
1492memcpy(default_NVCAP, new_NVCAP, NVCAP_LEN);
1493}
1494}
1495
1496if (getValueForKey(kDcfg0, &value, &len, &bootInfo->chameleonConfig) && len == DCFG0_LEN * 2)
1497{
1498uint8_t new_dcfg0[DCFG0_LEN];
1499
1500if (hex2bin(value, new_dcfg0, DCFG0_LEN) == 0)
1501{
1502memcpy(default_dcfg_0, new_dcfg0, DCFG0_LEN);
1503
1504verbose("Using user supplied @0,display-cfg\n");
1505printf("@0,display-cfg: %02x%02x%02x%02x\n",
1506 default_dcfg_0[0], default_dcfg_0[1], default_dcfg_0[2], default_dcfg_0[3]);
1507}
1508}
1509
1510if (getValueForKey(kDcfg1, &value, &len, &bootInfo->chameleonConfig) && len == DCFG1_LEN * 2)
1511{
1512uint8_t new_dcfg1[DCFG1_LEN];
1513
1514if (hex2bin(value, new_dcfg1, DCFG1_LEN) == 0)
1515{
1516memcpy(default_dcfg_1, new_dcfg1, DCFG1_LEN);
1517
1518verbose("Using user supplied @1,display-cfg\n");
1519printf("@1,display-cfg: %02x%02x%02x%02x\n",
1520 default_dcfg_1[0], default_dcfg_1[1], default_dcfg_1[2], default_dcfg_1[3]);
1521}
1522}
1523
1524#if DEBUG_NVCAP
1525printf("NVCAP: %02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x%02x%02x\n",
1526default_NVCAP[0], default_NVCAP[1], default_NVCAP[2], default_NVCAP[3],
1527default_NVCAP[4], default_NVCAP[5], default_NVCAP[6], default_NVCAP[7],
1528default_NVCAP[8], default_NVCAP[9], default_NVCAP[10], default_NVCAP[11],
1529default_NVCAP[12], default_NVCAP[13], default_NVCAP[14], default_NVCAP[15],
1530default_NVCAP[16], default_NVCAP[17], default_NVCAP[18], default_NVCAP[19]);
1531#endif
1532
1533devprop_add_nvidia_template(device);
1534devprop_add_value(device, "NVCAP", default_NVCAP, NVCAP_LEN);
1535devprop_add_value(device, "VRAM,totalsize", (uint8_t*)&videoRam, 4);
1536devprop_add_value(device, "model", (uint8_t*)model, strlen(model) + 1);
1537devprop_add_value(device, "rom-revision", (uint8_t*)biosVersion, strlen(biosVersion) + 1);
1538 //devprop_add_value(device, "@1,connector-type", connector_type_1, 4); // fixme
1539 //devprop_add_value(device, "@0,display-cfg", display_cfg_0, 4);
1540 //devprop_add_value(device, "@1,display-cfg", display_cfg_1, 4);
1541devprop_add_value(device, "NVPM", default_NVPM, NVPM_LEN);
1542devprop_add_value(device, "@0,display-cfg", default_dcfg_0, DCFG0_LEN);
1543devprop_add_value(device, "@1,display-cfg", default_dcfg_1, DCFG1_LEN);
1544
1545//add HDMI Audio back to nvidia
1546//http://forge.voodooprojects.org/p/chameleon/issues/67/
1547//uint8_t connector_type_1[]= {0x00, 0x08, 0x00, 0x00};
1548//devprop_add_value(device, "@1,connector-type",connector_type_1, 4);
1549//end Nvidia HDMI Audio
1550
1551if (getBoolForKey(kVBIOS, &doit, &bootInfo->chameleonConfig) && doit)
1552{
1553devprop_add_value(device, "vbios", rom, (nvBiosOveride > 0) ? nvBiosOveride : (rom[2] * 512));
1554}
1555
1556stringdata = malloc(sizeof(uint8_t) * string->length);
1557memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
1558stringlength = string->length;
1559
1560return true;
1561}
1562

Archive Download this file

Revision: 1836