Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 2051