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...)
24#endif
25
26uint32_t devices_number = 1;
27uint32_t builtin_set = 0;
28struct DevPropString *string = 0;
29uint8_t *stringdata = 0;
30uint32_t stringlength = 0;
31
32char *efi_inject_get_devprop_string(uint32_t *len)
33{
34if(string)
35{
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);
71}
72}
73}
74
75struct DevPropString *devprop_create_string(void)
76{
77string = (struct DevPropString*)malloc(sizeof(struct DevPropString));
78
79if(string == NULL)
80return NULL;
81
82memset(string, 0, sizeof(struct DevPropString));
83string->length = 12;
84string->WHAT2 = 0x01000000;
85return string;
86}
87
88struct DevPropDevice *devprop_add_device(struct DevPropString *string, char *path)
89{
90struct DevPropDevice*device;
91const charpciroot_string[] = "PciRoot(0x";
92const charpci_device_string[] = "Pci(0x";
93
94if (string == NULL || path == NULL) {
95return NULL;
96}
97device = malloc(sizeof(struct DevPropDevice));
98
99if (strncmp(path, pciroot_string, strlen(pciroot_string))) {
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++) {
112if (!strncmp(&path[x], pci_device_string, strlen(pci_device_string))) {
113x+=strlen(pci_device_string);
114curr=x;
115while(path[++x] != ',');
116if(x-curr == 2)
117sprintf(buff, "%c%c", path[curr], path[curr+1]);
118else if(x-curr == 1)
119sprintf(buff, "%c", path[curr]);
120else
121{
122printf("ERROR parsing device path\n");
123numpaths = 0;
124break;
125}
126device->pci_dev_path[numpaths].device =ascii_hex_to_int(buff);
127
128x += 3; // 0x
129curr = x;
130while(path[++x] != ')');
131if(x-curr == 2)
132sprintf(buff, "%c%c", path[curr], path[curr+1]);
133else if(x-curr == 1)
134sprintf(buff, "%c", path[curr]);
135else
136{
137printf("ERROR parsing device path\n");
138numpaths = 0;
139break;
140}
141device->pci_dev_path[numpaths].function = ascii_hex_to_int(buff); // TODO: find dev from char *path
142
143numpaths++;
144}
145}
146
147if(!numpaths)
148return NULL;
149
150device->numentries = 0x00;
151
152device->acpi_dev_path.length = 0x0c;
153device->acpi_dev_path.type = 0x02;
154device->acpi_dev_path.subtype = 0x01;
155device->acpi_dev_path._HID = 0xd041030a;
156
157device->num_pci_devpaths = numpaths;
158device->length = 24 + (6*numpaths);
159
160inti;
161
162for(i = 0; i < numpaths; i++)
163{
164device->pci_dev_path[i].length = 0x06;
165device->pci_dev_path[i].type = 0x01;
166device->pci_dev_path[i].subtype = 0x01;
167}
168
169device->path_end.length = 0x04;
170device->path_end.type = 0x7f;
171device->path_end.subtype = 0xff;
172
173device->string = string;
174device->data = NULL;
175string->length += device->length;
176
177if(!string->entries)
178if((string->entries = (struct DevPropDevice**)malloc(sizeof(device)*DEV_PROP_DEVICE_MAX_ENTRIES))== NULL)
179return 0;
180
181string->entries[string->numentries++] = (struct DevPropDevice*)malloc(sizeof(device));
182string->entries[string->numentries-1] = device;
183
184return device;
185}
186
187int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
188{
189
190if(!nm || !vl || !len)
191return 0;
192
193uint32_t length = ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
194uint8_t *data = (uint8_t*)malloc(length);
195{
196if(!data)
197{
198return 0;
199}
200
201memset(data, 0, length);
202uint32_t off= 0;
203data[off+1] = ((strlen(nm) * 2) + 6) >> 8;
204data[off] = ((strlen(nm) * 2) + 6) & 0x00FF;
205
206off += 4;
207uint32_t i=0, l = strlen(nm);
208for(i = 0 ; i < l ; i++, off += 2)
209{
210data[off] = *nm++;
211}
212
213off += 2;
214l = len;
215uint32_t *datalength = (uint32_t*)&data[off];
216*datalength = l + 4;
217off += 4;
218for(i = 0 ; i < l ; i++, off++)
219{
220data[off] = *vl++;
221}
222}
223
224uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
225
226uint8_t *newdata = (uint8_t*)malloc((length + offset));
227if(!newdata)
228{
229return 0;
230}
231if(device->data)
232{
233if(offset > 1)
234{
235memcpy(newdata, device->data, offset);
236}
237}
238
239memcpy(newdata + offset, data, length);
240
241device->length += length;
242device->string->length += length;
243device->numentries++;
244
245if(!device->data)
246{
247device->data = (uint8_t*)malloc(sizeof(uint8_t));
248}
249else
250{
251free(device->data);
252}
253
254free(data);
255device->data = newdata;
256
257return 1;
258}
259
260char *devprop_generate_string(struct DevPropString *string)
261{
262char *buffer = (char*)malloc(string->length * 2);
263char *ptr = buffer;
264
265if(!buffer)
266{
267return NULL;
268}
269
270sprintf(buffer, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2,
271dp_swap16(string->numentries), string->WHAT3);
272buffer += 24;
273int i = 0, x = 0;
274
275while(i < string->numentries)
276{
277sprintf(buffer, "%08x%04x%04x", dp_swap32(string->entries[i]->length),
278dp_swap16(string->entries[i]->numentries), string->entries[i]->WHAT2);
279
280buffer += 16;
281sprintf(buffer, "%02x%02x%04x%08x%08x", string->entries[i]->acpi_dev_path.type,
282string->entries[i]->acpi_dev_path.subtype,
283dp_swap16(string->entries[i]->acpi_dev_path.length),
284string->entries[i]->acpi_dev_path._HID,
285dp_swap32(string->entries[i]->acpi_dev_path._UID));
286
287buffer += 24;
288for(x=0;x < string->entries[i]->num_pci_devpaths; x++)
289{
290sprintf(buffer, "%02x%02x%04x%02x%02x", string->entries[i]->pci_dev_path[x].type,
291string->entries[i]->pci_dev_path[x].subtype,
292dp_swap16(string->entries[i]->pci_dev_path[x].length),
293string->entries[i]->pci_dev_path[x].function,
294string->entries[i]->pci_dev_path[x].device);
295buffer += 12;
296}
297
298sprintf(buffer, "%02x%02x%04x", string->entries[i]->path_end.type,
299string->entries[i]->path_end.subtype,
300dp_swap16(string->entries[i]->path_end.length));
301
302buffer += 8;
303uint8_t *dataptr = string->entries[i]->data;
304for(x = 0; x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++)
305{
306sprintf(buffer, "%02x", *dataptr++);
307buffer += 2;
308}
309i++;
310}
311return ptr;
312}
313
314void devprop_free_string(struct DevPropString *string)
315{
316
317if(!string)
318{
319return;
320}
321
322int i;
323for(i = 0; i < string->numentries; i++)
324{
325if(string->entries[i])
326{
327if(string->entries[i]->data)
328{
329free(string->entries[i]->data);
330string->entries[i]->data = NULL;
331}
332free(string->entries[i]);
333string->entries[i] = NULL;
334}
335}
336
337free(string);
338string = NULL;
339}
340
341/* ======================================================= */
342
343
344/*******************************************************************
345 * Decodes a sequence of 'len' hexadecimal chars from 'hex' into *
346 * a binary. returns -1 in case of error (i.e. badly formed chars) *
347 *******************************************************************/
348int hex2bin(const char *hex, uint8_t *bin, int len)
349{
350char*p;
351inti;
352charbuf[3];
353
354if (hex == NULL || bin == NULL || len <= 0 || strlen(hex) != len * 2)
355{
356printf("[ERROR] bin2hex input error\n");
357return -1;
358}
359
360buf[2] = '\0';
361p = (char *) hex;
362
363for (i = 0; i < len; i++)
364{
365if (p[0] == '\0' || p[1] == '\0' || !isxdigit(p[0]) || !isxdigit(p[1]))
366{
367printf("[ERROR] bin2hex '%s' syntax error\n", hex);
368return -2;
369}
370buf[0] = *p++;
371buf[1] = *p++;
372bin[i] = (unsigned char) strtoul(buf, NULL, 16);
373}
374return 0;
375}
376
377/* ======================================================= */
378
379/* a fine place for this code */
380
381int devprop_add_network_template(struct DevPropDevice *device, uint16_t vendor_id)
382{
383if(!device)
384return 0;
385uint8_t builtin = 0x0;
386if((vendor_id != 0x168c) && (builtin_set == 0))
387{
388builtin_set = 1;
389builtin = 0x01;
390}
391if(!devprop_add_value(device, "built-in", (uint8_t*)&builtin, 1))
392return 0;
393devices_number++;
394return 1;
395}
396
397void set_eth_builtin(pci_dt_t *eth_dev)
398{
399char *devicepath = get_pci_dev_path(eth_dev);
400struct DevPropDevice *device = (struct DevPropDevice*)malloc(sizeof(struct DevPropDevice));
401
402verbose("LAN Controller [%04x:%04x] :: %s\n", eth_dev->vendor_id, eth_dev->device_id, devicepath);
403
404if (!string)
405string = devprop_create_string();
406
407device = devprop_add_device(string, devicepath);
408if(device)
409{
410verbose("Setting up lan keys\n");
411devprop_add_network_template(device, eth_dev->vendor_id);
412stringdata = (uint8_t*)malloc(sizeof(uint8_t) * string->length);
413if(stringdata)
414{
415memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
416stringlength = string->length;
417}
418}
419}
420

Archive Download this file

Revision: 2266