Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 2697