1 | /*␊ |
2 | * Copyright (c) 2012 cparm <armelcadetpetit@gmail.com>. All rights reserved.␊ |
3 | *␊ |
4 | */␊ |
5 | ␊ |
6 | #include "libsaio.h"␊ |
7 | #include "bootstruct.h"␊ |
8 | #include "xml.h"␊ |
9 | #include "gfx_helper.h"␊ |
10 | #include "pci.h"␊ |
11 | #include "nvidia.h"␊ |
12 | ␊ |
13 | /*␊ |
14 | ␊ |
15 | NVIDIA and ATI card injection usage e.g (to be placed in the boot.plist): ␊ |
16 | ␊ |
17 | <key>NVIDIA</key>␊ |
18 | ␉<array>␊ |
19 | ␉␉<dict>␊ |
20 | ␉␉␉<key>Chipset Name</key>␊ |
21 | ␉␉␉<string>Quadro FX 380</string>␊ |
22 | ␉␉␉<key>IOPCIPrimaryMatch</key>␊ |
23 | ␉␉␉<string>0x10DE0658</string>␊ |
24 | ␉␉␉<key>VRam Size</key>␊ |
25 | ␉␉␉<string>256</string>␊ |
26 | ␉␉</dict>␊ |
27 | ␉␉<dict>␊ |
28 | ␉␉␉<key>Chipset Name</key>␊ |
29 | ␉␉␉<string>YOUR_CARD_NAME</string>␊ |
30 | ␉␉␉<key>IOPCIPrimaryMatch</key>␊ |
31 | ␉␉␉<string>YOUR_CARD_ID</string>␊ |
32 | ␉␉␉<key>IOPCISubDevId</key>␊ |
33 | ␉␉␉<string>YOUR_CARD_SUB_ID(if necessary)</string>␊ |
34 | ␉␉␉<key>VRam Size</key>␊ |
35 | ␉␉␉<string>YOUR_CARD_VRAM_SIZE</string>␊ |
36 | ␉␉</dict>␊ |
37 | ␉␉<dict>␊ |
38 | ␉␉␉<key>Chipset Name</key>␊ |
39 | ␉␉␉<string>YOUR_SECOND_CARD_NAME</string>␊ |
40 | ␉␉␉<key>IOPCIPrimaryMatch</key>␊ |
41 | ␉␉␉<string>YOUR_SECOND_CARD_ID</string>␊ |
42 | ␉␉␉<key>IOPCISubDevId</key>␊ |
43 | ␉␉␉<string>YOUR_SECOND_CARD_SUB_ID(if necessary)</string>␊ |
44 | ␉␉␉<key>VRam Size</key>␊ |
45 | ␉␉␉<string>YOUR_SECOND_CARD_VRAM_SIZE</string>␊ |
46 | ␉␉</dict>␊ |
47 | .␊ |
48 | .␊ |
49 | .␊ |
50 | .␊ |
51 | ␉</array>␊ |
52 | ␊ |
53 | <key>ATI</key>␊ |
54 | ␉<array>␊ |
55 | ␉␉<dict>␊ |
56 | ␉␉␉<key>Chipset Name</key>␊ |
57 | ␉␉␉<string>ATI RADEON HD6670</string>␊ |
58 | ␉␉␉<key>IOPCIPrimaryMatch</key>␊ |
59 | ␉␉␉<string>0x10026758</string>␊ |
60 | ␉␉␉<key>VRam Size</key>␊ |
61 | ␉␉␉<string>2048</string>␊ |
62 | ␉␉</dict>␊ |
63 | ␉</array>␊ |
64 | ␊ |
65 | */␊ |
66 | ␊ |
67 | cardList_t *cardList = NULL;␊ |
68 | ␊ |
69 | void add_card(char *model, uint32_t id, uint32_t subid, uint64_t videoRam)␊ |
70 | {␊ |
71 | ␉␊ |
72 | ␉cardList_t *new_card = malloc(sizeof(cardList_t));␊ |
73 | ␉if (new_card)␊ |
74 | ␉{␉␊ |
75 | ␉␉new_card->next = cardList;␊ |
76 | ␉␉␊ |
77 | ␉␉cardList = new_card;␊ |
78 | ␉␉␊ |
79 | ␉␉new_card->id␉␉= id;␊ |
80 | ␉␉new_card->subid␉␉= subid;␊ |
81 | ␉␉new_card->videoRam␉= videoRam;␊ |
82 | ␉␉new_card->model␉␉= model;␊ |
83 | ␉}␉␊ |
84 | }␊ |
85 | ␊ |
86 | cardList_t *FindCardWithIds(uint32_t id, uint32_t subid)␊ |
87 | {␊ |
88 | ␉cardList_t *entry = cardList;␊ |
89 | ␉while(entry)␊ |
90 | ␉{␉␉␊ |
91 | ␉␉if((entry->id == id) && (entry->subid == subid))␊ |
92 | ␉␉{␊ |
93 | ␉␉␉return entry;␊ |
94 | ␉␉}␊ |
95 | ␉␉else␊ |
96 | ␉␉{␊ |
97 | ␉␉␉entry = entry->next;␊ |
98 | ␉␉} ␊ |
99 | ␉␉␊ |
100 | ␉}␊ |
101 | ␉␊ |
102 | ␉// LET A SECOND CHANCE by seaching only for the device-id␊ |
103 | ␉entry = cardList;␊ |
104 | ␉while(entry)␊ |
105 | ␉{␉␉␊ |
106 | ␉␉if(entry->id == id)␊ |
107 | ␉␉{␊ |
108 | ␉␉␉return entry;␊ |
109 | ␉␉}␊ |
110 | ␉␉else␊ |
111 | ␉␉{␊ |
112 | ␉␉␉entry = entry->next;␊ |
113 | ␉␉} ␊ |
114 | ␉␉␊ |
115 | ␉}␊ |
116 | ␉␊ |
117 | ␉return NULL;␊ |
118 | }␊ |
119 | ␊ |
120 | void fill_card_list(void) ␊ |
121 | {␊ |
122 | ␉unsigned int␉i, count;␊ |
123 | ␉TagPtr␉␉NVDIATag;␊ |
124 | ␉TagPtr␉␉ATITag;␊ |
125 | ␉char␉␉*model_name = NULL;␊ |
126 | ␉char␉␉*match_id = NULL;␊ |
127 | ␉char␉␉*sub_id = NULL;␊ |
128 | ␉char␉␉*vram_size = NULL;␊ |
129 | ␉uint32_t␉dev_id = 0;␊ |
130 | ␉uint32_t␉subdev_id = 0;␊ |
131 | ␉uint64_t␉VramSize = 0;␊ |
132 | ␊ |
133 | ␉if ((NVDIATag = XMLCastArray(XMLGetProperty(bootInfo->chameleonConfig.dictionary, (const char *)"NVIDIA"))))␊ |
134 | ␉{␊ |
135 | ␉␉count = XMLTagCount(NVDIATag);␊ |
136 | ␊ |
137 | ␉␉for (i=0; i<count; i++)␊ |
138 | ␉␉{␊ |
139 | ␉␉␉TagPtr element = XMLGetElement( NVDIATag, i );␊ |
140 | ␉␉␉if (element)␊ |
141 | ␉␉␉{␊ |
142 | ␉␉␉␉match_id = XMLCastString(XMLGetProperty(element, (const char*)"IOPCIPrimaryMatch")); //device-id␊ |
143 | ␉␉␉␉sub_id = XMLCastString(XMLGetProperty(element, (const char*)"IOPCISubDevId")); //sub device-id␊ |
144 | ␉␉␉␉model_name = XMLCastString(XMLGetProperty(element, (const char*)"Chipset Name"));␊ |
145 | ␉␉␉␉vram_size = XMLCastString(XMLGetProperty(element, (const char*)"VRam Size"));␊ |
146 | ␊ |
147 | ␉␉␉␉if (match_id)␊ |
148 | ␉␉␉␉{␊ |
149 | ␉␉␉␉␉dev_id = strtoul(match_id, NULL, 16);␊ |
150 | ␉␉␉␉}␊ |
151 | ␊ |
152 | ␉␉␉␉if (sub_id)␊ |
153 | ␉␉␉␉{␊ |
154 | ␉␉␉␉␉subdev_id = strtoul(sub_id, NULL, 16);␊ |
155 | ␉␉␉␉}␊ |
156 | ␊ |
157 | ␉␉␉␉if (vram_size)␊ |
158 | ␉␉␉␉{␊ |
159 | ␉␉␉␉␉VramSize = strtoul(vram_size, NULL, 10);␊ |
160 | ␉␉␉␉}␊ |
161 | ␊ |
162 | ␉␉␉␉add_card(model_name, dev_id, subdev_id, VramSize);␊ |
163 | ␉␉␉}␊ |
164 | ␉␉}␊ |
165 | ␉}␊ |
166 | ␊ |
167 | ␉if ((ATITag = XMLCastArray(XMLGetProperty(bootInfo->chameleonConfig.dictionary, (const char *)"ATI"))))␊ |
168 | ␉{␊ |
169 | ␉␉count = XMLTagCount(ATITag);␊ |
170 | ␊ |
171 | ␉␉for (i=0; i<count; i++)␊ |
172 | ␉␉{␊ |
173 | ␉␉␉TagPtr element = XMLGetElement( NVDIATag, i );␊ |
174 | ␉␉␉if (element)␊ |
175 | ␉␉␉{␊ |
176 | ␉␉␉␉match_id = XMLCastString(XMLGetProperty(element, (const char*)"IOPCIPrimaryMatch")); //device-id␊ |
177 | ␉␉␉␉sub_id = XMLCastString(XMLGetProperty(element, (const char*)"IOPCISubDevId")); //sub device-id␊ |
178 | ␉␉␉␉model_name = XMLCastString(XMLGetProperty(element, (const char*)"Chipset Name"));␊ |
179 | ␉␉␉␉vram_size = XMLCastString(XMLGetProperty(element, (const char*)"VRam Size"));␊ |
180 | ␊ |
181 | ␉␉␉␉if (match_id)␊ |
182 | ␉␉␉␉{␊ |
183 | ␉␉␉␉␉dev_id = strtoul(match_id, NULL, 16);␊ |
184 | ␉␉␉␉}␊ |
185 | ␊ |
186 | ␉␉␉␉if (sub_id)␊ |
187 | ␉␉␉␉{␊ |
188 | ␉␉␉␉␉subdev_id = strtoul(sub_id, NULL, 16);␊ |
189 | ␉␉␉␉}␊ |
190 | ␊ |
191 | ␉␉␉␉if (vram_size)␊ |
192 | ␉␉␉␉{␊ |
193 | ␉␉␉␉␉VramSize = strtoul(vram_size, NULL, 10);␊ |
194 | ␉␉␉␉}␊ |
195 | ␊ |
196 | ␉␉␉␉add_card(model_name, dev_id, subdev_id, VramSize);␊ |
197 | ␉␉␉}␊ |
198 | ␉␉}␊ |
199 | ␉}␊ |
200 | ␊ |
201 | }␊ |
202 | |