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

Archive Download this file

Revision: 1972