Chameleon

Chameleon Svn Source Tree

Root/trunk/i386/libsaio/device_inject.c

1/*
2 *Copyright 2009 Jasmin Fazlic All rights reserved.
3 */
4/*
5 *Cleaned and merged by iNDi
6 */
7
8#include "config.h"
9#include "libsaio.h"
10#include "boot.h"
11#include "bootstruct.h"
12#include "pci.h"
13#include "pci_root.h"
14#include "device_inject.h"
15#include "convert.h"
16
17#if DEBUG_INJECT
18#define DBG(x...)printf(x)
19#else
20#define DBG(x...)msglog(x)
21#endif
22
23uint32_tdevices_number= 1; // nvidia.c
24uint32_tlocation_number= 1; // networking.c
25
26DevPropString*string= NULL;
27uint8_t*stringdata= NULL;
28uint32_tstringlength= 0;
29
30char *efi_inject_get_devprop_string(uint32_t *len)
31{
32if(string) {
33*len = string->length;
34return devprop_generate_string(string);
35}
36verbose("efi_inject_get_devprop_string NULL trying stringdata\n");
37return NULL;
38}
39
40void setupDeviceProperties(Node *node)
41{
42 const char *val;
43 uint8_t *binStr;
44 int cnt, cnt2;
45
46 static char DEVICE_PROPERTIES_PROP[] = "device-properties";
47
48 /* Generate devprop string.
49 */
50 uint32_t strlength;
51 char *string = efi_inject_get_devprop_string(&strlength);
52
53 /* Use the static "device-properties" boot config key contents if available,
54 * otheriwse use the generated one.
55 */
56if (!getValueForKey(kDeviceProperties, &val, &cnt, &bootInfo->chameleonConfig) && string)
57{
58val = (const char *)string;
59cnt = strlength * 2;
60}
61
62if (cnt > 1)
63{
64binStr = convertHexStr2Binary(val, &cnt2);
65if (cnt2 > 0)
66{
67DT__AddProperty(node, DEVICE_PROPERTIES_PROP, cnt2, binStr);
68DBG("Adding device-properties string to DT\n");
69}
70}
71}
72
73DevPropString *devprop_create_string(void)
74{
75string = (DevPropString *)malloc(sizeof(DevPropString));
76
77if(string == NULL)
78{
79return NULL;
80}
81
82memset(string, 0, sizeof(DevPropString));
83string->length = 12;
84string->WHAT2 = 0x01000000;
85return string;
86}
87
88DevPropDevice *devprop_add_device(DevPropString *string, char *path)
89{
90DevPropDevice*device= NULL;
91const charpciroot_string[]= "PciRoot(0x";
92const charpci_device_string[]= "Pci(0x";
93
94if (string == NULL || path == NULL)
95{
96printf("ERROR null device path\n");
97return NULL;
98}
99
100if (strncmp(path, pciroot_string, strlen(pciroot_string)))
101{
102printf("ERROR parsing device path\n");
103return NULL;
104}
105
106if (!(device = malloc(sizeof(DevPropDevice))))
107{
108printf("ERROR malloc failed\n");
109return NULL;
110}
111
112memset(device, 0, sizeof(DevPropDevice));
113device->acpi_dev_path._UID = getPciRootUID();
114
115int numpaths = 0;
116intx, curr = 0;
117charbuff[] = "00";
118
119for (x = 0; x < strlen(path); x++)
120{
121if (!strncmp(&path[x], pci_device_string, strlen(pci_device_string)))
122{
123x+=strlen(pci_device_string);
124curr=x;
125while(path[++x] != ',');
126if(x-curr == 2)
127{
128sprintf(buff, "%c%c", path[curr], path[curr+1]);
129}
130else if(x-curr == 1)
131{
132sprintf(buff, "%c", path[curr]);
133}
134else
135{
136printf("ERROR parsing device path\n");
137numpaths = 0;
138break;
139}
140device->pci_dev_path[numpaths].device =ascii_hex_to_int(buff);
141
142x += 3; // 0x
143curr = x;
144while(path[++x] != ')');
145if(x-curr == 2)
146{
147sprintf(buff, "%c%c", path[curr], path[curr+1]);
148}
149else if(x-curr == 1)
150{
151sprintf(buff, "%c", path[curr]);
152}
153else
154{
155printf("ERROR parsing device path\n");
156numpaths = 0;
157break;
158}
159device->pci_dev_path[numpaths].function = ascii_hex_to_int(buff); // TODO: find dev from char *path
160
161numpaths++;
162}
163}
164
165if(!numpaths)
166{
167free(device);
168return NULL;
169}
170
171device->numentries = 0x00;
172
173device->acpi_dev_path.length= 0x0c;
174device->acpi_dev_path.type= 0x02;
175device->acpi_dev_path.subtype= 0x01;
176device->acpi_dev_path._HID= 0xd041030a; // 0x0a0341d0
177
178device->num_pci_devpaths = numpaths;
179device->length = 24 + (6*numpaths);
180
181inti;
182
183for(i = 0; i < numpaths; i++)
184{
185device->pci_dev_path[i].length = 0x06;
186device->pci_dev_path[i].type = 0x01;
187device->pci_dev_path[i].subtype = 0x01;
188}
189
190device->path_end.length = 0x04;
191device->path_end.type = 0x7f;
192device->path_end.subtype = 0xff;
193
194device->string = string;
195device->data = NULL;
196
197if(!string->entries)
198{
199if (!(string->entries = (struct DevPropDevice**) malloc(sizeof(device) * DEV_PROP_DEVICE_MAX_ENTRIES)))
200{
201free(device);
202return NULL;
203}
204}
205
206/* FIXME: probably needs bounds checking, as well as error handling in event of malloc failure */
207string->length += device->length;
208string->entries[string->numentries++] = (DevPropDevice*)malloc(sizeof(device));
209string->entries[string->numentries-1] = device;
210
211return device;
212}
213
214int devprop_add_value(DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
215{
216
217if(!nm || !vl || !len)
218{
219return 0;
220}
221uint32_t length= ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
222uint8_t *data= (uint8_t*)malloc(length);
223
224if(!data)
225{
226return 0;
227}
228
229memset(data, 0, length);
230uint32_t off = 0;
231data[off+1] = (uint8_t)(((strlen(nm) * 2) + 6) >> 8);
232data[off] = ((strlen(nm) * 2) + 6) & 0x00FF;
233
234off += 4;
235uint32_t i=0, l = strlen(nm);
236for(i = 0 ; i < l ; i++, off += 2)
237{
238data[off] = *nm++;
239}
240
241off += 2;
242l = len;
243uint32_t *datalength = (uint32_t*)&data[off];
244*datalength = (uint32_t)(l + 4);
245off += 4;
246for(i = 0 ; i < l ; i++, off++)
247{
248data[off] = *vl++;
249}
250
251uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
252
253uint8_t *newdata = (uint8_t*)malloc((length + offset));
254if(!newdata)
255{
256return 0;
257}
258
259if(device->data)
260{
261if(offset > 1)
262{
263memcpy(newdata, device->data, offset);
264}
265}
266
267memcpy(newdata + offset, data, length);
268
269device->length += length;
270device->string->length += length;
271device->numentries++;
272
273if(!device->data)
274{
275device->data = (uint8_t *)malloc(sizeof(uint8_t));
276}
277else
278{
279free(device->data);
280}
281
282free(data);
283device->data = newdata;
284
285return 1;
286}
287
288// devprop_generate_string optimized by cparm
289char *devprop_generate_string(DevPropString *string)
290{
291int len = ((string->length * 2) + 1);
292char *buffer = (char *)malloc(len);
293char *ptr = buffer;
294
295if(!buffer)
296{
297return NULL;
298}
299
300snprintf(buffer, len, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2,
301dp_swap16(string->numentries), string->WHAT3);
302buffer += 24;
303len -= 24;
304int i = 0, x = 0;
305
306while(i < string->numentries)
307{
308 if (!(i < DEV_PROP_DEVICE_MAX_ENTRIES))
309{
310 break;
311 }
312
313 if(!len)
314{
315 break;
316 }
317
318snprintf(buffer, len, "%08x%04x%04x", dp_swap32(string->entries[i]->length),
319dp_swap16(string->entries[i]->numentries), string->entries[i]->WHAT2);
320
321buffer += 16;
322len -= 16;
323snprintf(buffer, len, "%02x%02x%04x%08x%08x", string->entries[i]->acpi_dev_path.type,
324string->entries[i]->acpi_dev_path.subtype,
325dp_swap16(string->entries[i]->acpi_dev_path.length),
326string->entries[i]->acpi_dev_path._HID,
327dp_swap32(string->entries[i]->acpi_dev_path._UID));
328
329buffer += 24;
330len -= 24;
331for(x = 0;x < string->entries[i]->num_pci_devpaths; x++)
332{
333if(!len)
334{
335break;
336}
337snprintf(buffer, len, "%02x%02x%04x%02x%02x", string->entries[i]->pci_dev_path[x].type,
338string->entries[i]->pci_dev_path[x].subtype,
339dp_swap16(string->entries[i]->pci_dev_path[x].length),
340string->entries[i]->pci_dev_path[x].function,
341string->entries[i]->pci_dev_path[x].device);
342buffer += 12;
343len -= 12;
344}
345
346if(!len)
347{
348break;
349}
350
351snprintf(buffer, len, "%02x%02x%04x", string->entries[i]->path_end.type,
352string->entries[i]->path_end.subtype,
353dp_swap16(string->entries[i]->path_end.length));
354
355buffer += 8;
356len -= 8;
357uint8_t *dataptr = string->entries[i]->data;
358for(x = 0; (uint32_t)x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++)
359{
360if(!len)
361{
362break;
363}
364snprintf(buffer, len, "%02x", *dataptr++);
365buffer += 2;
366len -= 2;
367}
368i++;
369}
370return ptr;
371}
372
373void devprop_free_string(DevPropString *string)
374{
375
376if(!string) {
377return;
378}
379
380int i;
381for(i = 0; i < string->numentries; i++)
382{
383if(string->entries[i])
384{
385if(string->entries[i]->data)
386{
387free(string->entries[i]->data);
388string->entries[i]->data = NULL;
389}
390free(string->entries[i]);
391string->entries[i] = NULL;
392}
393}
394
395free(string);
396string = NULL;
397}
398
399/* ======================================================= */
400
401/* a fine place for this code */
402
403// (devprop_add_network_template) and (setup_eth_builtin) moved to i386/libsaio/networking.c
404

Archive Download this file

Revision: 2858