Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 2299