Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch/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...)msglog(x)
24#endif
25
26uint32_t devices_number= 1;
27DevPropString *string= NULL;
28uint8_t *stringdata= NULL;
29uint32_t stringlength= 0;
30
31char *efi_inject_get_devprop_string(uint32_t *len)
32{
33if(string) {
34*len = string->length;
35return devprop_generate_string(string);
36}
37verbose("efi_inject_get_devprop_string NULL trying stringdata\n");
38return NULL;
39}
40
41void setupDeviceProperties(Node *node)
42{
43 const char *val;
44 uint8_t *binStr;
45 int cnt, cnt2;
46
47 static char DEVICE_PROPERTIES_PROP[] = "device-properties";
48
49 /* Generate devprop string.
50 */
51 uint32_t strlength;
52 char *string = efi_inject_get_devprop_string(&strlength);
53
54 /* Use the static "device-properties" boot config key contents if available,
55 * otheriwse use the generated one.
56 */
57if (!getValueForKey(kDeviceProperties, &val, &cnt, &bootInfo->chameleonConfig) && string) {
58val = (const char*)string;
59cnt = strlength * 2;
60}
61
62if (cnt > 1) {
63binStr = convertHexStr2Binary(val, &cnt2);
64if (cnt2 > 0) {
65DT__AddProperty(node, DEVICE_PROPERTIES_PROP, cnt2, binStr);
66}
67}
68}
69
70DevPropString *devprop_create_string(void)
71{
72string = (struct DevPropString*)malloc(sizeof(struct DevPropString));
73
74if(string == NULL) {
75return NULL;
76}
77
78memset(string, 0, sizeof(struct DevPropString));
79string->length = 12;
80string->WHAT2 = 0x01000000;
81return string;
82}
83
84DevPropDevice *devprop_add_device(DevPropString *string, char *path)
85{
86DevPropDevice*device = NULL;
87const charpciroot_string[] = "PciRoot(0x";
88const charpci_device_string[] = "Pci(0x";
89
90if (string == NULL || path == NULL) {
91printf("ERROR null device path\n");
92return NULL;
93}
94
95if (strncmp(path, pciroot_string, strlen(pciroot_string))) {
96printf("ERROR parsing device path\n");
97return NULL;
98}
99if (!(device = malloc(sizeof(DevPropDevice)))) {
100printf("ERROR malloc failed\n");
101return NULL;
102}
103
104memset(device, 0, sizeof(DevPropDevice));
105device->acpi_dev_path._UID = getPciRootUID();
106
107int numpaths = 0;
108intx, curr = 0;
109charbuff[] = "00";
110
111for (x = 0; x < strlen(path); x++) {
112if (!strncmp(&path[x], pci_device_string, strlen(pci_device_string))) {
113x+=strlen(pci_device_string);
114curr=x;
115while(path[++x] != ',');
116if(x-curr == 2) {
117sprintf(buff, "%c%c", path[curr], path[curr+1]);
118} else if(x-curr == 1) {
119sprintf(buff, "%c", path[curr]);
120} else {
121printf("ERROR parsing device path\n");
122numpaths = 0;
123break;
124}
125device->pci_dev_path[numpaths].device =ascii_hex_to_int(buff);
126
127x += 3; // 0x
128curr = x;
129while(path[++x] != ')');
130if(x-curr == 2) {
131sprintf(buff, "%c%c", path[curr], path[curr+1]);
132} else if(x-curr == 1) {
133sprintf(buff, "%c", path[curr]);
134} else {
135printf("ERROR parsing device path\n");
136numpaths = 0;
137break;
138}
139device->pci_dev_path[numpaths].function = ascii_hex_to_int(buff); // TODO: find dev from char *path
140
141numpaths++;
142}
143}
144
145if(!numpaths) {
146free(device);
147return NULL;
148}
149
150device->numentries = 0x00;
151
152device->acpi_dev_path.length = 0x0c;
153device->acpi_dev_path.type = 0x02;
154device->acpi_dev_path.subtype = 0x01;
155device->acpi_dev_path._HID = 0xd041030a;
156
157device->num_pci_devpaths = numpaths;
158device->length = 24 + (6*numpaths);
159
160inti;
161
162for(i = 0; i < numpaths; i++) {
163device->pci_dev_path[i].length = 0x06;
164device->pci_dev_path[i].type = 0x01;
165device->pci_dev_path[i].subtype = 0x01;
166}
167
168device->path_end.length = 0x04;
169device->path_end.type = 0x7f;
170device->path_end.subtype = 0xff;
171
172device->string = string;
173device->data = NULL;
174
175if(!string->entries) {
176if (!(string->entries = (struct DevPropDevice**) malloc(sizeof(device) * DEV_PROP_DEVICE_MAX_ENTRIES))) {
177free(device);
178return NULL;
179}
180}
181
182/* FIXME: probably needs bounds checking, as well as error handling in event of malloc failure */
183string->length += device->length;
184string->entries[string->numentries++] = (DevPropDevice*)malloc(sizeof(device));
185string->entries[string->numentries-1] = device;
186
187return device;
188}
189
190int devprop_add_value(DevPropDevice *device, char *nm, uint8_t *vl, uint32_t len)
191{
192
193if(!nm || !vl || !len) {
194return 0;
195}
196uint32_t length = ((strlen(nm) * 2) + len + (2 * sizeof(uint32_t)) + 2);
197uint8_t *data = (uint8_t*)malloc(length);
198
199if(!data) {
200return 0;
201}
202
203memset(data, 0, length);
204uint32_t off= 0;
205data[off+1] = ((strlen(nm) * 2) + 6) >> 8;
206data[off] = ((strlen(nm) * 2) + 6) & 0x00FF;
207
208off += 4;
209uint32_t i=0, l = strlen(nm);
210for(i = 0 ; i < l ; i++, off += 2) {
211data[off] = *nm++;
212}
213
214off += 2;
215l = len;
216uint32_t *datalength = (uint32_t*)&data[off];
217*datalength = (uint32_t)(l + 4);
218off += 4;
219for(i = 0 ; i < l ; i++, off++) {
220data[off] = *vl++;
221}
222
223uint32_t offset = device->length - (24 + (6 * device->num_pci_devpaths));
224
225uint8_t *newdata = (uint8_t*)malloc((length + offset));
226if(!newdata) {
227return 0;
228}
229if(device->data) {
230if(offset > 1) {
231memcpy(newdata, device->data, offset);
232}
233}
234
235memcpy(newdata + offset, data, length);
236
237device->length += length;
238device->string->length += length;
239device->numentries++;
240
241if(!device->data) {
242device->data = (uint8_t*)malloc(sizeof(uint8_t));
243} else {
244free(device->data);
245}
246
247free(data);
248device->data = newdata;
249
250return 1;
251}
252
253// devprop_generate_string optimized by cparm
254char *devprop_generate_string(DevPropString *string)
255{
256int len = string->length * 2;
257char *buffer = (char*)malloc(len);
258char *ptr = buffer;
259
260if(!buffer)
261{
262return NULL;
263}
264
265snprintf(buffer, len, "%08x%08x%04x%04x", dp_swap32(string->length), string->WHAT2,
266dp_swap16(string->numentries), string->WHAT3);
267buffer += 24;
268len -= 24;
269int i = 0, x = 0;
270
271while(i < string->numentries)
272{
273 if (!(i < DEV_PROP_DEVICE_MAX_ENTRIES))
274{
275 break;
276 }
277
278 if(!len)
279{
280 break;
281 }
282
283snprintf(buffer, len, "%08x%04x%04x", dp_swap32(string->entries[i]->length),
284dp_swap16(string->entries[i]->numentries), string->entries[i]->WHAT2);
285
286buffer += 16;
287len -= 16;
288snprintf(buffer, len, "%02x%02x%04x%08x%08x", string->entries[i]->acpi_dev_path.type,
289string->entries[i]->acpi_dev_path.subtype,
290dp_swap16(string->entries[i]->acpi_dev_path.length),
291string->entries[i]->acpi_dev_path._HID,
292dp_swap32(string->entries[i]->acpi_dev_path._UID));
293
294buffer += 24;
295len -= 24;
296for(x = 0;x < string->entries[i]->num_pci_devpaths; x++)
297{
298if(!len)
299{
300break;
301}
302snprintf(buffer, len, "%02x%02x%04x%02x%02x", string->entries[i]->pci_dev_path[x].type,
303string->entries[i]->pci_dev_path[x].subtype,
304dp_swap16(string->entries[i]->pci_dev_path[x].length),
305string->entries[i]->pci_dev_path[x].function,
306string->entries[i]->pci_dev_path[x].device);
307buffer += 12;
308len -= 12;
309}
310
311if(!len)
312{
313break;
314}
315
316snprintf(buffer, len, "%02x%02x%04x", string->entries[i]->path_end.type,
317string->entries[i]->path_end.subtype,
318dp_swap16(string->entries[i]->path_end.length));
319
320buffer += 8;
321len -= 8;
322uint8_t *dataptr = string->entries[i]->data;
323for(x = 0; (uint32_t)x < (string->entries[i]->length) - (24 + (6 * string->entries[i]->num_pci_devpaths)) ; x++)
324{
325if(!len)
326{
327break;
328}
329snprintf(buffer, len, "%02x", *dataptr++);
330buffer += 2;
331len -= 2;
332}
333i++;
334}
335return ptr;
336}
337
338void devprop_free_string(DevPropString *string)
339{
340
341if(!string) {
342return;
343}
344
345int i;
346for(i = 0; i < string->numentries; i++) {
347if(string->entries[i]) {
348if(string->entries[i]->data) {
349free(string->entries[i]->data);
350string->entries[i]->data = NULL;
351}
352free(string->entries[i]);
353string->entries[i] = NULL;
354}
355}
356
357free(string);
358string = NULL;
359}
360
361/* ======================================================= */
362
363
364/*******************************************************************
365 * Decodes a sequence of 'len' hexadecimal chars from 'hex' into *
366 * a binary. returns -1 in case of error (i.e. badly formed chars) *
367 *******************************************************************/
368int hex2bin(const char *hex, uint8_t *bin, int len)
369{
370char*p;
371inti;
372charbuf[3];
373
374if (hex == NULL || bin == NULL || len <= 0 || strlen(hex) != len * 2) {
375printf("[ERROR] bin2hex input error\n");
376return -1;
377}
378
379buf[2] = '\0';
380p = (char *) hex;
381
382for (i = 0; i < len; i++) {
383if (p[0] == '\0' || p[1] == '\0' || !isxdigit(p[0]) || !isxdigit(p[1])) {
384printf("[ERROR] bin2hex '%s' syntax error\n", hex);
385return -2;
386}
387buf[0] = *p++;
388buf[1] = *p++;
389bin[i] = (unsigned char) strtoul(buf, NULL, 16);
390}
391return 0;
392}
393
394/* ======================================================= */
395
396/* a fine place for this code */
397
398

Archive Download this file

Revision: 2457