Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/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 "bootstruct.h"
10#include "pci.h"
11#include "device_inject.h"
12#include "convert.h"
13#include "platform.h"
14#include "modules.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
26static char *efi_inject_get_devprop_string(uint32_t *len);
27void setupDeviceProperties_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6);
28static EFI_STATUS setupDeviceProperties(Node *node);
29
30struct DevPropString *devprop_create_string(void)
31{
32struct DevPropString *string = (struct DevPropString*)malloc(sizeof(struct DevPropString));
33
34if(string == NULL)
35{
36return NULL;
37}
38
39memset(string, 0, sizeof(struct DevPropString));
40string->length = 12;
41string->WHAT2 = 0x01000000;
42return string;
43}
44
45struct DevPropDevice *devprop_make_device(pci_dt_t *pci_dt)
46{
47struct DevPropDevice*device;
48 int numpaths = 0;
49
50pci_dt_t*current;
51pci_dt_t*end;
52
53end = (pci_dt_t *)(uint32_t)get_env(envPCIRootDev);
54
55device = malloc(sizeof(struct DevPropDevice));
56if (!device) {
57 return NULL;
58 }
59 memset(device, 0, sizeof(struct DevPropDevice));
60
61device->acpi_dev_path._UID = getPciRootUID();
62while (end != pci_dt)
63{
64current = pci_dt;
65while (current->parent != end)
66current = current->parent;
67end = current;
68
69{
70 device->pci_dev_path[numpaths].device =(uint8_t)current->dev.bits.dev;
71device->pci_dev_path[numpaths].function = (uint8_t)current->dev.bits.func;
72 numpaths++;
73}
74
75}
76
77if(!numpaths)
78{
79 printf("ERROR parsing device path\n");
80 free(device);
81return NULL;
82}
83
84device->numentries = 0x00;
85
86device->acpi_dev_path.length = 0x0c;
87device->acpi_dev_path.type = 0x02;
88device->acpi_dev_path.subtype = 0x01;
89device->acpi_dev_path._HID = 0xd041030a;
90
91device->num_pci_devpaths = numpaths;
92device->length = 24 + (6*numpaths);
93
94inti;
95
96for(i = 0; i < numpaths; i++)
97{
98device->pci_dev_path[i].length = 0x06;
99device->pci_dev_path[i].type = 0x01;
100device->pci_dev_path[i].subtype = 0x01;
101}
102
103device->path_end.length = 0x04;
104device->path_end.type = 0x7f;
105device->path_end.subtype = 0xff;
106
107device->data = NULL;
108
109return device;
110}
111
112struct DevPropDevice *devprop_add_device(struct DevPropString *string, pci_dt_t * pci_dt)
113{
114struct DevPropDevice*device;
115
116if (string == NULL || pci_dt == NULL) {
117return NULL;
118}
119device = devprop_make_device(pci_dt);
120if (!device) {
121 return NULL;
122 }
123
124device->string = string;
125string->length += device->length;
126
127if(!string->entries)
128{
129if((string->entries = (struct DevPropDevice*)malloc(sizeof(struct DevPropDevice) * MAX_STRING_NUM_ENTRIES))== NULL)
130{
131 printf("ERROR parsing device path 2\n");
132
133 free(device);
134return NULL;
135}
136}
137struct DevPropDevice **string_entries_arrey = (struct DevPropDevice **) string->entries;
138
139if ((string->numentries+1) < MAX_STRING_NUM_ENTRIES)
140 {
141string->numentries++;
142
143 }
144 else
145 {
146 free(string->entries);
147 free(device);
148 return NULL;
149 }
150
151string_entries_arrey[string->numentries-1] = device;
152
153return device;
154}
155
156int devprop_add_value(struct DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
157{
158
159if(!nm || !vl || !len)
160{
161return 0;
162}
163
164uint32_t length = ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
165uint8_t *data = (uint8_t*)malloc(length);
166
167if(!data)
168 {
169 return 0;
170 }
171
172 memset(data, 0, length);
173 uint32_t off= 0;
174 data[off+1] = ((strlen(nm) * 2) + 6) >> 8;
175 data[off] = ((strlen(nm) * 2) + 6) & 0x00FF;
176
177 off += 4;
178 uint32_t i=0, l = strlen(nm);
179 for(i = 0 ; i < l ; i++, off += 2)
180 {
181 data[off] = *nm++;
182 }
183
184 off += 2;
185 l = len;
186 uint32_t *datalength = (uint32_t*)&data[off];
187 *datalength = l + 4;
188 off += 4;
189 for(i = 0 ; i < l ; i++, off++)
190 {
191 data[off] = *vl++;
192 }
193
194uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
195
196uint8_t *newdata = (uint8_t*)malloc((length + offset));
197if(!newdata)
198{
199return 0;
200}
201if(device->data)
202{
203if(offset > 1)
204{
205memcpy(newdata, device->data, offset);
206}
207}
208
209memcpy(newdata + offset, data, length);
210
211device->length += length;
212device->string->length += length;
213device->numentries++;
214
215if(device->data)
216{
217free(device->data);
218}
219
220free(data);
221device->data = newdata;
222
223return 1;
224}
225
226char *devprop_generate_string(struct DevPropString *string)
227{
228 int len = string->length * 2;
229char *buffer = (char*)malloc(len);
230char *ptr = buffer;
231
232if(!buffer)
233{
234return NULL;
235}
236
237snprintf(buffer, len, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2,
238 dp_swap16(string->numentries), string->WHAT3);
239buffer += 24;
240 len -= 24;
241int i = 0, x = 0;
242
243struct DevPropDevice **string_entries_arrey = (struct DevPropDevice **) string->entries;
244
245while(i < string->numentries)
246{
247if (!(i<MAX_STRING_NUM_ENTRIES))
248 {
249 break;
250 }
251 if (!len) {
252 break;
253 }
254snprintf(buffer, len, "%08x%04x%04x", dp_swap32(string_entries_arrey[i]->length),
255 dp_swap16(string_entries_arrey[i]->numentries), string_entries_arrey[i]->WHAT2);
256
257buffer += 16;
258 len -= 16;
259snprintf(buffer, len,"%02x%02x%04x%08x%08x", string_entries_arrey[i]->acpi_dev_path.type,
260 string_entries_arrey[i]->acpi_dev_path.subtype,
261 dp_swap16(string_entries_arrey[i]->acpi_dev_path.length),
262 string_entries_arrey[i]->acpi_dev_path._HID,
263 dp_swap32(string_entries_arrey[i]->acpi_dev_path._UID));
264
265buffer += 24;
266 len -= 24;
267for(x=0;x < string_entries_arrey[i]->num_pci_devpaths; x++)
268{
269 if (!len) {
270 break;
271 }
272snprintf(buffer, len,"%02x%02x%04x%02x%02x", string_entries_arrey[i]->pci_dev_path[x].type,
273 string_entries_arrey[i]->pci_dev_path[x].subtype,
274 dp_swap16(string_entries_arrey[i]->pci_dev_path[x].length),
275 string_entries_arrey[i]->pci_dev_path[x].function,
276 string_entries_arrey[i]->pci_dev_path[x].device);
277buffer += 12;
278 len -= 12;
279}
280if (!len) {
281 break;
282 }
283snprintf(buffer, len,"%02x%02x%04x", string_entries_arrey[i]->path_end.type,
284 string_entries_arrey[i]->path_end.subtype,
285 dp_swap16(string_entries_arrey[i]->path_end.length));
286
287buffer += 8;
288 len -= 8;
289uint8_t *dataptr = string_entries_arrey[i]->data;
290for(x = 0; (uint32_t)x < (string_entries_arrey[i]->length) - (24 + (6 * string_entries_arrey[i]->num_pci_devpaths)) ; x++)
291{
292 if (!len) {
293 break;
294 }
295snprintf(buffer, len, "%02x", *dataptr++);
296buffer += 2;
297 len -= 2;
298}
299i++;
300}
301return ptr;
302}
303
304void devprop_free_string(struct DevPropString *string)
305{
306if(!string)
307{
308return;
309}
310
311int i;
312
313struct DevPropDevice **string_entries_arrey = (struct DevPropDevice **) string->entries;
314
315for(i = 0; i < string->numentries; i++)
316{
317 if (!(i<MAX_STRING_NUM_ENTRIES))
318 {
319 break;
320 }
321if(string_entries_arrey[i])
322{
323if(string_entries_arrey[i]->data)
324{
325free(string_entries_arrey[i]->data);
326string_entries_arrey[i]->data = NULL;
327}
328}
329}
330
331 free(string->entries);
332 string->entries = NULL;
333
334free(string);
335string = NULL;
336}
337
338static char *efi_inject_get_devprop_string(uint32_t *len)
339{
340 struct DevPropString *string = (struct DevPropString *)(uint32_t)get_env(envEFIString);
341
342if(string)
343{
344*len = string->length;
345return devprop_generate_string(string);
346}
347return NULL;
348}
349
350static EFI_STATUS setupDeviceProperties(Node *node)
351{
352const char *val;
353uint8_t *binStr;
354 uint8_t *kbinStr;
355
356int cnt = 0, cnt2 = 0;
357
358static char DEVICE_PROPERTIES_PROP[] = "device-properties";
359
360/* Generate devprop string.
361 */
362uint32_t strlength = 0;
363char *string = efi_inject_get_devprop_string(&strlength);
364if (string == NULL) {
365DBG("efi_inject_get_devprop_string NULL trying stringdata\n");
366return EFI_NO_MEDIA;
367}
368
369val = (const char*)string;
370cnt = strlength * 2;
371
372if (cnt > 1)
373{
374binStr = convertHexStr2Binary(val, &cnt2);
375
376 if (cnt2 > 0)
377 {
378 kbinStr = (uint8_t*)AllocateKernelMemory(cnt2);
379if (kbinStr)
380{
381bcopy(binStr,kbinStr,cnt2);
382DT__AddProperty(node, DEVICE_PROPERTIES_PROP, cnt2, kbinStr);
383return EFI_SUCCESS;
384}
385 }
386}
387return EFI_DEVICE_ERROR;
388
389}
390
391void setupDeviceProperties_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6)
392{
393Node *node = (Node *)arg1;
394EFI_STATUS *ret = (EFI_STATUS*)arg2;
395*ret = setupDeviceProperties(node);
396}
397
398void register_device_inject(void)
399{
400register_one_callback("setupDeviceProperties", &setupDeviceProperties_hook);
401}

Archive Download this file

Revision: 2118