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
185if ((string->numentries+1) < MAX_STRING_NUM_ENTRIES)
186 {
187string->numentries++;
188
189 }
190 else
191 {
192 free(string->entries);
193 free(device);
194 return NULL;
195 }
196
197string_entries_arrey[string->numentries-1] = device;
198
199return device;
200}
201
202#if 0
203struct DevPropDevice *devprop_add_device(struct DevPropString *string, char *path)
204{
205struct DevPropDevice*device;
206const charpciroot_string[] = "PciRoot(0x";
207const charpci_device_string[] = "Pci(0x";
208
209if (string == NULL || path == NULL) {
210return NULL;
211}
212device = malloc(sizeof(struct DevPropDevice));
213if (!device) {
214 return NULL;
215 }
216if (strncmp(path, pciroot_string, strlen(pciroot_string))) {
217 free(device);
218printf("ERROR parsing device path 1\n");
219return NULL;
220}
221
222memset(device, 0, sizeof(struct DevPropDevice));
223device->acpi_dev_path._UID = getPciRootUID();
224
225int numpaths = 0;
226intx, curr = 0, w = 0;
227
228charbuff[16];
229
230
231for (x = 0; x < strlen(path); x++)
232{
233
234if (!strncmp(&path[x], pci_device_string, strlen(pci_device_string)))
235{
236x+=strlen(pci_device_string);
237curr=x;
238while(path[++x] != ',');
239
240 w = x-curr;
241
242 if ((w > 4) || /*(w > sizeof(buff)) ||*/ (w == 0)) {
243 printf("ERROR parsing device path 2\n");
244 break;
245 }
246
247 snprintf(buff, x-curr, "%s",&path[curr]);
248
249device->pci_dev_path[numpaths].device =(uint8_t)strtoul(buff, NULL, 16);
250
251 bzero(buff, sizeof(buff));
252
253x += 3; // 0x
254curr = x;
255while(path[++x] != ')');
256
257 w = x-curr;
258
259 if ((w > 4) || /*(w > sizeof(buff)) ||*/ (w == 0)) {
260 printf("ERROR parsing device path 3\n");
261 break;
262 }
263
264 snprintf(buff, x-curr, "%s",&path[curr]);
265
266device->pci_dev_path[numpaths].function = (uint8_t)strtoul(buff, NULL, 16); // TODO: find dev from char *path
267
268numpaths++;
269}
270}
271
272if(!numpaths)
273{
274 printf("ERROR parsing device path 4\n");
275 free(device);
276return NULL;
277}
278
279device->numentries = 0x00;
280
281device->acpi_dev_path.length = 0x0c;
282device->acpi_dev_path.type = 0x02;
283device->acpi_dev_path.subtype = 0x01;
284device->acpi_dev_path._HID = 0xd041030a;
285
286device->num_pci_devpaths = numpaths;
287device->length = 24 + (6*numpaths);
288
289inti;
290
291for(i = 0; i < numpaths; i++)
292{
293device->pci_dev_path[i].length = 0x06;
294device->pci_dev_path[i].type = 0x01;
295device->pci_dev_path[i].subtype = 0x01;
296}
297
298device->path_end.length = 0x04;
299device->path_end.type = 0x7f;
300device->path_end.subtype = 0xff;
301
302device->string = string;
303device->data = NULL;
304string->length += device->length;
305
306if(!string->entries)
307{
308if((string->entries = (struct DevPropDevice*)malloc(sizeof(struct DevPropDevice) * MAX_STRING_NUM_ENTRIES))== NULL)
309{
310 printf("ERROR parsing device path 6\n");
311
312 free(device);
313return NULL;
314}
315}
316struct DevPropDevice **string_entries_arrey = (struct DevPropDevice **) string->entries;
317
318if ((string->numentries+1) < MAX_STRING_NUM_ENTRIES)
319 {
320string->numentries++;
321
322 }
323 else
324 {
325 free(string->entries);
326 free(device);
327 return NULL;
328 }
329
330string_entries_arrey[string->numentries-1] = device;
331
332return device;
333}
334#endif
335
336int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
337{
338
339if(!nm || !vl || !len)
340{
341return 0;
342}
343
344uint32_t length = ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
345uint8_t *data = (uint8_t*)malloc(length);
346{
347if(!data)
348{
349return 0;
350}
351
352memset(data, 0, length);
353uint32_t off= 0;
354data[off+1] = ((strlen(nm) * 2) + 6) >> 8;
355data[off] = ((strlen(nm) * 2) + 6) & 0x00FF;
356
357off += 4;
358uint32_t i=0, l = strlen(nm);
359for(i = 0 ; i < l ; i++, off += 2)
360{
361data[off] = *nm++;
362}
363
364off += 2;
365l = len;
366uint32_t *datalength = (uint32_t*)&data[off];
367*datalength = l + 4;
368off += 4;
369for(i = 0 ; i < l ; i++, off++)
370{
371data[off] = *vl++;
372}
373}
374
375uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
376
377uint8_t *newdata = (uint8_t*)malloc((length + offset));
378if(!newdata)
379{
380return 0;
381}
382if(device->data)
383{
384if(offset > 1)
385{
386memcpy(newdata, device->data, offset);
387}
388}
389
390memcpy(newdata + offset, data, length);
391
392device->length += length;
393device->string->length += length;
394device->numentries++;
395
396if(!device->data)
397{
398//device->data = (uint8_t*)malloc(sizeof(uint8_t)); //IMHO this is useless
399}
400else
401{
402free(device->data);
403}
404
405free(data);
406device->data = newdata;
407
408return 1;
409}
410
411char *devprop_generate_string(struct DevPropString *string)
412{
413char *buffer = (char*)malloc(string->length * 2);
414char *ptr = buffer;
415
416if(!buffer)
417{
418return NULL;
419}
420
421sprintf(buffer, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2,
422dp_swap16(string->numentries), string->WHAT3);
423buffer += 24;
424int i = 0, x = 0;
425
426struct DevPropDevice **string_entries_arrey = (struct DevPropDevice **) string->entries;
427
428while(i < string->numentries)
429{
430if (!(i<MAX_STRING_NUM_ENTRIES))
431 {
432 continue;
433 }
434sprintf(buffer, "%08x%04x%04x", dp_swap32(string_entries_arrey[i]->length),
435dp_swap16(string_entries_arrey[i]->numentries), string_entries_arrey[i]->WHAT2);
436
437buffer += 16;
438sprintf(buffer, "%02x%02x%04x%08x%08x", string_entries_arrey[i]->acpi_dev_path.type,
439string_entries_arrey[i]->acpi_dev_path.subtype,
440dp_swap16(string_entries_arrey[i]->acpi_dev_path.length),
441string_entries_arrey[i]->acpi_dev_path._HID,
442dp_swap32(string_entries_arrey[i]->acpi_dev_path._UID));
443
444buffer += 24;
445for(x=0;x < string_entries_arrey[i]->num_pci_devpaths; x++)
446{
447sprintf(buffer, "%02x%02x%04x%02x%02x", string_entries_arrey[i]->pci_dev_path[x].type,
448string_entries_arrey[i]->pci_dev_path[x].subtype,
449dp_swap16(string_entries_arrey[i]->pci_dev_path[x].length),
450string_entries_arrey[i]->pci_dev_path[x].function,
451string_entries_arrey[i]->pci_dev_path[x].device);
452buffer += 12;
453}
454
455sprintf(buffer, "%02x%02x%04x", string_entries_arrey[i]->path_end.type,
456string_entries_arrey[i]->path_end.subtype,
457dp_swap16(string_entries_arrey[i]->path_end.length));
458
459buffer += 8;
460uint8_t *dataptr = string_entries_arrey[i]->data;
461for(x = 0; (uint32_t)x < (string_entries_arrey[i]->length) - (24 + (6 * string_entries_arrey[i]->num_pci_devpaths)) ; x++)
462{
463sprintf(buffer, "%02x", *dataptr++);
464buffer += 2;
465}
466i++;
467}
468return ptr;
469}
470
471void devprop_free_string(struct DevPropString *string)
472{
473if(!string)
474{
475return;
476}
477
478int i;
479
480struct DevPropDevice **string_entries_arrey = (struct DevPropDevice **) string->entries;
481
482for(i = 0; i < string->numentries; i++)
483{
484 if (!(i<MAX_STRING_NUM_ENTRIES))
485 {
486 continue;
487 }
488if(string_entries_arrey[i])
489{
490if(string_entries_arrey[i]->data)
491{
492free(string_entries_arrey[i]->data);
493string_entries_arrey[i]->data = NULL;
494}
495}
496}
497
498 free(string->entries);
499 string->entries = NULL;
500
501free(string);
502string = NULL;
503}

Archive Download this file

Revision: 2006