Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch/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 "boot.h"
10#include "bootstruct.h"
11#include "pci.h"
12#include "pci_root.h"
13#include "device_inject.h"
14#include "convert.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...)msglog(x)
24#endif
25
26uint32_tdevices_number= 1;
27DevPropString*string= NULL;
28uint8_t*stringdata= NULL;
29uint32_tstringlength= 0;
30
31char *efi_inject_get_devprop_string(uint32_t *len)
32{
33if(string) {
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{
43 const char *val;
44 uint8_t *binStr;
45 int cnt, cnt2;
46
47 static char DEVICE_PROPERTIES_PROP[] = "device-properties";
48
49 /* Generate devprop string.
50 */
51 uint32_t strlength;
52 char *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, &bootInfo->chameleonConfig) && string)
58{
59val = (const char*)string;
60cnt = strlength * 2;
61}
62
63if (cnt > 1)
64{
65binStr = convertHexStr2Binary(val, &cnt2);
66if (cnt2 > 0)
67{
68DT__AddProperty(node, DEVICE_PROPERTIES_PROP, cnt2, binStr);
69DBG("Adding device-properties string to DT");
70}
71}
72}
73
74DevPropString *devprop_create_string(void)
75{
76string = (DevPropString *)malloc(sizeof(DevPropString));
77
78if(string == NULL)
79{
80return NULL;
81}
82
83memset(string, 0, sizeof(DevPropString));
84string->length = 12;
85string->WHAT2 = 0x01000000;
86return string;
87}
88
89DevPropDevice *devprop_add_device(DevPropString *string, char *path)
90{
91DevPropDevice*device= NULL;
92const charpciroot_string[]= "PciRoot(0x";
93const charpci_device_string[]= "Pci(0x";
94
95if (string == NULL || path == NULL)
96{
97printf("ERROR null device path\n");
98return NULL;
99}
100
101if (strncmp(path, pciroot_string, strlen(pciroot_string)))
102{
103printf("ERROR parsing device path\n");
104return NULL;
105}
106
107if (!(device = malloc(sizeof(DevPropDevice))))
108{
109printf("ERROR malloc failed\n");
110return NULL;
111}
112
113memset(device, 0, sizeof(DevPropDevice));
114device->acpi_dev_path._UID = getPciRootUID();
115
116int numpaths = 0;
117intx, curr = 0;
118charbuff[] = "00";
119
120for (x = 0; x < strlen(path); x++)
121{
122if (!strncmp(&path[x], pci_device_string, strlen(pci_device_string)))
123{
124x+=strlen(pci_device_string);
125curr=x;
126while(path[++x] != ',');
127if(x-curr == 2)
128{
129sprintf(buff, "%c%c", path[curr], path[curr+1]);
130}
131else if(x-curr == 1)
132{
133sprintf(buff, "%c", path[curr]);
134}
135else
136{
137printf("ERROR parsing device path\n");
138numpaths = 0;
139break;
140}
141device->pci_dev_path[numpaths].device =ascii_hex_to_int(buff);
142
143x += 3; // 0x
144curr = x;
145while(path[++x] != ')');
146if(x-curr == 2)
147{
148sprintf(buff, "%c%c", path[curr], path[curr+1]);
149}
150else if(x-curr == 1)
151{
152sprintf(buff, "%c", path[curr]);
153}
154else
155{
156printf("ERROR parsing device path\n");
157numpaths = 0;
158break;
159}
160device->pci_dev_path[numpaths].function = ascii_hex_to_int(buff); // TODO: find dev from char *path
161
162numpaths++;
163}
164}
165
166if(!numpaths)
167{
168free(device);
169return NULL;
170}
171
172device->numentries = 0x00;
173
174device->acpi_dev_path.length= 0x0c;
175device->acpi_dev_path.type= 0x02;
176device->acpi_dev_path.subtype= 0x01;
177device->acpi_dev_path._HID= 0xd041030a; // 0x0a0341d0
178
179device->num_pci_devpaths = numpaths;
180device->length = 24 + (6*numpaths);
181
182inti;
183
184for(i = 0; i < numpaths; i++)
185{
186device->pci_dev_path[i].length = 0x06;
187device->pci_dev_path[i].type = 0x01;
188device->pci_dev_path[i].subtype = 0x01;
189}
190
191device->path_end.length = 0x04;
192device->path_end.type = 0x7f;
193device->path_end.subtype = 0xff;
194
195device->string = string;
196device->data = NULL;
197
198if(!string->entries)
199{
200if (!(string->entries = (struct DevPropDevice**) malloc(sizeof(device) * DEV_PROP_DEVICE_MAX_ENTRIES)))
201{
202free(device);
203return NULL;
204}
205}
206
207/* FIXME: probably needs bounds checking, as well as error handling in event of malloc failure */
208string->length += device->length;
209string->entries[string->numentries++] = (DevPropDevice*)malloc(sizeof(device));
210string->entries[string->numentries-1] = device;
211
212return device;
213}
214
215int devprop_add_value(DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
216{
217
218if(!nm || !vl || !len)
219{
220return 0;
221}
222uint32_t length= ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
223uint8_t *data= (uint8_t*)malloc(length);
224
225if(!data)
226{
227return 0;
228}
229
230memset(data, 0, length);
231uint32_t off = 0;
232data[off+1] = ((strlen(nm) * 2) + 6) >> 8;
233data[off] = ((strlen(nm) * 2) + 6) & 0x00FF;
234
235off += 4;
236uint32_t i=0, l = strlen(nm);
237for(i = 0 ; i < l ; i++, off += 2)
238{
239data[off] = *nm++;
240}
241
242off += 2;
243l = len;
244uint32_t *datalength = (uint32_t*)&data[off];
245*datalength = (uint32_t)(l + 4);
246off += 4;
247for(i = 0 ; i < l ; i++, off++)
248{
249data[off] = *vl++;
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}
259
260if(device->data)
261{
262if(offset > 1)
263{
264memcpy(newdata, device->data, offset);
265}
266}
267
268memcpy(newdata + offset, data, length);
269
270device->length += length;
271device->string->length += length;
272device->numentries++;
273
274if(!device->data)
275{
276device->data = (uint8_t *)malloc(sizeof(uint8_t));
277}
278else
279{
280free(device->data);
281}
282
283free(data);
284device->data = newdata;
285
286return 1;
287}
288
289// devprop_generate_string optimized by cparm
290char *devprop_generate_string(DevPropString *string)
291{
292int len = string->length * 2;
293char *buffer = (char*)malloc(len);
294char *ptr = buffer;
295
296if(!buffer)
297{
298return NULL;
299}
300
301snprintf(buffer, len, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2,
302dp_swap16(string->numentries), string->WHAT3);
303buffer += 24;
304len -= 24;
305int i = 0, x = 0;
306
307while(i < string->numentries)
308{
309 if (!(i < DEV_PROP_DEVICE_MAX_ENTRIES))
310{
311 break;
312 }
313
314 if(!len)
315{
316 break;
317 }
318
319snprintf(buffer, len, "%08x%04x%04x", dp_swap32(string->entries[i]->length),
320dp_swap16(string->entries[i]->numentries), string->entries[i]->WHAT2);
321
322buffer += 16;
323len -= 16;
324snprintf(buffer, len, "%02x%02x%04x%08x%08x", string->entries[i]->acpi_dev_path.type,
325string->entries[i]->acpi_dev_path.subtype,
326dp_swap16(string->entries[i]->acpi_dev_path.length),
327string->entries[i]->acpi_dev_path._HID,
328dp_swap32(string->entries[i]->acpi_dev_path._UID));
329
330buffer += 24;
331len -= 24;
332for(x = 0;x < string->entries[i]->num_pci_devpaths; x++)
333{
334if(!len)
335{
336break;
337}
338snprintf(buffer, len, "%02x%02x%04x%02x%02x", string->entries[i]->pci_dev_path[x].type,
339string->entries[i]->pci_dev_path[x].subtype,
340dp_swap16(string->entries[i]->pci_dev_path[x].length),
341string->entries[i]->pci_dev_path[x].function,
342string->entries[i]->pci_dev_path[x].device);
343buffer += 12;
344len -= 12;
345}
346
347if(!len)
348{
349break;
350}
351
352snprintf(buffer, len, "%02x%02x%04x", string->entries[i]->path_end.type,
353string->entries[i]->path_end.subtype,
354dp_swap16(string->entries[i]->path_end.length));
355
356buffer += 8;
357len -= 8;
358uint8_t *dataptr = string->entries[i]->data;
359for(x = 0; (uint32_t)x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++)
360{
361if(!len)
362{
363break;
364}
365snprintf(buffer, len, "%02x", *dataptr++);
366buffer += 2;
367len -= 2;
368}
369i++;
370}
371return ptr;
372}
373
374void devprop_free_string(DevPropString *string)
375{
376
377if(!string) {
378return;
379}
380
381int i;
382for(i = 0; i < string->numentries; i++)
383{
384if(string->entries[i])
385{
386if(string->entries[i]->data)
387{
388free(string->entries[i]->data);
389string->entries[i]->data = NULL;
390}
391free(string->entries[i]);
392string->entries[i] = NULL;
393}
394}
395
396free(string);
397string = NULL;
398}
399
400/* ======================================================= */
401
402/* a fine place for this code */
403

Archive Download this file

Revision: 2679