Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch_Modules/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 "libsaio.h"
9#include "boot.h"
10#include "bootstruct.h"
11#include "pci.h"
12#include "pci_root.h"
13#include "device_inject.h"
14#include "convert.h"
15
16#ifndef DEBUG_INJECT
17#define DEBUG_INJECT 0
18#endif
19
20#if DEBUG_INJECT
21#define DBG(x...)printf(x)
22#else
23#define DBG(x...)
24#endif
25
26uint32_t devices_number= 1;
27uint32_t onboard_number= 1; // TODO: increment the onboard-x(+1) value if the duallink option is true for nVidia and ATi (gfx and HDAU)
28uint32_t builtin_set= 0;
29DevPropString *string= NULL;
30uint8_t *stringdata= NULL;
31uint32_t stringlength= 0;
32
33char *efi_inject_get_devprop_string(uint32_t *len)
34{
35if(string)
36{
37*len = string->length;
38return devprop_generate_string(string);
39}
40verbose("efi_inject_get_devprop_string NULL trying stringdata\n");
41return NULL;
42}
43
44void setupDeviceProperties(Node *node)
45{
46 const char *val;
47 uint8_t *binStr;
48 int cnt, cnt2;
49
50 static char DEVICE_PROPERTIES_PROP[] = "device-properties";
51
52 /* Generate devprop string.
53 */
54 uint32_t strlength;
55 char *string = efi_inject_get_devprop_string(&strlength);
56
57 /* Use the static "device-properties" boot config key contents if available,
58 * otheriwse use the generated one.
59 */
60if (!getValueForKey(kDeviceProperties, &val, &cnt, &bootInfo->chameleonConfig) && string)
61{
62val = (const char*)string;
63cnt = strlength * 2;
64}
65
66if (cnt > 1)
67{
68binStr = convertHexStr2Binary(val, &cnt2);
69if (cnt2 > 0)
70{
71DT__AddProperty(node, DEVICE_PROPERTIES_PROP, cnt2, binStr);
72}
73}
74}
75
76DevPropString *devprop_create_string(void)
77{
78string = (struct DevPropString*)malloc(sizeof(struct DevPropString));
79
80if(string == NULL)
81{
82return NULL;
83}
84
85memset(string, 0, sizeof(struct DevPropString));
86string->length = 12;
87string->WHAT2 = 0x01000000;
88return string;
89}
90
91DevPropDevice *devprop_add_device(DevPropString *string, char *path)
92{
93DevPropDevice*device;
94const charpciroot_string[] = "PciRoot(0x";
95const charpci_device_string[] = "Pci(0x";
96
97if (string == NULL || path == NULL) {
98return NULL;
99}
100device = malloc(sizeof(DevPropDevice));
101if (!device)
102{
103return NULL;
104}
105if (strncmp(path, pciroot_string, strlen(pciroot_string)))
106{
107free(device);
108printf("ERROR parsing device path\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;
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;
196string->length += device->length;
197
198if(!string->entries)
199{
200if((string->entries = (DevPropDevice**)malloc(sizeof(device)*DEV_PROP_DEVICE_MAX_ENTRIES))== NULL)
201{
202printf("ERROR parsing device path 2\n");
203
204free(device);
205return 0;
206}
207}
208
209string->entries[string->numentries++] = (DevPropDevice*)malloc(sizeof(device));
210string->entries[string->numentries-1] = device;
211
212return device;
213}
214
215int devprop_add_value(DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
216{
217
218if(!nm || !vl || !len)
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] = ((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}
251
252uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
253
254uint8_t *newdata = (uint8_t*)malloc((length + offset));
255if(!newdata)
256{
257return 0;
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
288char *devprop_generate_string(DevPropString *string)
289{
290uint32_t len = string->length * 2;
291int i = 0;
292uint32_t x = 0;
293
294char *buffer = (char*)malloc(len +1);
295char *ptr = buffer;
296
297if(!buffer)
298{
299return NULL;
300}
301
302sprintf(buffer, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2,
303dp_swap16(string->numentries), string->WHAT3);
304buffer += 24;
305
306while(i < string->numentries)
307{
308sprintf(buffer, "%08x%04x%04x", dp_swap32(string->entries[i]->length),
309dp_swap16(string->entries[i]->numentries), string->entries[i]->WHAT2);
310
311buffer += 16;
312sprintf(buffer, "%02x%02x%04x%08x%08x", string->entries[i]->acpi_dev_path.type,
313string->entries[i]->acpi_dev_path.subtype,
314dp_swap16(string->entries[i]->acpi_dev_path.length),
315string->entries[i]->acpi_dev_path._HID,
316dp_swap32(string->entries[i]->acpi_dev_path._UID));
317
318buffer += 24;
319for(x = 0;x < string->entries[i]->num_pci_devpaths; x++)
320{
321sprintf(buffer, "%02x%02x%04x%02x%02x", string->entries[i]->pci_dev_path[x].type,
322string->entries[i]->pci_dev_path[x].subtype,
323dp_swap16(string->entries[i]->pci_dev_path[x].length),
324string->entries[i]->pci_dev_path[x].function,
325string->entries[i]->pci_dev_path[x].device);
326buffer += 12;
327}
328
329sprintf(buffer, "%02x%02x%04x", string->entries[i]->path_end.type,
330string->entries[i]->path_end.subtype,
331dp_swap16(string->entries[i]->path_end.length));
332
333buffer += 8;
334uint8_t *dataptr = string->entries[i]->data;
335for(x = 0; (uint32_t)x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++)
336{
337sprintf(buffer, "%02x", *dataptr++);
338buffer += 2;
339}
340i++;
341}
342return ptr;
343}
344
345void devprop_free_string(DevPropString *string)
346{
347
348if(!string)
349{
350return;
351}
352
353int i;
354for(i = 0; i < string->numentries; i++)
355{
356if(string->entries[i])
357{
358if(string->entries[i]->data)
359{
360free(string->entries[i]->data);
361string->entries[i]->data = NULL;
362}
363free(string->entries[i]);
364string->entries[i] = NULL;
365}
366}
367
368free(string);
369string = NULL;
370}
371
372/* ======================================================= */
373
374/* Converters */
375
376/*static int hexdigit(int c)
377{
378unsigned d;
379
380d = (unsigned)(c - '0');
381if (d < 10) return d;
382
383d = (unsigned)(c - 'a');
384if (d < 6) return d+10;
385
386d = (unsigned)(c - 'A');
387if (d < 6) return d+10;
388printf("[ERROR] hexdigit input error\n");
389return -1;
390}*/
391
392/*********************************************************************
393 * decodes a sequence of 'len' hexadecimal chars from 'hex' into *
394 * an integer. returns -1 in case of error (i.e. badly formed chars) *
395 *********************************************************************/
396static const long hextable[] = {
397 [0 ... 255] = -1, // bit aligned access into this table is considerably
398 ['0'] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // faster for most modern processors,
399 ['A'] = 10, 11, 12, 13, 14, 15, // for the space conscious, reduce to
400 ['a'] = 10, 11, 12, 13, 14, 15 // signed char.
401};
402
403int hex2dec(unsigned const char *hex) { //long... unsigned const char
404int ret = 0;
405while (*hex && ret >= 0) {
406ret = (ret << 4) | hextable[*hex++];
407}
408return ret;
409}
410
411/************************************************************************
412 * Encodes an integer 'val' into 'len' hexadecimal charaters into 'hex' *
413 ************************************************************************/
414//char int2hex(int val)
415
416
417/***********************************************************
418 * bin2hex creates hexadecimal presentation of binary data *
419 ***********************************************************/
420char *bin2hex(const uint8_t* bin, char* hex, int len)
421{
422int i;
423const char *hexc = "0123456789abcdef";
424for (i = 0; i < len; i++) {
425hex[i * 2] = hexc[(bin[i] >> 4) & 0xf];
426hex[i * 2 + 1] = hexc[bin[i] &0xf];
427}
428hex[i * 2] = '\0';
429return hex;
430}
431/* */
432
433/*******************************************************************
434 * Decodes a sequence of 'len' hexadecimal chars from 'hex' into *
435 * a binary. returns -1 in case of error (i.e. badly formed chars) *
436 *******************************************************************/
437int hex2bin(const char *hex, uint8_t *bin, int len)
438{
439char*p;
440inti;
441charbuf[3];
442
443if (hex == NULL || bin == NULL || len <= 0 || strlen(hex) != len * 2)
444{
445printf("[ERROR] bin2hex input error\n");
446return -1;
447}
448
449buf[2] = '\0';
450p = (char *) hex;
451
452for (i = 0; i < len; i++)
453{
454if (p[0] == '\0' || p[1] == '\0' || !isxdigit(p[0]) || !isxdigit(p[1]))
455{
456printf("[ERROR] bin2hex '%s' syntax error\n", hex);
457return -2;
458}
459buf[0] = *p++;
460buf[1] = *p++;
461bin[i] = (unsigned char) strtoul(buf, NULL, 16);
462}
463return 0;
464}
465
466/* ======================================================= */
467
468/* a fine place for this code */
469int devprop_add_network_template(DevPropDevice *device, uint16_t vendor_id)
470{
471uint8_t builtin = 0x00;
472if(device)
473{
474
475if((vendor_id != 0x168c) && (builtin_set == 0))
476{
477builtin_set = 1;
478builtin = 0x01;
479}
480if(!devprop_add_value(device, "device_type", (uint8_t*)"ethernet", 8))
481{
482return 0;
483}
484if(!devprop_add_value(device, "built-in", (uint8_t*)&builtin, 1))
485{
486return 0;
487}
488devices_number++;
489return 1;
490}
491else
492{
493return 0;
494}
495}
496
497void set_eth_builtin(pci_dt_t *eth_dev)
498{
499char *devicepath = get_pci_dev_path(eth_dev);
500DevPropDevice *device = (DevPropDevice*)malloc(sizeof(DevPropDevice));
501
502verbose("LAN Controller [%04x:%04x] :: %s\n", eth_dev->vendor_id, eth_dev->device_id, devicepath);
503
504if (!string)
505{
506string = devprop_create_string();
507if (!string)
508{
509return;
510}
511}
512
513device = devprop_add_device(string, devicepath);
514if(device)
515{
516verbose("Setting up lan keys\n");
517devprop_add_network_template(device, eth_dev->vendor_id);
518stringdata = (uint8_t*)malloc(sizeof(uint8_t) * string->length);
519if(stringdata)
520{
521memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
522stringlength = string->length;
523}
524}
525}
526

Archive Download this file

Revision: 2238