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

Archive Download this file

Revision: 1900