Chameleon

Chameleon Svn Source Tree

Root/branches/andyvand/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
32typedef struct DeviceEntryStruct DeviceEntry_t;
33
34struct DeviceEntryStruct {
35 DeviceEntry_t* next;
36 const char* path;
37 struct DevPropDevice* device;
38};
39
40DeviceEntry_t* TheDeviceRegistry = NULL;
41
42char *efi_inject_get_devprop_string(uint32_t *len)
43{
44if(string) {
45*len = string->length;
46return devprop_generate_string(string);
47}
48verbose("efi_inject_get_devprop_string NULL trying stringdata\n");
49return NULL;
50}
51
52void setupDeviceProperties(Node *node)
53{
54 const char *val;
55 uint8_t *binStr;
56 int cnt, cnt2;
57
58 static char DEVICE_PROPERTIES_PROP[] = "device-properties";
59
60 /* Generate devprop string.
61 */
62 uint32_t strlength;
63 char *string = efi_inject_get_devprop_string(&strlength);
64
65 /* Use the static "device-properties" boot config key contents if available,
66 * otheriwse use the generated one.
67 */
68 if (!getValueForKey(kDeviceProperties, &val, &cnt, &bootInfo->bootConfig) && string)
69 {
70 val = (const char*)string;
71 cnt = strlength * 2;
72 }
73
74 if (cnt > 1)
75 {
76 binStr = convertHexStr2Binary(val, &cnt2);
77 if (cnt2 > 0) DT__AddProperty(node, DEVICE_PROPERTIES_PROP, cnt2, binStr);
78 }
79}
80
81struct DevPropString *devprop_create_string(void)
82{
83string = (struct DevPropString*)malloc(sizeof(struct DevPropString));
84
85if(string == NULL)
86return NULL;
87
88memset(string, 0, sizeof(struct DevPropString));
89string->length = 12;
90string->WHAT2 = 0x01000000;
91return string;
92}
93
94struct DevPropDevice *devprop_add_device(struct DevPropString *string, char *path)
95{
96struct DevPropDevice*device;
97const charpciroot_string[] = "PciRoot(0x";
98const charpci_device_string[] = "Pci(0x";
99DeviceEntry_t* newDeviceEntry;
100
101if (string == NULL || path == NULL) {
102return NULL;
103}
104device = malloc(sizeof(struct DevPropDevice));
105
106if (strncmp(path, pciroot_string, strlen(pciroot_string))) {
107printf("ERROR parsing device path\n");
108return NULL;
109}
110
111memset(device, 0, sizeof(struct DevPropDevice));
112device->acpi_dev_path._UID = getPciRootUID();
113
114int numpaths = 0;
115intx, curr = 0;
116charbuff[] = "00";
117
118for (x = 0; x < strlen(path); x++) {
119if (!strncmp(&path[x], pci_device_string, strlen(pci_device_string))) {
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 =ascii_hex_to_int(buff);
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 = ascii_hex_to_int(buff); // TODO: find dev from char *path
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
191// Register the device to the device entries
192newDeviceEntry = malloc(sizeof(DeviceEntry_t));
193newDeviceEntry->next = TheDeviceRegistry;
194TheDeviceRegistry = newDeviceEntry;
195newDeviceEntry->path = strdup(path);
196newDeviceEntry->device = device;
197
198return device;
199}
200
201int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
202{
203
204if(!nm || !vl || !len)
205return 0;
206
207uint32_t length = ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
208uint8_t *data = (uint8_t*)malloc(length);
209{
210if(!data)
211return 0;
212
213memset(data, 0, length);
214uint32_t off= 0;
215data[off+1] = ((strlen(nm) * 2) + 6) >> 8;
216data[off] = ((strlen(nm) * 2) + 6) & 0x00FF;
217
218off += 4;
219uint32_t i=0, l = strlen(nm);
220for(i = 0 ; i < l ; i++, off += 2)
221{
222data[off] = *nm++;
223}
224
225off += 2;
226l = len;
227uint32_t *datalength = (uint32_t*)&data[off];
228*datalength = l + 4;
229off += 4;
230for(i = 0 ; i < l ; i++, off++)
231{
232data[off] = *vl++;
233}
234}
235
236uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
237
238uint8_t *newdata = (uint8_t*)malloc((length + offset));
239if(!newdata)
240return 0;
241if(device->data)
242if(offset > 1)
243memcpy(newdata, device->data, offset);
244
245memcpy(newdata + offset, data, length);
246
247device->length += length;
248device->string->length += length;
249device->numentries++;
250
251if(!device->data)
252device->data = (uint8_t*)malloc(sizeof(uint8_t));
253else
254free(device->data);
255
256free(data);
257device->data = newdata;
258
259return 1;
260}
261
262char *devprop_generate_string(struct DevPropString *string)
263{
264char *buffer = (char*)malloc(string->length * 2);
265char *ptr = buffer;
266
267if(!buffer)
268return NULL;
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{
316if(!string)
317return;
318
319int i;
320for(i = 0; i < string->numentries; i++)
321{
322if(string->entries[i])
323{
324if(string->entries[i]->data)
325{
326free(string->entries[i]->data);
327string->entries[i]->data = NULL;
328}
329free(string->entries[i]);
330string->entries[i] = NULL;
331}
332}
333
334free(string);
335string = NULL;
336}
337
338/* a fine place for this code */
339
340int devprop_add_network_template(struct DevPropDevice *device, uint16_t vendor_id)
341{
342if(!device)
343return 0;
344uint8_t builtin = 0x0;
345if((vendor_id != 0x168c) && (builtin_set == 0))
346{
347builtin_set = 1;
348builtin = 0x01;
349}
350if(!devprop_add_value(device, "built-in", (uint8_t*)&builtin, 1))
351return 0;
352devices_number++;
353return 1;
354}
355
356void set_eth_builtin(pci_dt_t *eth_dev)
357{
358char *devicepath = get_pci_dev_path(eth_dev);
359struct DevPropDevice *device = (struct DevPropDevice*)malloc(sizeof(struct DevPropDevice));
360
361verbose("LAN Controller [%04x:%04x] :: %s\n", eth_dev->vendor_id, eth_dev->device_id, devicepath);
362
363if (!string)
364string = devprop_create_string();
365
366device = devprop_add_device(string, devicepath);
367if(device)
368{
369verbose("Setting up lan keys\n");
370devprop_add_network_template(device, eth_dev->vendor_id);
371stringdata = (uint8_t*)malloc(sizeof(uint8_t) * string->length);
372if(stringdata)
373{
374memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
375stringlength = string->length;
376}
377}
378}
379
380
381struct DevPropDevice *devprop_find_device(char *path)
382{
383 DeviceEntry_t* entry;
384
385 for (entry = TheDeviceRegistry; entry; entry = entry->next)
386if (strcmp(entry->path, path) == 0)
387 return entry->device;
388 return NULL;
389}
390
391

Archive Download this file

Revision: 141