Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 1836