Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 553