/*␊ |
* Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved.␊ |
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.␊ |
*␊ |
* Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights␊ |
* Reserved. This file contains Original Code and/or Modifications of␊ |
* Original Code as defined in and that are subject to the Apple Public␊ |
* Source License Version 2.0 (the "License"). You may not use this file␊ |
* except in compliance with the License. Please obtain a copy of the␊ |
* License at http://www.apple.com/publicsource and read it before using␊ |
* this file.␊ |
* ␊ |
* The Original Code and all software distributed under the License are␊ |
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the␊ |
* License for the specific language governing rights and limitations␊ |
* under the License.␊ |
* ␊ |
*/␊ |
␊ |
#if 1␊ |
/*␊ |
␊ |
␊ |
Structures for a Flattened Device Tree ␊ |
*/␊ |
␊ |
#define kPropNameLength 32␊ |
␊ |
typedef struct DeviceTreeNodeProperty {␊ |
char name[kPropNameLength]; // NUL terminated property name␊ |
unsigned long length; // Length (bytes) of folloing prop value␊ |
␉char name[kPropNameLength]; // NUL terminated property name␊ |
␉unsigned long length; // Length (bytes) of folloing prop value␊ |
// unsigned long value[1]; // Variable length value of property␊ |
// Padded to a multiple of a longword?␊ |
} DeviceTreeNodeProperty;␊ |
␊ |
typedef struct OpaqueDTEntry {␊ |
unsigned long nProperties; // Number of props[] elements (0 => end)␊ |
unsigned long nChildren; // Number of children[] elements␊ |
␉unsigned long nProperties; // Number of props[] elements (0 => end)␊ |
␉unsigned long nChildren; // Number of children[] elements␊ |
// DeviceTreeNodeProperty props[];// array size == nProperties␊ |
// DeviceTreeNode children[]; // array size == nChildren␊ |
} DeviceTreeNode;␊ |
␊ |
typedef char DTPropertyNameBuf[32];␊ |
/* Entry Name Definitions (Entry Names are C-Strings)*/␊ |
␊ |
// Entry Name Definitions (Entry Names are C-Strings).␊ |
enum {␊ |
kDTMaxEntryNameLength = 31 /* Max length of a C-String Entry Name (terminator not included) */␊ |
};␊ |
|
#define RoundToLong(x)␉(((x) + 3) & ~3)␊ |
␊ |
static struct _DTSizeInfo {␊ |
uint32_t numNodes;␊ |
uint32_t numProperties;␊ |
uint32_t totalPropertySize;␊ |
␉uint32_t␉numNodes;␊ |
␉uint32_t␉numProperties;␊ |
␉uint32_t␉totalPropertySize;␊ |
} DTInfo;␊ |
␊ |
#define kAllocSize 4096␊ |
|
static Node *freeNodes, *allocedNodes;␊ |
static Property *freeProperties, *allocedProperties;␊ |
␊ |
␊ |
//==============================================================================␊ |
␊ |
Property *␊ |
DT__AddProperty(Node *node, const char *name, uint32_t length, void *value)␊ |
{␊ |
Property *prop;␊ |
␉Property *prop;␊ |
␊ |
DPRINTF("DT__AddProperty([Node '%s'], '%s', %d, 0x%x)\n", DT__GetName(node), name, length, value);␊ |
if (freeProperties == NULL) {␊ |
void *buf = malloc(kAllocSize);␊ |
int i;␊ |
␊ |
DPRINTF("Allocating more free properties\n");␊ |
if (buf == 0) return 0;␊ |
bzero(buf, kAllocSize);␊ |
// Use the first property to record the allocated buffer␊ |
// for later freeing.␊ |
prop = (Property *)buf;␊ |
prop->next = allocedProperties;␊ |
allocedProperties = prop;␊ |
prop->value = buf;␊ |
prop++;␊ |
for (i=1; i<(kAllocSize / sizeof(Property)); i++) {␊ |
prop->next = freeProperties;␊ |
freeProperties = prop;␊ |
prop++;␊ |
}␊ |
}␊ |
prop = freeProperties;␊ |
freeProperties = prop->next;␊ |
␉DPRINTF("DT__AddProperty([Node '%s'], '%s', %d, 0x%x)\n", DT__GetName(node), name, length, value);␊ |
␊ |
prop->name = name;␊ |
prop->length = length;␊ |
prop->value = value;␊ |
␉if (freeProperties == NULL) {␊ |
␉␉void *buf = malloc(kAllocSize);␊ |
␉␉int i;␊ |
␊ |
// Always add to end of list␊ |
if (node->properties == 0) {␊ |
node->properties = prop;␊ |
} else {␊ |
node->last_prop->next = prop;␊ |
}␊ |
node->last_prop = prop;␊ |
prop->next = 0;␊ |
␉␉DPRINTF("Allocating more free properties\n");␊ |
␊ |
DPRINTF("Done [0x%x]\n", prop);␊ |
␊ |
DTInfo.numProperties++;␊ |
DTInfo.totalPropertySize += RoundToLong(length);␊ |
␉␉if (buf == 0) {␊ |
␉␉␉return 0;␊ |
␉␉}␊ |
␊ |
return prop;␊ |
␉␉bzero(buf, kAllocSize);␊ |
␉␉// Use the first property to record the allocated buffer␊ |
␉␉// for later freeing.␊ |
␉␉prop = (Property *)buf;␊ |
␉␉prop->next = allocedProperties;␊ |
␉␉allocedProperties = prop;␊ |
␉␉prop->value = buf;␊ |
␉␉prop++;␊ |
␊ |
␉␉for (i = 1; i < (kAllocSize / sizeof(Property)); i++) {␊ |
␉␉␉prop->next = freeProperties;␊ |
␉␉␉freeProperties = prop;␊ |
␉␉␉prop++;␊ |
␉␉}␊ |
␉}␊ |
␊ |
␉prop = freeProperties;␊ |
␉freeProperties = prop->next;␊ |
␊ |
␉prop->name = name;␊ |
␉prop->length = length;␊ |
␉prop->value = value;␊ |
␊ |
␉// Always add to end of list␊ |
␉if (node->properties == 0) {␊ |
␉␉node->properties = prop;␊ |
␉} else {␊ |
␉␉node->last_prop->next = prop;␊ |
␉}␊ |
␊ |
␉node->last_prop = prop;␊ |
␉prop->next = 0;␊ |
␊ |
␉DPRINTF("Done [0x%x]\n", prop);␊ |
␊ |
␉DTInfo.numProperties++;␊ |
␉DTInfo.totalPropertySize += RoundToLong(length);␊ |
␊ |
␉return prop;␊ |
}␊ |
␊ |
␊ |
//==============================================================================␊ |
␊ |
Node *␊ |
DT__AddChild(Node *parent, const char *name)␊ |
{␊ |
Node *node;␊ |
␉Node *node;␊ |
␊ |
if (freeNodes == NULL) {␊ |
void *buf = malloc(kAllocSize);␊ |
int i;␊ |
␊ |
DPRINTF("Allocating more free nodes\n");␊ |
if (buf == 0) return 0;␊ |
bzero(buf, kAllocSize);␊ |
node = (Node *)buf;␊ |
// Use the first node to record the allocated buffer␊ |
// for later freeing.␊ |
node->next = allocedNodes;␊ |
allocedNodes = node;␊ |
node->children = (Node *)buf;␊ |
node++;␊ |
for (i=1; i<(kAllocSize / sizeof(Node)); i++) {␊ |
node->next = freeNodes;␊ |
freeNodes = node;␊ |
node++;␊ |
}␊ |
}␊ |
DPRINTF("DT__AddChild(0x%x, '%s')\n", parent, name);␊ |
node = freeNodes;␊ |
freeNodes = node->next;␊ |
DPRINTF("Got free node 0x%x\n", node);␊ |
DPRINTF("prop = 0x%x, children = 0x%x, next = 0x%x\n", node->properties, node->children, node->next);␊ |
␉if (freeNodes == NULL)␊ |
␉{␊ |
␉␉void *buf = malloc(kAllocSize);␊ |
␊ |
if (parent == NULL) {␊ |
rootNode = node;␊ |
node->next = 0;␊ |
} else {␊ |
node->next = parent->children;␊ |
parent->children = node;␊ |
}␊ |
DTInfo.numNodes++;␊ |
DT__AddProperty(node, "name", strlen(name) + 1, (void *) name);␊ |
return node;␊ |
␉␉if (buf == 0)␊ |
␉␉{␊ |
␉␉␉return 0;␊ |
␉␉}␊ |
␊ |
␉␉int i;␊ |
␊ |
␉␉DPRINTF("Allocating more free nodes\n");␊ |
␊ |
␉␉bzero(buf, kAllocSize);␊ |
␉␉node = (Node *)buf;␊ |
␊ |
␉␉// Use the first node to record the allocated buffer for later freeing.␊ |
␉␉node->next = allocedNodes;␊ |
␉␉allocedNodes = node;␊ |
␉␉node->children = (Node *)buf;␊ |
␉␉node++;␊ |
␊ |
␉␉for (i = 1; i < (kAllocSize / sizeof(Node)); i++)␊ |
␉␉{␊ |
␉␉␉node->next = freeNodes;␊ |
␉␉␉freeNodes = node;␊ |
␉␉␉node++;␊ |
␉␉}␊ |
␉}␊ |
␊ |
␉DPRINTF("DT__AddChild(0x%x, '%s')\n", parent, name);␊ |
␊ |
␉node = freeNodes;␊ |
␉freeNodes = node->next;␊ |
␊ |
␉DPRINTF("Got free node 0x%x\n", node);␊ |
␉DPRINTF("prop = 0x%x, children = 0x%x, next = 0x%x\n", node->properties, node->children, node->next);␊ |
␊ |
␉if (parent == NULL)␊ |
␉{␊ |
␉␉rootNode = node;␊ |
␉␉node->next = 0;␊ |
␉}␊ |
␉else␊ |
␉{␊ |
␉␉node->next = parent->children;␊ |
␉␉parent->children = node;␊ |
␉}␊ |
␊ |
␉DTInfo.numNodes++;␊ |
␉DT__AddProperty(node, "name", strlen(name) + 1, (void *) name);␊ |
␊ |
␉return node;␊ |
}␊ |
␊ |
␊ |
//==============================================================================␊ |
␊ |
void␊ |
DT__FreeProperty(Property *prop)␊ |
{␊ |
prop->next = freeProperties;␊ |
freeProperties = prop;␊ |
␉prop->next = freeProperties;␊ |
␉freeProperties = prop;␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
void␊ |
DT__FreeNode(Node *node)␊ |
{␊ |
|
freeNodes = node;␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
void␊ |
DT__Initialize(void)␊ |
{␊ |
DPRINTF("DT__Initialize\n");␊ |
␊ |
freeNodes = 0;␊ |
allocedNodes = 0;␊ |
freeProperties = 0;␊ |
allocedProperties = 0;␊ |
␊ |
DTInfo.numNodes = 0;␊ |
DTInfo.numProperties = 0;␊ |
DTInfo.totalPropertySize = 0;␊ |
␊ |
rootNode = DT__AddChild(NULL, "/");␊ |
DPRINTF("DT__Initialize done\n");␊ |
␉DPRINTF("DT__Initialize\n");␊ |
␊ |
␉freeNodes = 0;␊ |
␉allocedNodes = 0;␊ |
␉freeProperties = 0;␊ |
␉allocedProperties = 0;␊ |
␊ |
␉DTInfo.numNodes = 0;␊ |
␉DTInfo.numProperties = 0;␊ |
␉DTInfo.totalPropertySize = 0;␊ |
␊ |
␉rootNode = DT__AddChild(NULL, "/");␊ |
␉DPRINTF("DT__Initialize done\n");␊ |
}␊ |
␊ |
//==============================================================================␊ |
/*␊ |
* Free up memory used by in-memory representation␊ |
* of device tree.␊ |
* Free up memory used by in-memory representation of device tree.␊ |
*/␊ |
void␊ |
DT__Finalize(void)␊ |
{␊ |
Node *node;␊ |
Property *prop;␊ |
␉Node *node;␊ |
␉Property *prop;␊ |
␊ |
DPRINTF("DT__Finalize\n");␊ |
for (prop = allocedProperties; prop != NULL; prop = prop->next) {␊ |
free(prop->value);␊ |
}␊ |
allocedProperties = NULL;␊ |
freeProperties = NULL;␊ |
␉DPRINTF("DT__Finalize\n");␊ |
␊ |
for (node = allocedNodes; node != NULL; node = node->next) {␊ |
free((void *)node->children);␊ |
}␊ |
allocedNodes = NULL;␊ |
freeNodes = NULL;␊ |
rootNode = NULL;␊ |
␉for (prop = allocedProperties; prop != NULL; prop = prop->next)␊ |
␉{␊ |
␉␉free(prop->value);␊ |
␉}␊ |
␊ |
␉allocedProperties = NULL;␊ |
␉freeProperties = NULL;␊ |
␊ |
␉for (node = allocedNodes; node != NULL; node = node->next)␊ |
␉{␊ |
␉␉free((void *)node->children);␊ |
␉}␊ |
␊ |
␉allocedNodes = NULL;␊ |
␉freeNodes = NULL;␊ |
␉rootNode = NULL;␊ |
␊ |
// XXX leaks any created strings␊ |
␊ |
DTInfo.numNodes = 0;␊ |
DTInfo.numProperties = 0;␊ |
DTInfo.totalPropertySize = 0;␊ |
␉// XXX leaks any created strings␊ |
␉DTInfo.numNodes = 0;␊ |
␉DTInfo.numProperties = 0;␊ |
␉DTInfo.totalPropertySize = 0;␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
static void *␊ |
FlattenNodes(Node *node, void *buffer)␊ |
{␊ |
Property *prop;␊ |
DeviceTreeNode *flatNode;␊ |
DeviceTreeNodeProperty *flatProp;␊ |
int count;␊ |
␉Property *prop;␊ |
␉DeviceTreeNode *flatNode;␊ |
␉DeviceTreeNodeProperty *flatProp;␊ |
␉int count;␊ |
␊ |
if (node == 0) return buffer;␊ |
␉if (node == 0) {␊ |
␉␉return buffer;␊ |
␉}␊ |
␊ |
flatNode = (DeviceTreeNode *)buffer;␊ |
buffer += sizeof(DeviceTreeNode);␊ |
␉flatNode = (DeviceTreeNode *)buffer;␊ |
␉buffer += sizeof(DeviceTreeNode);␊ |
␊ |
for (count = 0, prop = node->properties; prop != 0; count++, prop = prop->next) {␊ |
flatProp = (DeviceTreeNodeProperty *)buffer;␊ |
strcpy(flatProp->name, prop->name);␊ |
flatProp->length = prop->length;␊ |
buffer += sizeof(DeviceTreeNodeProperty);␊ |
bcopy(prop->value, buffer, prop->length);␊ |
buffer += RoundToLong(prop->length);␊ |
}␊ |
flatNode->nProperties = count;␊ |
␉for (count = 0, prop = node->properties; prop != 0; count++, prop = prop->next)␊ |
␉{␊ |
␉␉flatProp = (DeviceTreeNodeProperty *)buffer;␊ |
␉␉strcpy(flatProp->name, prop->name);␊ |
␉␉flatProp->length = prop->length;␊ |
␉␉buffer += sizeof(DeviceTreeNodeProperty);␊ |
␉␉bcopy(prop->value, buffer, prop->length);␊ |
␉␉buffer += RoundToLong(prop->length);␊ |
␉}␊ |
␊ |
for (count = 0, node = node->children; node != 0; count++, node = node->next) {␊ |
buffer = FlattenNodes(node, buffer);␊ |
}␊ |
flatNode->nChildren = count;␊ |
␉flatNode->nProperties = count;␊ |
␊ |
return buffer;␊ |
␉for (count = 0, node = node->children; node != 0; count++, node = node->next)␊ |
␉{␊ |
␉␉buffer = FlattenNodes(node, buffer);␊ |
␉}␊ |
␊ |
␉flatNode->nChildren = count;␊ |
␊ |
␉return buffer;␊ |
}␊ |
␊ |
/*␊ |
* Flatten the in-memory representation of the device tree␊ |
* into a binary DT block.␊ |
␊ |
/*==============================================================================␊ |
* Flatten the in-memory representation of the device tree into a binary DT block.␊ |
* To get the buffer size needed, call with result = 0.␊ |
* To have a buffer allocated for you, call with *result = 0.␊ |
* To use your own buffer, call with *result = &buffer.␊ |
|
void␊ |
DT__FlattenDeviceTree(void **buffer_p, uint32_t *length)␊ |
{␊ |
uint32_t totalSize;␊ |
void *buf;␊ |
␉uint32_t totalSize;␊ |
␉void * buf;␊ |
␊ |
DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length);␊ |
␉DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length);␊ |
␊ |
#if DEBUG␊ |
if (buffer_p) DT__PrintTree(rootNode);␊ |
␉if (buffer_p) {␊ |
␉␉DT__PrintTree(rootNode);␊ |
␉}␊ |
#endif␊ |
␊ |
totalSize = DTInfo.numNodes * sizeof(DeviceTreeNode) + ␊ |
DTInfo.numProperties * sizeof(DeviceTreeNodeProperty) +␊ |
DTInfo.totalPropertySize;␊ |
␉totalSize = DTInfo.numNodes * sizeof(DeviceTreeNode) + ␊ |
␉␉DTInfo.numProperties * sizeof(DeviceTreeNodeProperty) +␊ |
␉␉DTInfo.totalPropertySize;␊ |
␊ |
DPRINTF("Total size 0x%x\n", totalSize);␊ |
if (buffer_p != 0) {␊ |
if (totalSize == 0) {␊ |
buf = 0;␊ |
} else {␊ |
if (*buffer_p == 0) {␊ |
buf = malloc(totalSize);␊ |
} else {␊ |
buf = *buffer_p;␊ |
}␊ |
bzero(buf, totalSize);␊ |
␊ |
FlattenNodes(rootNode, buf);␊ |
}␊ |
*buffer_p = buf;␊ |
}␊ |
if (length)␊ |
*length = totalSize;␊ |
␉DPRINTF("Total size 0x%x\n", totalSize);␊ |
␊ |
␉if (buffer_p != 0)␊ |
␉{␊ |
␉␉if (totalSize == 0)␊ |
␉␉{␊ |
␉␉␉buf = 0;␊ |
␉␉}␊ |
␉␉else␊ |
␉␉{␊ |
␉␉␉if (*buffer_p == 0)␊ |
␉␉␉{␊ |
␉␉␉␉buf = malloc(totalSize);␊ |
␉␉␉}␊ |
␉␉␉else␊ |
␉␉␉{␊ |
␉␉␉␉buf = *buffer_p;␊ |
␉␉␉}␊ |
␊ |
␉␉␉bzero(buf, totalSize);␊ |
␊ |
␉␉␉FlattenNodes(rootNode, buf);␊ |
␉␉}␊ |
␊ |
␉␉*buffer_p = buf;␊ |
␉}␊ |
␊ |
␉if (length)␊ |
␉{␊ |
␉␉*length = totalSize;␊ |
␉}␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
char *␊ |
DT__GetName(Node *node)␊ |
{␊ |
Property *prop;␊ |
␉Property *prop;␊ |
␊ |
//DPRINTF("DT__GetName(0x%x)\n", node);␊ |
//DPRINTF("Node properties = 0x%x\n", node->properties);␊ |
for (prop = node->properties; prop; prop = prop->next) {␊ |
//DPRINTF("Prop '%s'\n", prop->name);␊ |
if (strcmp(prop->name, "name") == 0) {␊ |
return prop->value;␊ |
}␊ |
}␊ |
//DPRINTF("DT__GetName returns 0\n");␊ |
return "(null)";␊ |
␉//DPRINTF("DT__GetName(0x%x)\n", node);␊ |
␉//DPRINTF("Node properties = 0x%x\n", node->properties);␊ |
␉for (prop = node->properties; prop; prop = prop->next)␊ |
␉{␊ |
␉␉//DPRINTF("Prop '%s'\n", prop->name);␊ |
␉␉if (strcmp(prop->name, "name") == 0)␊ |
␉␉{␊ |
␉␉␉return prop->value;␊ |
␉␉}␊ |
␉}␊ |
␊ |
␉//DPRINTF("DT__GetName returns 0\n");␊ |
␉return "(null)";␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
Node *␊ |
DT__FindNode(const char *path, bool createIfMissing)␊ |
{␊ |
Node *node, *child;␊ |
DTPropertyNameBuf nameBuf;␊ |
char *bp;␊ |
int i;␊ |
␉Node *node, *child;␊ |
␉DTPropertyNameBuf nameBuf;␊ |
␉char *bp;␊ |
␉int i;␊ |
␊ |
DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing);␊ |
␉DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing);␊ |
␊ |
// Start at root␊ |
node = rootNode;␊ |
DPRINTF("root = 0x%x\n", rootNode);␊ |
␉// Start at root␊ |
␉node = rootNode;␊ |
␊ |
while (node) {␊ |
// Skip leading slash␊ |
while (*path == '/') path++;␊ |
␉DPRINTF("root = 0x%x\n", rootNode);␊ |
␊ |
for (i=0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++) *bp = *path;␊ |
*bp = '\0';␊ |
␉while (node)␊ |
␉{␊ |
␉␉// Skip leading slash␊ |
␉␉while (*path == '/')␊ |
␉␉{␊ |
␉␉␉path++;␊ |
␉␉}␊ |
␊ |
if (nameBuf[0] == '\0') {␊ |
// last path entry␊ |
break;␊ |
}␊ |
DPRINTF("Node '%s'\n", nameBuf);␊ |
␉␉for (i = 0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++)␊ |
␉␉{␊ |
␉␉␉*bp = *path;␊ |
␉␉}␊ |
␊ |
for (child = node->children; child != 0; child = child->next) {␊ |
DPRINTF("Child 0x%x\n", child);␊ |
if (strcmp(DT__GetName(child), nameBuf) == 0) {␊ |
break;␊ |
}␊ |
}␊ |
if (child == 0 && createIfMissing) {␊ |
DPRINTF("Creating node\n");␊ |
char *str = malloc(strlen(nameBuf) + 1);␊ |
// XXX this will leak␊ |
strcpy(str, nameBuf);␊ |
␉␉*bp = '\0';␊ |
␊ |
child = DT__AddChild(node, str);␊ |
}␊ |
node = child;␊ |
}␊ |
return node;␊ |
␉if (nameBuf[0] == '\0')␊ |
␉{␊ |
␉␉// last path entry␊ |
␉␉break;␊ |
␉}␊ |
␊ |
␉DPRINTF("Node '%s'\n", nameBuf);␊ |
␊ |
␉for (child = node->children; child != 0; child = child->next)␊ |
␉{␊ |
␉␉DPRINTF("Child 0x%x\n", child);␊ |
␊ |
␉␉if (strcmp(DT__GetName(child), nameBuf) == 0)␊ |
␉␉{␊ |
␉␉␉break;␊ |
␉␉}␊ |
␉}␊ |
␊ |
if (child == 0 && createIfMissing)␊ |
␉{␊ |
␉␉DPRINTF("Creating node\n");␊ |
␊ |
␉␉char *str = malloc(strlen(nameBuf) + 1);␊ |
␉␉// XXX this will leak␊ |
␉␉strcpy(str, nameBuf);␊ |
␊ |
␉␉child = DT__AddChild(node, str);␊ |
␉}␊ |
␊ |
␉␉node = child;␊ |
␉}␊ |
␊ |
␉return node;␊ |
}␊ |
␊ |
#if DEBUG␊ |
␊ |
//==============================================================================␊ |
␊ |
void␊ |
DT__PrintNode(Node *node, int level)␊ |
{␊ |
char spaces[10], *cp = spaces;␊ |
Property *prop;␊ |
␉char spaces[10], *cp = spaces;␊ |
␉Property *prop;␊ |
␊ |
if (level > 9) level = 9;␊ |
while (level--) *cp++ = ' ';␊ |
*cp = '\0';␊ |
␉if (level > 9)␊ |
␉{␊ |
␉␉level = 9;␊ |
␉}␊ |
␊ |
printf("%s===Node===\n", spaces);␊ |
for (prop = node->properties; prop; prop = prop->next) {␊ |
char c = *((char *)prop->value);␊ |
if (prop->length < 64 && (␊ |
strcmp(prop->name, "name") == 0 || ␊ |
(c >= '0' && c <= '9') ||␊ |
(c >= 'a' && c <= 'z') ||␊ |
(c >= 'A' && c <= 'Z') || c == '_')) {␊ |
printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value);␊ |
} else {␊ |
printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length);␊ |
}␊ |
}␊ |
printf("%s==========\n", spaces);␊ |
␉while (level--)␊ |
␉{␊ |
␉␉*cp++ = ' ';␊ |
␉}␊ |
␊ |
␉*cp = '\0';␊ |
␊ |
␉printf("%s===Node===\n", spaces);␊ |
␊ |
␉for (prop = node->properties; prop; prop = prop->next)␊ |
␉{␊ |
␉␉char c = *((char *)prop->value);␊ |
␉␉if (prop->length < 64 && (strcmp(prop->name, "name") == 0 || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'))␊ |
␉␉{␊ |
␉␉␉printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value);␊ |
␉␉}␊ |
␉␉else␊ |
␉␉{␊ |
␉␉␉printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length);␊ |
␉␉}␊ |
␉}␊ |
␊ |
␉printf("%s==========\n", spaces);␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
static void␊ |
_PrintTree(Node *node, int level)␊ |
{␊ |
DT__PrintNode(node, level);␊ |
level++;␊ |
for (node = node->children; node; node = node->next)␊ |
_PrintTree(node, level);␊ |
␉DT__PrintNode(node, level);␊ |
␊ |
␉level++;␊ |
␊ |
␉for (node = node->children; node; node = node->next)␊ |
␉{␊ |
␉␉_PrintTree(node, level);␊ |
␉}␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
void␊ |
DT__PrintTree(Node *node)␊ |
{␊ |
if (node == 0) node = rootNode;␊ |
_PrintTree(node, 0);␊ |
␉if (node == 0) node = rootNode;␊ |
␉_PrintTree(node, 0);␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
void␊ |
DT__PrintFlattenedNode(DTEntry entry, int level)␊ |
{␊ |
char spaces[10], *cp = spaces;␊ |
DTPropertyIterator␉ propIter;␊ |
char *name;␊ |
void *prop;␊ |
int propSize;␊ |
␉char spaces[10], *cp = spaces;␊ |
␉DTPropertyIterator␉ propIter;␊ |
␉char *name;␊ |
␉void *prop;␊ |
␉int propSize;␊ |
␊ |
if (level > 9) level = 9;␊ |
while (level--) *cp++ = ' ';␊ |
*cp = '\0';␊ |
␉if (level > 9) level = 9;␊ |
␉while (level--) *cp++ = ' ';␊ |
␉␉*cp = '\0';␊ |
␊ |
printf("%s===Entry %p===\n", spaces, entry);␊ |
if (kSuccess != DTCreatePropertyIterator(entry, &propIter)) {␊ |
printf("Couldn't create property iterator\n");␊ |
return;␊ |
}␊ |
while( kSuccess == DTIterateProperties( propIter, &name)) {␊ |
if( kSuccess != DTGetProperty( entry, name, &prop, &propSize ))␊ |
continue;␊ |
printf("%s Property %s = %s\n", spaces, name, prop);␊ |
}␊ |
DTDisposePropertyIterator(propIter);␊ |
␉printf("%s===Entry %p===\n", spaces, entry);␊ |
␉␉if (kSuccess != DTCreatePropertyIterator(entry, &propIter))␊ |
␉␉{␊ |
␉␉␉printf("Couldn't create property iterator\n");␊ |
␉␉␉return;␊ |
␉␉}␊ |
␉␉while( kSuccess == DTIterateProperties( propIter, &name))␊ |
␉␉{␊ |
␉␉␉if( kSuccess != DTGetProperty( entry, name, &prop, &propSize ))␊ |
␉␉␉␉continue;␊ |
␉␉printf("%s Property %s = %s\n", spaces, name, prop);␊ |
␉}␊ |
␉DTDisposePropertyIterator(propIter);␊ |
␊ |
printf("%s==========\n", spaces);␊ |
␉printf("%s==========\n", spaces);␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
static void␊ |
_PrintFlattenedTree(DTEntry entry, int level)␊ |
{␊ |
DTEntryIterator entryIter;␊ |
␉DTEntryIterator entryIter;␊ |
␊ |
PrintFlattenedNode(entry, level);␊ |
␉PrintFlattenedNode(entry, level);␊ |
␊ |
if (kSuccess != DTCreateEntryIterator(entry, &entryIter)) {␊ |
printf("Couldn't create entry iterator\n");␊ |
return;␊ |
}␊ |
level++;␊ |
while (kSuccess == DTIterateEntries( entryIter, &entry )) {␊ |
_PrintFlattenedTree(entry, level);␊ |
}␊ |
DTDisposeEntryIterator(entryIter);␊ |
␉if (kSuccess != DTCreateEntryIterator(entry, &entryIter))␊ |
␉{␊ |
␉␉printf("Couldn't create entry iterator\n");␊ |
␉␉return;␊ |
␉}␊ |
␉level++;␊ |
␉while (kSuccess == DTIterateEntries( entryIter, &entry ))␊ |
␉{␊ |
␉␉_PrintFlattenedTree(entry, level);␊ |
␉}␊ |
␉DTDisposeEntryIterator(entryIter);␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
void␊ |
DT__PrintFlattenedTree(DTEntry entry)␊ |
{␊ |
_PrintFlattenedTree(entry, 0);␊ |
␉_PrintFlattenedTree(entry, 0);␊ |
}␊ |
␊ |
//==============================================================================␊ |
␊ |
int␊ |
main(int argc, char **argv)␊ |
{␊ |
DTEntry dtEntry;␊ |
DTPropertyIterator␉ propIter;␊ |
DTEntryIterator entryIter;␊ |
void␉␉␉␉*prop;␊ |
int␉␉␉␉␉propSize;␊ |
char␉␉␉␉*name;␊ |
void *flatTree;␊ |
uint32_t flatSize;␊ |
␉DTEntry␉␉␉dtEntry;␊ |
␉DTPropertyIterator␉propIter;␊ |
␉DTEntryIterator␉␉entryIter;␊ |
␉void␉␉␉*prop;␊ |
␉int␉␉␉propSize;␊ |
␉char␉␉␉*name;␊ |
␉void␉␉␉*flatTree;␊ |
␉uint32_t␉␉flatSize;␊ |
␊ |
Node *node;␊ |
␉Node *node;␊ |
␊ |
node = AddChild(NULL, "device-tree");␊ |
AddProperty(node, "potato", 4, "foo");␊ |
AddProperty(node, "chemistry", 4, "bar");␊ |
AddProperty(node, "physics", 4, "baz");␊ |
␉node = AddChild(NULL, "device-tree");␊ |
␉AddProperty(node, "potato", 4, "foo");␊ |
␉AddProperty(node, "chemistry", 4, "bar");␊ |
␉AddProperty(node, "physics", 4, "baz");␊ |
␊ |
node = AddChild(node, "dev");␊ |
AddProperty(node, "one", 4, "one");␊ |
AddProperty(node, "two", 4, "two");␊ |
AddProperty(node, "three", 6, "three");␊ |
␉node = AddChild(node, "dev");␊ |
␉AddProperty(node, "one", 4, "one");␊ |
␉AddProperty(node, "two", 4, "two");␊ |
␉AddProperty(node, "three", 6, "three");␊ |
␊ |
node = AddChild(rootNode, "foo");␊ |
AddProperty(node, "aaa", 4, "aab");␊ |
AddProperty(node, "bbb", 4, "bbc");␊ |
AddProperty(node, "cccc", 6, "ccccd");␊ |
␉node = AddChild(rootNode, "foo");␊ |
␉AddProperty(node, "aaa", 4, "aab");␊ |
␉AddProperty(node, "bbb", 4, "bbc");␊ |
␉AddProperty(node, "cccc", 6, "ccccd");␊ |
␊ |
node = FindNode("/this/is/a/test", 1);␊ |
AddProperty(node, "dddd", 12, "abcdefghijk");␊ |
␉node = FindNode("/this/is/a/test", 1);␊ |
␉AddProperty(node, "dddd", 12, "abcdefghijk");␊ |
␊ |
printf("In-memory tree:\n\n");␊ |
␉printf("In-memory tree:\n\n");␊ |
␊ |
PrintTree(rootNode);␊ |
␉PrintTree(rootNode);␊ |
␊ |
FlattenDeviceTree(&flatTree, &flatSize);␊ |
␉FlattenDeviceTree(&flatTree, &flatSize);␊ |
␊ |
printf("Flat tree = %p, size %d\n", flatTree, flatSize);␊ |
␉printf("Flat tree = %p, size %d\n", flatTree, flatSize);␊ |
␊ |
dtEntry = (DTEntry)flatTree;␊ |
␉dtEntry = (DTEntry)flatTree;␊ |
␊ |
printf("\n\nPrinting flat tree\n\n");␊ |
␉printf("\n\nPrinting flat tree\n\n");␊ |
␊ |
DTInit(dtEntry);␊ |
␉DTInit(dtEntry);␊ |
␊ |
PrintFlattenedTree((DTEntry)flatTree);␊ |
␉PrintFlattenedTree((DTEntry)flatTree);␊ |
#if 0␊ |
printf("=== Entry %p ===\n", dtEntry);␊ |
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) {␊ |
printf("Couldn't create property iterator\n");␊ |
return 1;␊ |
␉printf("=== Entry %p ===\n", dtEntry);␊ |
␉if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter))␊ |
␉{␊ |
␉␉printf("Couldn't create property iterator\n");␊ |
␉␉return 1;␊ |
␉}␊ |
␉while( kSuccess == DTIterateProperties( propIter, &name))␊ |
␉{␊ |
␉␉if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))␊ |
␉␉␉continue;␊ |
␉␉printf(" Property %s = %s\n", name, prop);␊ |
}␊ |
while( kSuccess == DTIterateProperties( propIter, &name)) {␊ |
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))␊ |
continue;␊ |
printf(" Property %s = %s\n", name, prop);␊ |
}␊ |
DTDisposePropertyIterator(propIter);␊ |
printf("========\n");␊ |
␉DTDisposePropertyIterator(propIter);␊ |
␉printf("========\n");␊ |
␊ |
if (kSuccess != DTCreateEntryIterator(dtEntry, &entryIter)) {␊ |
printf("Couldn't create entry iterator\n");␊ |
return 1;␊ |
}␊ |
while (kSuccess == DTIterateEntries( entryIter, &dtEntry )) {␊ |
printf("=== Entry %p ===\n", dtEntry);␊ |
␉if (kSuccess != DTCreateEntryIterator(dtEntry, &entryIter))␊ |
␉{␊ |
␉␉printf("Couldn't create entry iterator\n");␊ |
␉␉return 1;␊ |
␉}␊ |
␉while (kSuccess == DTIterateEntries( entryIter, &dtEntry ))␊ |
␉{␊ |
␉␉printf("=== Entry %p ===\n", dtEntry);␊ |
␊ |
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) {␊ |
printf("Couldn't create property iterator\n");␊ |
return 1;␊ |
}␊ |
while( kSuccess == DTIterateProperties( propIter, &name)) {␊ |
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))␊ |
continue;␊ |
printf(" Property %s = %s\n", name, prop);␊ |
}␊ |
DTDisposePropertyIterator(propIter);␊ |
printf("========\n");␊ |
}␊ |
DTDisposeEntryIterator(entryIter);␊ |
␉if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter))␊ |
␉{␊ |
␉␉printf("Couldn't create property iterator\n");␊ |
␉␉return 1;␊ |
␉}␊ |
␉␉while( kSuccess == DTIterateProperties( propIter, &name))␊ |
␉␉{␊ |
␉␉␉if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))␊ |
␉␉␉␉continue;␊ |
␉␉␉printf(" Property %s = %s\n", name, prop);␊ |
␉␉}␊ |
␉␉DTDisposePropertyIterator(propIter);␊ |
␉␉printf("========\n");␊ |
␉}␊ |
␉DTDisposeEntryIterator(entryIter);␊ |
#endif␊ |
␊ |
return 0;␊ |
␉return 0;␊ |
}␊ |
␊ |
#endif␊ |