Chameleon

Chameleon Svn Source Tree

Root/tags/2.0/i386/libsaio/nvidia.c

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

Archive Download this file

Revision: 1808