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

Archive Download this file

Revision: 1977