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
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
25uint32_t devices_number = 1;
26struct DevPropString *string = 0;
27uint8_t *stringdata = 0;
28uint32_t stringlength = 0;
29
30char *efi_inject_get_devprop_string(uint32_t *len)
31{
32if(string)
33{
34*len = string->length;
35return devprop_generate_string(string);
36}
37verbose("efi_inject_get_devprop_string NULL trying stringdata\n");
38return NULL;
39}
40
41void setupDeviceProperties(Node *node)
42{
43const char *val;
44uint8_t *binStr;
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);
66if (cnt2 > 0) DT__AddProperty(node, DEVICE_PROPERTIES_PROP, cnt2, binStr);
67}
68}
69
70struct DevPropString *devprop_create_string(void)
71{
72string = (struct DevPropString*)malloc(sizeof(struct DevPropString));
73
74if(string == NULL)
75{
76return NULL;
77}
78
79memset(string, 0, sizeof(struct DevPropString));
80string->length = 12;
81string->WHAT2 = 0x01000000;
82return string;
83}
84
85struct DevPropDevice *devprop_add_device(struct DevPropString *string, char *path)
86{
87struct DevPropDevice*device;
88const charpciroot_string[] = "PciRoot(0x";
89const charpci_device_string[] = "Pci(0x";
90
91if (string == NULL || path == NULL) {
92return NULL;
93}
94device = malloc(sizeof(struct DevPropDevice));
95
96if (strncmp(path, pciroot_string, strlen(pciroot_string))) {
97printf("ERROR parsing device path\n");
98return NULL;
99}
100
101memset(device, 0, sizeof(struct DevPropDevice));
102device->acpi_dev_path._UID = getPciRootUID();
103
104int numpaths = 0;
105intx, curr = 0;
106charbuff[] = "00";
107
108for (x = 0; x < strlen(path); x++)
109{
110if (!strncmp(&path[x], pci_device_string, strlen(pci_device_string)))
111{
112x+=strlen(pci_device_string);
113curr=x;
114while(path[++x] != ',');
115if(x-curr == 2)
116{
117sprintf(buff, "%c%c", path[curr], path[curr+1]);
118}
119else if(x-curr == 1)
120{
121sprintf(buff, "%c", path[curr]);
122}
123else
124{
125printf("ERROR parsing device path\n");
126numpaths = 0;
127break;
128}
129device->pci_dev_path[numpaths].device =ascii_hex_to_int(buff);
130
131x += 3; // 0x
132curr = x;
133while(path[++x] != ')');
134if(x-curr == 2)
135{
136sprintf(buff, "%c%c", path[curr], path[curr+1]);
137}
138else if(x-curr == 1)
139{
140sprintf(buff, "%c", path[curr]);
141}
142else
143{
144printf("ERROR parsing device path\n");
145numpaths = 0;
146break;
147}
148device->pci_dev_path[numpaths].function = ascii_hex_to_int(buff); // TODO: find dev from char *path
149
150numpaths++;
151}
152}
153
154if(!numpaths)
155{
156return NULL;
157}
158
159device->numentries = 0x00;
160
161device->acpi_dev_path.length = 0x0c;
162device->acpi_dev_path.type = 0x02;
163device->acpi_dev_path.subtype = 0x01;
164device->acpi_dev_path._HID = 0xd041030a;
165
166device->num_pci_devpaths = numpaths;
167device->length = 24 + (6*numpaths);
168
169inti;
170
171for(i = 0; i < numpaths; i++)
172{
173device->pci_dev_path[i].length = 0x06;
174device->pci_dev_path[i].type = 0x01;
175device->pci_dev_path[i].subtype = 0x01;
176}
177
178device->path_end.length = 0x04;
179device->path_end.type = 0x7f;
180device->path_end.subtype = 0xff;
181
182device->string = string;
183device->data = NULL;
184string->length += device->length;
185
186if(!string->entries)
187{
188if((string->entries = (struct DevPropDevice**)malloc(sizeof(device)))== NULL)
189{
190return 0;
191}
192}
193
194string->entries[string->numentries++] = (struct DevPropDevice*)malloc(sizeof(device));
195string->entries[string->numentries-1] = device;
196
197return device;
198}
199
200int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
201{
202
203if(!nm || !vl || !len)
204{
205return 0;
206}
207
208uint32_t length = ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
209uint8_t *data = (uint8_t*)malloc(length);
210{
211if(!data)
212{
213return 0;
214}
215
216memset(data, 0, length);
217uint32_t off= 0;
218data[off+1] = ((strlen(nm) * 2) + 6) >> 8;
219data[off] = ((strlen(nm) * 2) + 6) & 0x00FF;
220
221off += 4;
222uint32_t i=0, l = strlen(nm);
223for(i = 0 ; i < l ; i++, off += 2)
224{
225data[off] = *nm++;
226}
227
228off += 2;
229l = len;
230uint32_t *datalength = (uint32_t*)&data[off];
231*datalength = l + 4;
232off += 4;
233for(i = 0 ; i < l ; i++, off++)
234{
235data[off] = *vl++;
236}
237}
238
239uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
240
241uint8_t *newdata = (uint8_t*)malloc((length + offset));
242if(!newdata)
243{
244return 0;
245}
246if(device->data)
247{
248if(offset > 1)
249{
250memcpy(newdata, device->data, offset);
251}
252}
253
254memcpy(newdata + offset, data, length);
255
256device->length += length;
257device->string->length += length;
258device->numentries++;
259
260if(!device->data)
261{
262device->data = (uint8_t*)malloc(sizeof(uint8_t));
263}
264else
265{
266free(device->data);
267}
268
269free(data);
270device->data = newdata;
271
272return 1;
273}
274
275char *devprop_generate_string(struct DevPropString *string)
276{
277char *buffer = (char*)malloc(string->length * 2);
278char *ptr = buffer;
279
280if(!buffer)
281{
282return NULL;
283}
284
285sprintf(buffer, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2,
286dp_swap16(string->numentries), string->WHAT3);
287buffer += 24;
288int i = 0, x = 0;
289
290while(i < string->numentries)
291{
292sprintf(buffer, "%08x%04x%04x", dp_swap32(string->entries[i]->length),
293dp_swap16(string->entries[i]->numentries), string->entries[i]->WHAT2);
294
295buffer += 16;
296sprintf(buffer, "%02x%02x%04x%08x%08x", string->entries[i]->acpi_dev_path.type,
297string->entries[i]->acpi_dev_path.subtype,
298dp_swap16(string->entries[i]->acpi_dev_path.length),
299string->entries[i]->acpi_dev_path._HID,
300dp_swap32(string->entries[i]->acpi_dev_path._UID));
301
302buffer += 24;
303for(x=0;x < string->entries[i]->num_pci_devpaths; x++)
304{
305sprintf(buffer, "%02x%02x%04x%02x%02x", string->entries[i]->pci_dev_path[x].type,
306string->entries[i]->pci_dev_path[x].subtype,
307dp_swap16(string->entries[i]->pci_dev_path[x].length),
308string->entries[i]->pci_dev_path[x].function,
309string->entries[i]->pci_dev_path[x].device);
310buffer += 12;
311}
312
313sprintf(buffer, "%02x%02x%04x", string->entries[i]->path_end.type,
314string->entries[i]->path_end.subtype,
315dp_swap16(string->entries[i]->path_end.length));
316
317buffer += 8;
318uint8_t *dataptr = string->entries[i]->data;
319for(x = 0; (uint32_t)x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++)
320{
321sprintf(buffer, "%02x", *dataptr++);
322buffer += 2;
323}
324i++;
325}
326return ptr;
327}
328
329void devprop_free_string(struct DevPropString *string)
330{
331if(!string)
332{
333return;
334}
335
336int i;
337for(i = 0; i < string->numentries; i++)
338{
339if(string->entries[i])
340{
341if(string->entries[i]->data)
342{
343free(string->entries[i]->data);
344string->entries[i]->data = NULL;
345}
346free(string->entries[i]);
347string->entries[i] = NULL;
348}
349}
350
351free(string);
352string = NULL;
353}

Archive Download this file

Revision: 1899