Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 1174