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

Archive Download this file

Revision: 2662