Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 1984