Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 1146