Chameleon

Chameleon Svn Source Tree

Root/branches/valv/i386/libsaio/device_inject.c

  • Property svn:executable set to
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->bootConfig) && 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)
77return NULL;
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;
88const charpciroot_string[] = "PciRoot(0x";
89const charpci_device_string[] = "Pci(0x";
90
91if (string == NULL || path == NULL) {
92return NULL;
93}
94device = malloc(sizeof(struct DevPropDevice));
95
96if (strncmp(path, pciroot_string, strlen(pciroot_string))) {
97printf("ERROR parsing device path\n");
98return NULL;
99}
100
101memset(device, 0, sizeof(struct DevPropDevice));
102device->acpi_dev_path._UID = getPciRootUID();
103
104int numpaths = 0;
105intx, curr = 0;
106charbuff[] = "00";
107
108for (x = 0; x < strlen(path); x++) {
109if (!strncmp(&path[x], pci_device_string, strlen(pci_device_string))) {
110x+=strlen(pci_device_string);
111curr=x;
112while(path[++x] != ',');
113if(x-curr == 2)
114sprintf(buff, "%c%c", path[curr], path[curr+1]);
115else if(x-curr == 1)
116sprintf(buff, "%c", path[curr]);
117else
118{
119printf("ERROR parsing device path\n");
120numpaths = 0;
121break;
122}
123device->pci_dev_path[numpaths].device =ascii_hex_to_int(buff);
124
125x += 3; // 0x
126curr = x;
127while(path[++x] != ')');
128if(x-curr == 2)
129sprintf(buff, "%c%c", path[curr], path[curr+1]);
130else if(x-curr == 1)
131sprintf(buff, "%c", path[curr]);
132else
133{
134printf("ERROR parsing device path\n");
135numpaths = 0;
136break;
137}
138device->pci_dev_path[numpaths].function = ascii_hex_to_int(buff); // TODO: find dev from char *path
139
140numpaths++;
141}
142}
143
144if(!numpaths)
145return NULL;
146
147device->numentries = 0x00;
148
149device->acpi_dev_path.length = 0x0c;
150device->acpi_dev_path.type = 0x02;
151device->acpi_dev_path.subtype = 0x01;
152device->acpi_dev_path._HID = 0xd041030a;
153
154device->num_pci_devpaths = numpaths;
155device->length = 24 + (6*numpaths);
156
157inti;
158
159for(i = 0; i < numpaths; i++)
160{
161device->pci_dev_path[i].length = 0x06;
162device->pci_dev_path[i].type = 0x01;
163device->pci_dev_path[i].subtype = 0x01;
164}
165
166device->path_end.length = 0x04;
167device->path_end.type = 0x7f;
168device->path_end.subtype = 0xff;
169
170device->string = string;
171device->data = NULL;
172string->length += device->length;
173
174if(!string->entries)
175if((string->entries = (struct DevPropDevice**)malloc(sizeof(device)))== NULL)
176return 0;
177
178string->entries[string->numentries++] = (struct DevPropDevice*)malloc(sizeof(device));
179string->entries[string->numentries-1] = device;
180
181return device;
182}
183
184int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
185{
186
187if(!nm || !vl || !len)
188return 0;
189
190uint32_t length = ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
191uint8_t *data = (uint8_t*)malloc(length);
192{
193if(!data)
194return 0;
195
196memset(data, 0, length);
197uint32_t off= 0;
198data[off+1] = ((strlen(nm) * 2) + 6) >> 8;
199data[off] = ((strlen(nm) * 2) + 6) & 0x00FF;
200
201off += 4;
202uint32_t i=0, l = strlen(nm);
203for(i = 0 ; i < l ; i++, off += 2)
204{
205data[off] = *nm++;
206}
207
208off += 2;
209l = len;
210uint32_t *datalength = (uint32_t*)&data[off];
211*datalength = l + 4;
212off += 4;
213for(i = 0 ; i < l ; i++, off++)
214{
215data[off] = *vl++;
216}
217}
218
219uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
220
221uint8_t *newdata = (uint8_t*)malloc((length + offset));
222if(!newdata)
223return 0;
224if(device->data)
225if(offset > 1)
226memcpy(newdata, device->data, offset);
227
228memcpy(newdata + offset, data, length);
229
230device->length += length;
231device->string->length += length;
232device->numentries++;
233
234if(!device->data)
235device->data = (uint8_t*)malloc(sizeof(uint8_t));
236else
237free(device->data);
238
239free(data);
240device->data = newdata;
241
242return 1;
243}
244
245char *devprop_generate_string(struct DevPropString *string)
246{
247char *buffer = (char*)malloc(string->length * 2);
248char *ptr = buffer;
249
250if(!buffer)
251return NULL;
252
253sprintf(buffer, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2,
254dp_swap16(string->numentries), string->WHAT3);
255buffer += 24;
256int i = 0, x = 0;
257
258while(i < string->numentries)
259{
260sprintf(buffer, "%08x%04x%04x", dp_swap32(string->entries[i]->length),
261dp_swap16(string->entries[i]->numentries), string->entries[i]->WHAT2);
262
263buffer += 16;
264sprintf(buffer, "%02x%02x%04x%08x%08x", string->entries[i]->acpi_dev_path.type,
265string->entries[i]->acpi_dev_path.subtype,
266dp_swap16(string->entries[i]->acpi_dev_path.length),
267string->entries[i]->acpi_dev_path._HID,
268dp_swap32(string->entries[i]->acpi_dev_path._UID));
269
270buffer += 24;
271for(x=0;x < string->entries[i]->num_pci_devpaths; x++)
272{
273sprintf(buffer, "%02x%02x%04x%02x%02x", string->entries[i]->pci_dev_path[x].type,
274string->entries[i]->pci_dev_path[x].subtype,
275dp_swap16(string->entries[i]->pci_dev_path[x].length),
276string->entries[i]->pci_dev_path[x].function,
277string->entries[i]->pci_dev_path[x].device);
278buffer += 12;
279}
280
281sprintf(buffer, "%02x%02x%04x", string->entries[i]->path_end.type,
282string->entries[i]->path_end.subtype,
283dp_swap16(string->entries[i]->path_end.length));
284
285buffer += 8;
286uint8_t *dataptr = string->entries[i]->data;
287for(x = 0; x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++)
288{
289sprintf(buffer, "%02x", *dataptr++);
290buffer += 2;
291}
292i++;
293}
294return ptr;
295}
296
297void devprop_free_string(struct DevPropString *string)
298{
299if(!string)
300return;
301
302int i;
303for(i = 0; i < string->numentries; i++)
304{
305if(string->entries[i])
306{
307if(string->entries[i]->data)
308{
309free(string->entries[i]->data);
310string->entries[i]->data = NULL;
311}
312free(string->entries[i]);
313string->entries[i] = NULL;
314}
315}
316
317free(string);
318string = NULL;
319}
320
321/* a fine place for this code */
322
323int devprop_add_network_template(struct DevPropDevice *device, uint16_t vendor_id)
324{
325if(!device)
326return 0;
327uint8_t builtin = 0x0;
328if((vendor_id != 0x168c) && (builtin_set == 0))
329{
330builtin_set = 1;
331builtin = 0x01;
332}
333if(!devprop_add_value(device, "built-in", (uint8_t*)&builtin, 1))
334return 0;
335devices_number++;
336return 1;
337}
338
339void set_eth_builtin(pci_dt_t *eth_dev)
340{
341char *devicepath = get_pci_dev_path(eth_dev);
342struct DevPropDevice *device = (struct DevPropDevice*)malloc(sizeof(struct DevPropDevice));
343
344verbose("LAN Controller [%04x:%04x] :: %s\n", eth_dev->vendor_id, eth_dev->device_id, devicepath);
345
346if (!string)
347string = devprop_create_string();
348
349device = devprop_add_device(string, devicepath);
350if(device)
351{
352verbose("Setting up lan keys\n");
353devprop_add_network_template(device, eth_dev->vendor_id);
354stringdata = (uint8_t*)malloc(sizeof(uint8_t) * string->length);
355if(stringdata)
356{
357memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
358stringlength = string->length;
359}
360}
361}
362

Archive Download this file

Revision: 665