Chameleon Applications

Chameleon Applications Svn Source Tree

Root/branches/iFabio/i386/libsaio/device_tree.c

Source at commit 214 created 13 years 5 months ago.
By ifabio, update to chameleon trunk 630, and now the pakage folder is the same as blackosx branch, also add Icon "building" into buildpkg script, and add mint theme info into the English localizable.strings.
1/*
2 * Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved.
3 */
4
5#if 1
6/*
7
8 Structures for a Flattened Device Tree
9 */
10
11#define kPropNameLength 32
12
13typedef struct DeviceTreeNodeProperty {
14 char name[kPropNameLength]; // NUL terminated property name
15 unsigned long length; // Length (bytes) of folloing prop value
16 // unsigned long value[1]; // Variable length value of property
17 // Padded to a multiple of a longword?
18} DeviceTreeNodeProperty;
19
20typedef struct OpaqueDTEntry {
21 unsigned long nProperties; // Number of props[] elements (0 => end)
22 unsigned long nChildren; // Number of children[] elements
23 // DeviceTreeNodeProperty props[];// array size == nProperties
24 // DeviceTreeNode children[]; // array size == nChildren
25} DeviceTreeNode;
26
27typedef char DTPropertyNameBuf[32];
28/* Entry Name Definitions (Entry Names are C-Strings)*/
29enum {
30 kDTMaxEntryNameLength = 31 /* Max length of a C-String Entry Name (terminator not included) */
31};
32
33/* length of DTEntryNameBuf = kDTMaxEntryNameLength +1*/
34typedef char DTEntryNameBuf[32];
35#endif
36
37#include "libsaio.h"
38#include "device_tree.h"
39
40#if DEBUG
41#define DPRINTF(args...) printf(args)
42void
43DT__PrintTree(Node *node);
44#else
45#define DPRINTF(args...)
46#endif
47
48
49#define RoundToLong(x)(((x) + 3) & ~3)
50
51static struct _DTSizeInfo {
52 uint32_t numNodes;
53 uint32_t numProperties;
54 uint32_t totalPropertySize;
55} DTInfo;
56
57#define kAllocSize 4096
58
59static Node *rootNode;
60
61static Node *freeNodes, *allocedNodes;
62static Property *freeProperties, *allocedProperties;
63
64Property *
65DT__AddProperty(Node *node, const char *name, uint32_t length, void *value)
66{
67 Property *prop;
68
69 DPRINTF("DT__AddProperty([Node '%s'], '%s', %d, 0x%x)\n", DT__GetName(node), name, length, value);
70 if (freeProperties == NULL) {
71 void *buf = malloc(kAllocSize);
72 int i;
73
74 DPRINTF("Allocating more free properties\n");
75 if (buf == 0) return 0;
76 bzero(buf, kAllocSize);
77 // Use the first property to record the allocated buffer
78 // for later freeing.
79 prop = (Property *)buf;
80 prop->next = allocedProperties;
81 allocedProperties = prop;
82 prop->value = buf;
83 prop++;
84 for (i=1; i<(kAllocSize / sizeof(Property)); i++) {
85 prop->next = freeProperties;
86 freeProperties = prop;
87 prop++;
88 }
89 }
90 prop = freeProperties;
91 freeProperties = prop->next;
92
93 prop->name = name;
94 prop->length = length;
95 prop->value = value;
96
97 // Always add to end of list
98 if (node->properties == 0) {
99 node->properties = prop;
100 } else {
101 node->last_prop->next = prop;
102 }
103 node->last_prop = prop;
104 prop->next = 0;
105
106 DPRINTF("Done [0x%x]\n", prop);
107
108 DTInfo.numProperties++;
109 DTInfo.totalPropertySize += RoundToLong(length);
110
111 return prop;
112}
113
114Node *
115DT__AddChild(Node *parent, const char *name)
116{
117 Node *node;
118
119 if (freeNodes == NULL) {
120 void *buf = malloc(kAllocSize);
121 int i;
122
123 DPRINTF("Allocating more free nodes\n");
124 if (buf == 0) return 0;
125 bzero(buf, kAllocSize);
126 node = (Node *)buf;
127 // Use the first node to record the allocated buffer
128 // for later freeing.
129 node->next = allocedNodes;
130 allocedNodes = node;
131 node->children = (Node *)buf;
132 node++;
133 for (i=1; i<(kAllocSize / sizeof(Node)); i++) {
134 node->next = freeNodes;
135 freeNodes = node;
136 node++;
137 }
138 }
139 DPRINTF("DT__AddChild(0x%x, '%s')\n", parent, name);
140 node = freeNodes;
141 freeNodes = node->next;
142 DPRINTF("Got free node 0x%x\n", node);
143 DPRINTF("prop = 0x%x, children = 0x%x, next = 0x%x\n", node->properties, node->children, node->next);
144
145 if (parent == NULL) {
146 rootNode = node;
147 node->next = 0;
148 } else {
149 node->next = parent->children;
150 parent->children = node;
151 }
152 DTInfo.numNodes++;
153 DT__AddProperty(node, "name", strlen(name) + 1, (void *) name);
154 return node;
155}
156
157void
158DT__FreeProperty(Property *prop)
159{
160 prop->next = freeProperties;
161 freeProperties = prop;
162}
163void
164DT__FreeNode(Node *node)
165{
166 node->next = freeNodes;
167 freeNodes = node;
168}
169
170void
171DT__Initialize(void)
172{
173 DPRINTF("DT__Initialize\n");
174
175 freeNodes = 0;
176 allocedNodes = 0;
177 freeProperties = 0;
178 allocedProperties = 0;
179
180 DTInfo.numNodes = 0;
181 DTInfo.numProperties = 0;
182 DTInfo.totalPropertySize = 0;
183
184 rootNode = DT__AddChild(NULL, "/");
185 DPRINTF("DT__Initialize done\n");
186}
187
188/*
189 * Free up memory used by in-memory representation
190 * of device tree.
191 */
192void
193DT__Finalize(void)
194{
195 Node *node;
196 Property *prop;
197
198 DPRINTF("DT__Finalize\n");
199 for (prop = allocedProperties; prop != NULL; prop = prop->next) {
200 free(prop->value);
201 }
202 allocedProperties = NULL;
203 freeProperties = NULL;
204
205 for (node = allocedNodes; node != NULL; node = node->next) {
206 free((void *)node->children);
207 }
208 allocedNodes = NULL;
209 freeNodes = NULL;
210 rootNode = NULL;
211
212 // XXX leaks any created strings
213
214 DTInfo.numNodes = 0;
215 DTInfo.numProperties = 0;
216 DTInfo.totalPropertySize = 0;
217}
218
219static void *
220FlattenNodes(Node *node, void *buffer)
221{
222 Property *prop;
223 DeviceTreeNode *flatNode;
224 DeviceTreeNodeProperty *flatProp;
225 int count;
226
227 if (node == 0) return buffer;
228
229 flatNode = (DeviceTreeNode *)buffer;
230 buffer += sizeof(DeviceTreeNode);
231
232 for (count = 0, prop = node->properties; prop != 0; count++, prop = prop->next) {
233 flatProp = (DeviceTreeNodeProperty *)buffer;
234 strcpy(flatProp->name, prop->name);
235 flatProp->length = prop->length;
236 buffer += sizeof(DeviceTreeNodeProperty);
237 bcopy(prop->value, buffer, prop->length);
238 buffer += RoundToLong(prop->length);
239 }
240 flatNode->nProperties = count;
241
242 for (count = 0, node = node->children; node != 0; count++, node = node->next) {
243 buffer = FlattenNodes(node, buffer);
244 }
245 flatNode->nChildren = count;
246
247 return buffer;
248}
249
250/*
251 * Flatten the in-memory representation of the device tree
252 * into a binary DT block.
253 * To get the buffer size needed, call with result = 0.
254 * To have a buffer allocated for you, call with *result = 0.
255 * To use your own buffer, call with *result = &buffer.
256 */
257
258void
259DT__FlattenDeviceTree(void **buffer_p, uint32_t *length)
260{
261 uint32_t totalSize;
262 void *buf;
263
264 DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length);
265#if DEBUG
266 if (buffer_p) DT__PrintTree(rootNode);
267#endif
268
269 totalSize = DTInfo.numNodes * sizeof(DeviceTreeNode) +
270 DTInfo.numProperties * sizeof(DeviceTreeNodeProperty) +
271 DTInfo.totalPropertySize;
272
273 DPRINTF("Total size 0x%x\n", totalSize);
274 if (buffer_p != 0) {
275 if (totalSize == 0) {
276 buf = 0;
277 } else {
278 if (*buffer_p == 0) {
279 buf = malloc(totalSize);
280 } else {
281 buf = *buffer_p;
282 }
283 bzero(buf, totalSize);
284
285 FlattenNodes(rootNode, buf);
286 }
287 *buffer_p = buf;
288 }
289 if (length)
290 *length = totalSize;
291}
292
293char *
294DT__GetName(Node *node)
295{
296 Property *prop;
297
298 //DPRINTF("DT__GetName(0x%x)\n", node);
299 //DPRINTF("Node properties = 0x%x\n", node->properties);
300 for (prop = node->properties; prop; prop = prop->next) {
301 //DPRINTF("Prop '%s'\n", prop->name);
302 if (strcmp(prop->name, "name") == 0) {
303 return prop->value;
304 }
305 }
306 //DPRINTF("DT__GetName returns 0\n");
307 return "(null)";
308}
309
310Node *
311DT__FindNode(const char *path, bool createIfMissing)
312{
313 Node *node, *child;
314 DTPropertyNameBuf nameBuf;
315 char *bp;
316 int i;
317
318 DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing);
319
320 // Start at root
321 node = rootNode;
322 DPRINTF("root = 0x%x\n", rootNode);
323
324 while (node) {
325 // Skip leading slash
326 while (*path == '/') path++;
327
328 for (i=0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++) *bp = *path;
329 *bp = '\0';
330
331 if (nameBuf[0] == '\0') {
332 // last path entry
333 break;
334 }
335 DPRINTF("Node '%s'\n", nameBuf);
336
337 for (child = node->children; child != 0; child = child->next) {
338 DPRINTF("Child 0x%x\n", child);
339 if (strcmp(DT__GetName(child), nameBuf) == 0) {
340 break;
341 }
342 }
343 if (child == 0 && createIfMissing) {
344 DPRINTF("Creating node\n");
345 char *str = malloc(strlen(nameBuf) + 1);
346 // XXX this will leak
347 strcpy(str, nameBuf);
348
349 child = DT__AddChild(node, str);
350 }
351 node = child;
352 }
353 return node;
354}
355
356#if DEBUG
357
358void
359DT__PrintNode(Node *node, int level)
360{
361 char spaces[10], *cp = spaces;
362 Property *prop;
363
364 if (level > 9) level = 9;
365 while (level--) *cp++ = ' ';
366 *cp = '\0';
367
368 printf("%s===Node===\n", spaces);
369 for (prop = node->properties; prop; prop = prop->next) {
370 char c = *((char *)prop->value);
371 if (prop->length < 64 && (
372 strcmp(prop->name, "name") == 0 ||
373 (c >= '0' && c <= '9') ||
374 (c >= 'a' && c <= 'z') ||
375 (c >= 'A' && c <= 'Z') || c == '_')) {
376 printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value);
377 } else {
378 printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length);
379 }
380 }
381 printf("%s==========\n", spaces);
382}
383
384static void
385_PrintTree(Node *node, int level)
386{
387 DT__PrintNode(node, level);
388 level++;
389 for (node = node->children; node; node = node->next)
390 _PrintTree(node, level);
391}
392
393void
394DT__PrintTree(Node *node)
395{
396 if (node == 0) node = rootNode;
397 _PrintTree(node, 0);
398}
399
400void
401DT__PrintFlattenedNode(DTEntry entry, int level)
402{
403 char spaces[10], *cp = spaces;
404 DTPropertyIterator propIter;
405 char *name;
406 void *prop;
407 int propSize;
408
409 if (level > 9) level = 9;
410 while (level--) *cp++ = ' ';
411 *cp = '\0';
412
413 printf("%s===Entry %p===\n", spaces, entry);
414 if (kSuccess != DTCreatePropertyIterator(entry, &propIter)) {
415 printf("Couldn't create property iterator\n");
416 return;
417 }
418 while( kSuccess == DTIterateProperties( propIter, &name)) {
419 if( kSuccess != DTGetProperty( entry, name, &prop, &propSize ))
420 continue;
421 printf("%s Property %s = %s\n", spaces, name, prop);
422 }
423 DTDisposePropertyIterator(propIter);
424
425 printf("%s==========\n", spaces);
426}
427
428static void
429_PrintFlattenedTree(DTEntry entry, int level)
430{
431 DTEntryIterator entryIter;
432
433 PrintFlattenedNode(entry, level);
434
435 if (kSuccess != DTCreateEntryIterator(entry, &entryIter)) {
436 printf("Couldn't create entry iterator\n");
437 return;
438 }
439 level++;
440 while (kSuccess == DTIterateEntries( entryIter, &entry )) {
441 _PrintFlattenedTree(entry, level);
442 }
443 DTDisposeEntryIterator(entryIter);
444}
445
446void
447DT__PrintFlattenedTree(DTEntry entry)
448{
449 _PrintFlattenedTree(entry, 0);
450}
451
452
453int
454main(int argc, char **argv)
455{
456 DTEntry dtEntry;
457 DTPropertyIterator propIter;
458 DTEntryIterator entryIter;
459 void*prop;
460 intpropSize;
461 char*name;
462 void *flatTree;
463 uint32_t flatSize;
464
465 Node *node;
466
467 node = AddChild(NULL, "device-tree");
468 AddProperty(node, "potato", 4, "foo");
469 AddProperty(node, "chemistry", 4, "bar");
470 AddProperty(node, "physics", 4, "baz");
471
472 node = AddChild(node, "dev");
473 AddProperty(node, "one", 4, "one");
474 AddProperty(node, "two", 4, "two");
475 AddProperty(node, "three", 6, "three");
476
477 node = AddChild(rootNode, "foo");
478 AddProperty(node, "aaa", 4, "aab");
479 AddProperty(node, "bbb", 4, "bbc");
480 AddProperty(node, "cccc", 6, "ccccd");
481
482 node = FindNode("/this/is/a/test", 1);
483 AddProperty(node, "dddd", 12, "abcdefghijk");
484
485 printf("In-memory tree:\n\n");
486
487 PrintTree(rootNode);
488
489 FlattenDeviceTree(&flatTree, &flatSize);
490
491 printf("Flat tree = %p, size %d\n", flatTree, flatSize);
492
493 dtEntry = (DTEntry)flatTree;
494
495 printf("\n\nPrinting flat tree\n\n");
496
497 DTInit(dtEntry);
498
499 PrintFlattenedTree((DTEntry)flatTree);
500#if 0
501 printf("=== Entry %p ===\n", dtEntry);
502 if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) {
503 printf("Couldn't create property iterator\n");
504 return 1;
505 }
506 while( kSuccess == DTIterateProperties( propIter, &name)) {
507 if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
508 continue;
509 printf(" Property %s = %s\n", name, prop);
510 }
511 DTDisposePropertyIterator(propIter);
512 printf("========\n");
513
514 if (kSuccess != DTCreateEntryIterator(dtEntry, &entryIter)) {
515 printf("Couldn't create entry iterator\n");
516 return 1;
517 }
518 while (kSuccess == DTIterateEntries( entryIter, &dtEntry )) {
519 printf("=== Entry %p ===\n", dtEntry);
520
521 if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) {
522 printf("Couldn't create property iterator\n");
523 return 1;
524 }
525 while( kSuccess == DTIterateProperties( propIter, &name)) {
526 if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
527 continue;
528 printf(" Property %s = %s\n", name, prop);
529 }
530 DTDisposePropertyIterator(propIter);
531 printf("========\n");
532 }
533 DTDisposeEntryIterator(entryIter);
534#endif
535
536 return 0;
537}
538
539#endif
540
541

Archive Download this file

Revision: 214