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

Archive Download this file

Revision: 2329