Chameleon

Chameleon Svn Source Tree

Root/branches/JrCs/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 "bootstruct.h"
10#include "pci.h"
11#include "device_inject.h"
12#include "convert.h"
13
14#ifndef DEBUG_INJECT
15#define DEBUG_INJECT 0
16#endif
17
18#if DEBUG_INJECT
19#define DBG(x...)printf(x)
20#else
21#define DBG(x...)
22#endif
23
24uint32_t devices_number = 1;
25uint32_t builtin_set = 0;
26struct DevPropString *string = 0;
27uint8_t *stringdata = 0;
28uint32_t stringlength = 0;
29
30char *efi_inject_get_devprop_string(uint32_t *len)
31{
32if(string)
33{
34*len = string->length;
35return devprop_generate_string(string);
36}
37printf("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 */
57 if (!getValueForKey(DEVICE_PROPERTIES_PROP, &val, &cnt, &bootInfo->bootConfig) && string)
58 {
59 val = (const char*)string;
60 cnt = strlength * 2;
61 }
62
63 if (cnt > 1)
64 {
65 binStr = convertHexStr2Binary(val, &cnt2);
66 if (cnt2 > 0) DT__AddProperty(node, DEVICE_PROPERTIES_PROP, cnt2, binStr);
67 }
68}
69
70struct DevPropString *devprop_create_string(void)
71{
72string = (struct DevPropString*)malloc(sizeof(struct DevPropString));
73
74if(string == NULL)
75return NULL;
76
77memset(string, 0, sizeof(struct DevPropString));
78string->length = 12;
79string->WHAT2 = 0x01000000;
80return string;
81}
82
83struct DevPropDevice *devprop_add_device(struct DevPropString *string, char *path)
84{
85uint32_t PciRootID = 0;
86const char *val;
87int len;
88
89struct DevPropDevice *device = (struct DevPropDevice*)malloc(sizeof(struct DevPropDevice));
90if(!device || !string || !path) {
91if(device)
92free(device);
93return NULL;
94}
95
96const char pciroot_string[]= "PciRoot(0x";
97const char pci_device_string[]= "Pci(0x";
98
99if (getValueForKey("PciRoot", &val, &len, &bootInfo->bootConfig))
100 PciRootID = atoi(val);
101
102if(strncmp(path, pciroot_string, strlen(pciroot_string)))
103{
104printf("ERROR parsing device path\n");
105return NULL;
106}
107
108memset(device, 0, sizeof(struct DevPropDevice));
109
110device->acpi_dev_path._UID = PciRootID;
111
112int numpaths = 0;
113intx, curr = 0;
114charbuff[] = "00";
115
116for(x = 0; x < strlen(path); x++)
117{
118if(!strncmp(&path[x], pci_device_string, strlen(pci_device_string)))
119{
120x+=strlen(pci_device_string);
121curr=x;
122while(path[++x] != ',');
123if(x-curr == 2)
124sprintf(buff, "%c%c", path[curr], path[curr+1]);
125else if(x-curr == 1)
126sprintf(buff, "%c", path[curr]);
127else
128{
129printf("ERROR parsing device path\n");
130numpaths = 0;
131break;
132}
133device->pci_dev_path[numpaths].device = strtoul(buff, NULL, 16);
134
135x += 3; // 0x
136curr = x;
137while(path[++x] != ')');
138if(x-curr == 2)
139sprintf(buff, "%c%c", path[curr], path[curr+1]);
140else if(x-curr == 1)
141sprintf(buff, "%c", path[curr]);
142else
143{
144printf("ERROR parsing device path\n");
145numpaths = 0;
146break;
147}
148device->pci_dev_path[numpaths].function = strtoul(buff, NULL, 16);
149
150numpaths++;
151}
152}
153
154if(!numpaths)
155return NULL;
156
157device->numentries = 0x00;
158
159device->acpi_dev_path.length = 0x0c;
160device->acpi_dev_path.type = 0x02;
161device->acpi_dev_path.subtype = 0x01;
162device->acpi_dev_path._HID = 0xd041030a;
163
164device->num_pci_devpaths = numpaths;
165device->length = 24 + (6*numpaths);
166
167inti;
168
169for(i = 0; i < numpaths; i++)
170{
171device->pci_dev_path[i].length = 0x06;
172device->pci_dev_path[i].type = 0x01;
173device->pci_dev_path[i].subtype = 0x01;
174}
175
176device->path_end.length = 0x04;
177device->path_end.type = 0x7f;
178device->path_end.subtype = 0xff;
179
180device->string = string;
181device->data = NULL;
182string->length += device->length;
183
184if(!string->entries)
185if((string->entries = (struct DevPropDevice**)malloc(sizeof(device)))== NULL)
186return 0;
187
188string->entries[string->numentries++] = (struct DevPropDevice*)malloc(sizeof(device));
189string->entries[string->numentries-1] = device;
190
191return device;
192}
193
194int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
195{
196
197if(!nm || !vl || !len)
198return 0;
199
200uint32_t length = ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
201uint8_t *data = (uint8_t*)malloc(length);
202{
203if(!data)
204return 0;
205
206memset(data, 0, length);
207uint32_t off= 0;
208data[off+1] = ((strlen(nm) * 2) + 6) >> 8;
209data[off] = ((strlen(nm) * 2) + 6) & 0x00FF;
210
211off += 4;
212uint32_t i=0, l = strlen(nm);
213for(i = 0 ; i < l ; i++, off += 2)
214{
215data[off] = *nm++;
216}
217
218off += 2;
219l = len;
220uint32_t *datalength = (uint32_t*)&data[off];
221*datalength = l + 4;
222off += 4;
223for(i = 0 ; i < l ; i++, off++)
224{
225data[off] = *vl++;
226}
227}
228
229uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
230
231uint8_t *newdata = (uint8_t*)malloc((length + offset));
232if(!newdata)
233return 0;
234if(device->data)
235if(offset > 1)
236memcpy(newdata, device->data, offset);
237
238memcpy(newdata + offset, data, length);
239
240device->length += length;
241device->string->length += length;
242device->numentries++;
243
244if(!device->data)
245device->data = (uint8_t*)malloc(sizeof(uint8_t));
246else
247free(device->data);
248
249free(data);
250device->data = newdata;
251
252return 1;
253}
254
255char *devprop_generate_string(struct DevPropString *string)
256{
257char *buffer = (char*)malloc(string->length * 2);
258char *ptr = buffer;
259
260if(!buffer)
261return NULL;
262
263sprintf(buffer, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2,
264dp_swap16(string->numentries), string->WHAT3);
265buffer += 24;
266int i = 0, x = 0;
267
268while(i < string->numentries)
269{
270sprintf(buffer, "%08x%04x%04x", dp_swap32(string->entries[i]->length),
271dp_swap16(string->entries[i]->numentries), string->entries[i]->WHAT2);
272
273buffer += 16;
274sprintf(buffer, "%02x%02x%04x%08x%08x", string->entries[i]->acpi_dev_path.type,
275string->entries[i]->acpi_dev_path.subtype,
276dp_swap16(string->entries[i]->acpi_dev_path.length),
277string->entries[i]->acpi_dev_path._HID,
278dp_swap32(string->entries[i]->acpi_dev_path._UID));
279
280buffer += 24;
281for(x=0;x < string->entries[i]->num_pci_devpaths; x++)
282{
283sprintf(buffer, "%02x%02x%04x%02x%02x", string->entries[i]->pci_dev_path[x].type,
284string->entries[i]->pci_dev_path[x].subtype,
285dp_swap16(string->entries[i]->pci_dev_path[x].length),
286string->entries[i]->pci_dev_path[x].function,
287string->entries[i]->pci_dev_path[x].device);
288buffer += 12;
289}
290
291sprintf(buffer, "%02x%02x%04x", string->entries[i]->path_end.type,
292string->entries[i]->path_end.subtype,
293dp_swap16(string->entries[i]->path_end.length));
294
295buffer += 8;
296uint8_t *dataptr = string->entries[i]->data;
297for(x = 0; x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++)
298{
299sprintf(buffer, "%02x", *dataptr++);
300buffer += 2;
301}
302i++;
303}
304return ptr;
305}
306
307void devprop_free_string(struct DevPropString *string)
308{
309if(!string)
310return;
311
312int i;
313for(i = 0; i < string->numentries; i++)
314{
315if(string->entries[i])
316{
317if(string->entries[i]->data)
318{
319free(string->entries[i]->data);
320string->entries[i]->data = NULL;
321}
322free(string->entries[i]);
323string->entries[i] = NULL;
324}
325}
326
327free(string);
328string = NULL;
329}
330
331/* a fine place for this code */
332
333int devprop_add_network_template(struct DevPropDevice *device, uint16_t vendor_id)
334{
335if(!device)
336return 0;
337uint8_t builtin = 0x0;
338if((vendor_id != 0x168c) && (builtin_set == 0))
339{
340builtin_set = 1;
341builtin = 0x01;
342}
343if(!devprop_add_value(device, "built-in", (uint8_t*)&builtin, 1))
344return 0;
345devices_number++;
346return 1;
347}
348
349void set_eth_builtin(pci_dt_t *eth_dev)
350{
351char *devicepath = get_pci_dev_path(eth_dev);
352struct DevPropDevice *device = (struct DevPropDevice*)malloc(sizeof(struct DevPropDevice));
353
354verbose("LAN Controller [%04x:%04x] :: %s\n", eth_dev->vendor_id, eth_dev->device_id, devicepath);
355
356if (!string)
357string = devprop_create_string();
358
359device = devprop_add_device(string, devicepath);
360if(device)
361{
362verbose("Setting up lan keys\n");
363devprop_add_network_template(device, eth_dev->vendor_id);
364stringdata = (uint8_t*)malloc(sizeof(uint8_t) * string->length);
365if(stringdata)
366{
367memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
368stringlength = string->length;
369}
370}
371}
372

Archive Download this file

Revision: 126