Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/modules/GraphicsEnabler/nvidia.c

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

Archive Download this file

Revision: 1931