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

Archive Download this file

Revision: 2057