aboutsummaryrefslogtreecommitdiff
path: root/sim/ppc/device_tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/ppc/device_tree.c')
-rw-r--r--sim/ppc/device_tree.c926
1 files changed, 532 insertions, 394 deletions
diff --git a/sim/ppc/device_tree.c b/sim/ppc/device_tree.c
index 3a0f60e..78b6e1b 100644
--- a/sim/ppc/device_tree.c
+++ b/sim/ppc/device_tree.c
@@ -27,358 +27,310 @@
#endif
#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
#include "basics.h"
#include "device_tree.h"
-#include "devices.h"
-#include "bfd.h"
-
-/* Any starting address less than this is assumed to be an OEA program
- rather than VEA. */
-#ifndef OEA_START_ADDRESS
-#define OEA_START_ADDRESS 4096
-#endif
-
-#ifndef OEA_MEMORY_SIZE
-#define OEA_MEMORY_SIZE 0x100000
-#endif
-
-enum { clayton_memory_size = OEA_MEMORY_SIZE };
-
-/* insert the address into the device_nodes sorted list of addresses */
-INLINE_DEVICE_TREE void
-device_node_add_address(device_node *node,
- unsigned_word lower_bound,
- unsigned size,
- device_access access,
- void *init)
-{
- unsigned_word upper_bound = lower_bound + size;
- device_address *new_address;
- device_address **current_address;
-
- /* find the insertion point */
- current_address = &node->addresses;
- while (*current_address != NULL
- && (*current_address)->upper_bound >= upper_bound) {
- current_address = &(*current_address)->next_address;
- }
-
- /* insert */
- new_address = ZALLOC(device_address);
- new_address->lower_bound = lower_bound;
- new_address->upper_bound = lower_bound + size;
- new_address->size = size;
- new_address->access = access;
- new_address->init = init;
- new_address->next_address = *current_address;
- *current_address = new_address;
-}
-
-
-/* create a new device tree optionally making it a child of the parent
- node */
-
-INLINE_DEVICE_TREE device_node *
-device_node_create(device_node *parent,
- char *name,
- device_type type,
- device_callbacks *callbacks,
- void *data)
+typedef enum {
+ node_any = 0,
+ node_device,
+ node_integer,
+ node_boolean,
+ node_string
+} node_type;
+
+
+struct _device_tree {
+ /* where i am */
+ device_tree *parent;
+ device_tree *children;
+ device_tree *sibling;
+ /* what i am */
+ node_type type;
+ const char *name;
+ /* the value */
+ const device *device;
+ int boolean;
+ const char *string;
+ signed_word integer;
+};
+
+
+STATIC_INLINE_DEVICE_TREE device_tree *
+new_device_tree(device_tree *parent,
+ const char *name,
+ node_type type)
{
- device_node *new_node;
- new_node = ZALLOC(device_node);
+ device_tree *new_node;
+ new_node = ZALLOC(device_tree);
new_node->parent = parent;
- new_node->name = name;
+ new_node->name = strdup(name);
new_node->type = type;
- new_node->callbacks = callbacks;
- new_node->data = data;
if (parent != NULL) {
- new_node->sibling = parent->children;
- parent->children = new_node;
+ device_tree **sibling = &parent->children;
+ while ((*sibling) != NULL)
+ sibling = &(*sibling)->sibling;
+ *sibling = new_node;
}
return new_node;
}
-/* Binary file:
+/* find/create a node in the device tree */
- The specified file is a binary, assume VEA is required, construct a
- fake device tree based on the addresses of the text / data segments
- requested by the binary */
+typedef enum {
+ device_tree_grow = 1,
+ device_tree_return_null = 2,
+ device_tree_abort = 3,
+} device_tree_action;
-
-/* Update the fake device tree so that memory is allocated for this
- section */
-STATIC_INLINE_DEVICE_TREE void
-update_memory_node_for_section(bfd *abfd,
- asection *the_section,
- PTR obj)
+STATIC_INLINE_DEVICE_TREE device_tree *
+device_tree_find_node(device_tree *root,
+ const char *path,
+ node_type type,
+ device_tree_action action)
{
- unsigned_word section_vma;
- unsigned_word section_size;
- device_access section_access;
- void *section_init;
- device_node *memory = (device_node*)obj;
-
- /* skip the section if no memory to allocate */
- if (! (bfd_get_section_flags(abfd, the_section) & SEC_ALLOC))
- return;
-
- /* check/ignore any sections of size zero */
- section_size = bfd_get_section_size_before_reloc(the_section);
- if (section_size == 0)
- return;
-
- /* find where it is to go */
- section_vma = bfd_get_section_vma(abfd, the_section);
-
- TRACE(trace_device_tree,
- ("name=%-7s, vma=0x%.8x, size=%6d, flags=%3x(%s%s%s%s )\n",
- bfd_get_section_name(abfd, the_section),
- section_vma, section_size,
- bfd_get_section_flags(abfd, the_section),
- bfd_get_section_flags(abfd, the_section) & SEC_LOAD ? " LOAD" : "",
- bfd_get_section_flags(abfd, the_section) & SEC_CODE ? " CODE" : "",
- bfd_get_section_flags(abfd, the_section) & SEC_DATA ? " DATA" : "",
- bfd_get_section_flags(abfd, the_section) & SEC_ALLOC ? " ALLOC" : "",
- bfd_get_section_flags(abfd, the_section) & SEC_READONLY ? " READONLY" : ""
- ));
-
- if (bfd_get_section_flags(abfd, the_section) & SEC_LOAD) {
- section_init = zalloc(section_size);
- if (!bfd_get_section_contents(abfd,
- the_section,
- section_init, 0,
- section_size)) {
- bfd_perror("core:load_section()");
- error("load of data failed");
- return;
+ const char *chp;
+ int name_len;
+ device_tree *child;
+
+ /* strip off any leading `/', `../' or `./' */
+ while (1) {
+ if (strncmp(path, "/", strlen("/")) == 0) {
+ while (root != NULL && root->parent != NULL)
+ root = root->parent;
+ path += strlen("/");
+ }
+ else if (strncmp(path, "./", strlen("./")) == 0) {
+ root = root;
+ path += strlen("./");
+ }
+ else if (strncmp(path, "../", strlen("../")) == 0) {
+ if (root != NULL && root->parent != NULL)
+ root = root->parent;
+ path += strlen("../");
+ }
+ else {
+ break;
}
}
- else {
- section_init = NULL;
+
+ /* find the qualified (with @) and unqualified names in the path,
+ remembering to skip any "\/" */
+ chp = path;
+ do {
+ chp = strchr(chp+1, '/');
+ } while (chp != NULL && chp[-1] == '\\');
+ name_len = (chp == NULL
+ ? strlen(path)
+ : chp - path);
+
+ /* leaf? and growing? */
+ if (root != NULL) {
+ for (child = root->children;
+ child != NULL;
+ child = child->sibling) {
+ if (strncmp(path, child->name, name_len) == 0
+ && (strlen(child->name) == name_len
+ || (strchr(child->name, '@')
+ == child->name + name_len))) {
+ if (path[name_len] == '\0') {
+ if (action == device_tree_grow)
+ error("device_tree_find_node() node %s already present\n",
+ path);
+ if (type != node_any && child->type != type) {
+ if (action == device_tree_return_null)
+ return NULL;
+ else
+ error("device_tree_find_node() node %s does not match type %d\n",
+ path, type);
+ }
+ else
+ return child;
+ }
+ else
+ return device_tree_find_node(child,
+ path + name_len + 1,
+ type,
+ action);
+ }
+ }
+ }
+
+ /* search failed, take default action */
+ switch (action) {
+ case device_tree_grow:
+ if (path[name_len] != '\0')
+ error("device_tree_find_node() not a leaf %s\n", path);
+ return new_device_tree(root, path, type);
+ case device_tree_return_null:
+ return NULL;
+ default:
+ error("device_tree_find_node() invalid default action %d\n", action);
+ return NULL;
}
+}
- /* determine the devices access */
- if (bfd_get_section_flags(abfd, the_section) & SEC_CODE)
- section_access = (device_is_readable | device_is_executable);
- else if (bfd_get_section_flags(abfd, the_section) & SEC_READONLY)
- section_access = device_is_readable;
- else
- section_access = (device_is_readable | device_is_writeable);
-
- /* find our memory and add this section to its list of addresses */
- device_node_add_address(memory,
- section_vma,
- section_size,
- section_access,
- section_init);
+
+/* grow the device tree */
+
+INLINE_DEVICE_TREE device_tree *
+device_tree_add_passthrough(device_tree *root,
+ const char *path)
+{
+ device_tree *new_node = device_tree_find_node(root,
+ path,
+ node_device,
+ device_tree_grow);
+ new_node->device = device_create_from(new_node->name,
+ NULL,
+ passthrough_device_callbacks(),
+ new_node->parent->device);
+ return new_node;
}
-/* construct the device tree from the executable */
+INLINE_DEVICE_TREE device_tree *
+device_tree_add_device(device_tree *root,
+ const char *path,
+ const device *dev)
+{
+ device_tree *new_node = device_tree_find_node(root,
+ path,
+ node_device,
+ device_tree_grow);
+ new_node->device = dev;
+ return new_node;
+}
-STATIC_INLINE_DEVICE_TREE device_node *
-create_option_device_node(device_node *root,
- bfd *image)
+INLINE_DEVICE_TREE device_tree *
+device_tree_add_integer(device_tree *root,
+ const char *path,
+ signed_word integer)
{
- int oea = (bfd_get_start_address(image) < OEA_START_ADDRESS);
- int elf = (image->xvec->flavour == bfd_target_elf_flavour);
- device_node *option_node;
-
- /* the option node and than its members */
- option_node = device_node_create(root, "options", options_device,
- NULL, NULL);
-
- /* which endian are we ? */
- device_node_create(option_node,
- "little-endian?",
- boolean_type_device,
- NULL,
- (void*)(image->xvec->byteorder_big_p ? 0 : -1));
-
- /* what is the initial entry point */
- device_node_create(option_node,
- "program-counter",
- integer_type_device,
- NULL,
- (void*)(bfd_get_start_address(image)));
-
- /* address of top of boot stack */
- TRACE(trace_tbd, ("create_optioin_device_node() - TBD - NT/OpenBoot?\n"));
- device_node_create(option_node,
- "stack-pointer",
- integer_type_device,
- NULL,
- (void *)((oea)
- ? clayton_memory_size /* OEA */
- : ((elf)
- ? 0xe0000000 /* elf */
- : 0x20000000 /* xcoff */)));
-
- /* execution environment */
- device_node_create(option_node,
- "vea?",
- boolean_type_device,
- NULL,
- (void *)((oea) ? 0 : -1));
-
- /* what type of binary */
- TRACE(trace_tbd, ("create_optioin_device_node() - TBD - NT/OpenBoot?\n"));
- device_node_create(option_node,
- "elf?",
- boolean_type_device,
- NULL,
- (void *)((elf) ? -1 : 0));
-
- /* must all memory transfers be naturally aligned? */
- device_node_create(option_node,
- "aligned?",
- boolean_type_device,
- NULL,
- (void*)((WITH_ALIGNMENT == NONSTRICT_ALIGNMENT
- || image->xvec->byteorder_big_p
- || !oea)
- ? 0
- : -1));
-
-
- return option_node;
+ device_tree *new_node = device_tree_find_node(root,
+ path,
+ node_integer,
+ device_tree_grow);
+ new_node->integer = integer;
+ return new_node;
}
+INLINE_DEVICE_TREE device_tree *
+device_tree_add_string(device_tree *root,
+ const char *path,
+ const char *string)
+{
+ device_tree *new_node = device_tree_find_node(root,
+ path,
+ node_string,
+ device_tree_grow);
+ new_node->string = string;
+ return new_node;
+}
-/* clatyon is a simple machine that does not require interrupts or any
- thing else */
+INLINE_DEVICE_TREE device_tree *
+device_tree_add_boolean(device_tree *root,
+ const char *path,
+ int boolean)
+{
+ device_tree *new_node = device_tree_find_node(root,
+ path,
+ node_boolean,
+ device_tree_grow);
+ new_node->boolean = boolean;
+ return new_node;
+}
-STATIC_INLINE_DEVICE_TREE device_node *
-create_clayton_device_tree(bfd *image)
+INLINE_DEVICE_TREE device_tree *
+device_tree_add_found_device(device_tree *root,
+ const char *path)
{
- device_node *root;
- device_node *io_node;
- device_node *data_node;
- device_node *memory_node;
-
- /* the root */
- root = ZALLOC(device_node);
-
- /* memory - clayton has 2mb of RAM at location 0 */
- memory_node = device_node_create(root,
- "memory",
- memory_device,
- NULL,
- NULL);
- device_node_add_address(memory_node, 0x0, clayton_memory_size,
- (device_is_readable
- | device_is_writeable
- | device_is_executable),
- NULL);
-
- /* io address space */
- io_node = device_node_create(root, "io", bus_device, NULL, NULL);
-
- /* and IO devices */
- find_device_descriptor("console")
- ->creator(io_node, "console@0x400000,0");
- find_device_descriptor("halt")
- ->creator(io_node, "halt@0x500000,0");
- find_device_descriptor("icu")
- ->creator(io_node, "icu@0x600000,0");
-
- /* data to load */
- data_node = device_node_create(root, "image", data_device, NULL, NULL);
- bfd_map_over_sections(image,
- update_memory_node_for_section,
- (PTR)data_node);
-
- /* options */
- create_option_device_node(root, image);
-
- return root;
+ device_tree *new_node = device_tree_add_device(root, path, NULL);
+ new_node->device = device_create(new_node->name,
+ new_node->parent->device);
+ return new_node;
}
-/* user mode executable build up a device tree that reflects this */
+/* look up the device tree */
-STATIC_INLINE_DEVICE_TREE device_node *
-create_vea_device_tree(bfd *image)
+INLINE_DEVICE_TREE const device *
+device_tree_find_device(device_tree *root,
+ const char *path)
{
- device_node *root;
- device_node *memory_node;
- device_node *option_node;
-
- /* the root */
- root = ZALLOC(device_node);
-
- /* memory */
- memory_node = device_node_create(root, "memory", memory_device,
- NULL, NULL);
- bfd_map_over_sections(image,
- update_memory_node_for_section,
- (PTR)memory_node);
- /* options - only endian so far */
- option_node = create_option_device_node(root, image);
-
- return root;
+ device_tree *node = device_tree_find_node(root,
+ path,
+ node_device,
+ device_tree_abort);
+ return node->device;
}
+INLINE_DEVICE_TREE signed_word
+device_tree_find_integer(device_tree *root,
+ const char *path)
+{
+ device_tree *node = device_tree_find_node(root,
+ path,
+ node_integer,
+ device_tree_abort);
+ return node->integer;
+}
-/* create a device tree from the specified file */
-INLINE_DEVICE_TREE device_node *
-device_tree_create(const char *file_name)
+INLINE_DEVICE_TREE const char *
+device_tree_find_string(device_tree *root,
+ const char *path)
{
- bfd *image;
- device_node *tree;
+ device_tree *node = device_tree_find_node(root,
+ path,
+ node_string,
+ device_tree_abort);
+ return node->string;
+}
- bfd_init(); /* could be redundant but ... */
+INLINE_DEVICE_TREE int
+device_tree_find_boolean(device_tree *root,
+ const char *path)
+{
+ device_tree *node = device_tree_find_node(root,
+ path,
+ node_boolean,
+ device_tree_abort);
+ return node->boolean;
+}
- /* open the file */
- image = bfd_openr(file_name, NULL);
- if (image == NULL) {
- bfd_perror("open failed:");
- error("nothing loaded\n");
- return NULL;
- }
- /* check it is valid */
- if (!bfd_check_format(image, bfd_object)) {
- printf_filtered("create_device_tree() - FIXME - should check more bfd bits\n");
- printf_filtered("create_device_tree() - %s not an executable, assume device file\n", file_name);
- bfd_close(image);
- image = NULL;
- }
+/* init all the devices */
- /* depending on what was found about the file, load it */
- if (image != NULL) {
- if (bfd_get_start_address(image) == 0) {
- TRACE(trace_device_tree, ("create_device_tree() - clayton image\n"));
- tree = create_clayton_device_tree(image);
- }
- else if (bfd_get_start_address(image) > 0) {
- TRACE(trace_device_tree, ("create_device_tree() - vea image\n"));
- tree = create_vea_device_tree(image);
- }
- bfd_close(image);
- }
- else {
- error("TBD - create_device_tree() text file defining device tree\n");
- tree = NULL;
- }
+STATIC_INLINE_DEVICE_TREE void
+device_tree_init_device(device_tree *root,
+ void *data)
+{
+ psim *system = (psim*)data;
+ if (root->type == node_device)
+ root->device->callback->init(root->device, system);
+}
- return tree;
+
+INLINE_DEVICE_TREE void
+device_tree_init(device_tree *root,
+ psim *system)
+{
+ device_tree_traverse(root, device_tree_init_device, NULL, system);
}
/* traverse a device tree applying prefix/postfix functions to it */
INLINE_DEVICE_TREE void
-device_tree_traverse(device_node *root,
+device_tree_traverse(device_tree *root,
device_tree_traverse_function *prefix,
device_tree_traverse_function *postfix,
void *data)
{
- device_node *child;
+ device_tree *child;
if (prefix != NULL)
prefix(root, data);
for (child = root->children; child != NULL; child = child->sibling) {
@@ -389,126 +341,312 @@ device_tree_traverse(device_node *root,
}
-/* query the device tree */
+/* dump out a device node and addresses */
-INLINE_DEVICE_TREE device_node *
-device_tree_find_node(device_node *root,
- const char *path)
+INLINE_DEVICE_TREE void
+device_tree_dump(device_tree *device,
+ void *ignore_data_argument)
{
- char *chp;
- int name_len;
- device_node *child;
+ printf_filtered("(device_tree@0x%x\n", device);
+ printf_filtered(" (parent 0x%x)\n", device->parent);
+ printf_filtered(" (children 0x%x)\n", device->children);
+ printf_filtered(" (sibling 0x%x)\n", device->sibling);
+ printf_filtered(" (type %d)\n", device->type);
+ printf_filtered(" (name %s)\n", device->name);
+ printf_filtered(" (device 0x%x)\n", device->device);
+ printf_filtered(" (boolean %d)\n", device->boolean);
+ printf_filtered(" (string %s)\n", device->string);
+ printf_filtered(" (integer %d)\n", device->integer);
+ printf_filtered(")\n");
+}
- /* strip off any leading `/', `../' or `./' */
- while (1) {
- if (strncmp(path, "/", strlen("/")) == 0) {
- while (root->parent != NULL)
- root = root->parent;
- path += strlen("/");
- }
- else if (strncmp(path, "./", strlen("./")) == 0) {
- root = root;
- path += strlen("./");
- }
- else if (strncmp(path, "../", strlen("../")) == 0) {
- if (root->parent != NULL)
- root = root->parent;
- path += strlen("../");
- }
- else {
- break;
- }
- }
- /* find the qualified (with @) and unqualified names in the path */
- chp = strchr(path, '/');
- name_len = (chp == NULL
- ? strlen(path)
- : chp - path);
+/* Parse a device name, various formats */
- /* search through children for a match */
- for (child = root->children;
- child != NULL;
- child = child->sibling) {
- if (strncmp(path, child->name, name_len) == 0
- && (strlen(child->name) == name_len
- || strchr(child->name, '@') == child->name + name_len)) {
- if (path[name_len] == '\0')
- return child;
- else
- return device_tree_find_node(child, path + name_len + 1);
- }
- }
- return NULL;
+#ifndef __NetBSD__
+#define strtouq strtoul
+#endif
+
+#define SCAN_INIT(START, END, COUNT, NAME) \
+ char *START = NULL; \
+ char *END = strchr(NAME, '@'); \
+ int COUNT = 0; \
+ if (END == NULL) \
+ return 0; \
+ START = END + 1
+
+#define SCAN_U(START, END, COUNT, U) \
+do { \
+ *U = strtouq(START, &END, 0); \
+ if (START == END) \
+ return COUNT; \
+ COUNT++; \
+ if (*END != ',') \
+ return COUNT; \
+ START = END + 1; \
+} while (0)
+
+#define SCAN_P(START, END, COUNT, P) \
+do { \
+ *P = (void*)(unsigned)strtouq(START, &END, 0); \
+ if (START == END) \
+ return COUNT; \
+ COUNT++; \
+ if (*END != ',') \
+ return COUNT; \
+ START = END + 1; \
+} while (0)
+
+#define SCAN_C(START, END, COUNT, C) \
+do { \
+ char *chp = C; \
+ END = START; \
+ while (*END != '\0' && *END != ',') { \
+ if (*END == '\\') \
+ END++; \
+ *chp = *END; \
+ chp += 1; \
+ END += 1; \
+ } \
+ *chp = '\0'; \
+ if (START == END) \
+ return COUNT; \
+ COUNT++; \
+ if (*END != ',') \
+ return COUNT; \
+ START = END + 1; \
+} while (0)
+
+INLINE_DEVICE_TREE int
+scand_uw(const char *name,
+ unsigned_word *uw1)
+{
+ SCAN_INIT(start, end, count, name);
+ SCAN_U(start, end, count, uw1);
+ return count;
}
-INLINE_DEVICE_TREE device_node *device_tree_find_next_node
-(device_node *root,
- const char *path,
- device_node *last);
+INLINE_DEVICE_TREE int
+scand_uw_u(const char *name,
+ unsigned_word *uw1,
+ unsigned *u2)
+{
+ SCAN_INIT(start, end, count, name);
+ SCAN_U(start, end, count, uw1);
+ SCAN_U(start, end, count, u2);
+ return count;
+}
-INLINE_DEVICE_TREE signed_word
-device_tree_find_int(device_node *root,
- const char *path)
+INLINE_DEVICE_TREE int
+scand_uw_u_u(const char *name,
+ unsigned_word *uw1,
+ unsigned *u2,
+ unsigned *u3)
{
- device_node *int_node = device_tree_find_node(root, path);
- if (int_node == NULL) {
- error("device_tree_find_int() - node %s does not exist\n", path);
- return 0;
- }
- else if (int_node->type != integer_type_device) {
- error("device_tree_find_int() - node %s is not an int\n", path);
- return 0;
- }
- else {
- return (signed_word)(int_node->data);
- }
+ SCAN_INIT(start, end, count, name);
+ SCAN_U(start, end, count, uw1);
+ SCAN_U(start, end, count, u2);
+ SCAN_U(start, end, count, u3);
+ return count;
}
+INLINE_DEVICE_TREE int
+scand_uw_uw_u(const char *name,
+ unsigned_word *uw1,
+ unsigned_word *uw2,
+ unsigned *u3)
+{
+ SCAN_INIT(start, end, count, name);
+ SCAN_U(start, end, count, uw1);
+ SCAN_U(start, end, count, uw2);
+ SCAN_U(start, end, count, u3);
+ return count;
+}
-INLINE_DEVICE_TREE const char *device_tree_find_string
-(device_node *root,
- const char *path);
+INLINE_DEVICE_TREE int
+scand_c(const char *name,
+ char *c1)
+{
+ SCAN_INIT(start, end, count, name);
+ SCAN_C(start, end, count, c1);
+ return count;
+}
INLINE_DEVICE_TREE int
-device_tree_find_boolean(device_node *root,
- const char *path)
+scand_c_uw_u(const char *name,
+ char *c1,
+ unsigned_word *uw2,
+ unsigned *u3)
{
- device_node *int_node = device_tree_find_node(root, path);
- if (int_node == NULL) {
- error("device_tree_find_boolean() - node %s does not exist\n", path);
- return 0;
- }
- else if (int_node->type != boolean_type_device) {
- error("device_tree_find_boolean() - node %s is not a boolean\n", path);
- return 0;
+ SCAN_INIT(start, end, count, name);
+ SCAN_C(start, end, count, c1);
+ SCAN_U(start, end, count, uw2);
+ SCAN_U(start, end, count, u3);
+ return count;
+}
+
+
+STATIC_INLINE_DEVICE_TREE void
+u_strcat(char *buf,
+ unsigned_word uw)
+{
+ if (MASKED64(uw, 32, 63) == uw
+ || WITH_HOST_WORD_BITSIZE == 64) {
+ char *end = strchr(buf, '\0');
+ sprintf(end, "0x%x", (unsigned)uw);
}
else {
- return (signed_word)(int_node->data);
+ char *end = strchr(buf, '\0');
+ sprintf(end, "0x%x%08x",
+ (unsigned)EXTRACTED64(uw, 0, 31),
+ (unsigned)EXTRACTED64(uw, 32, 63));
+ }
+}
+
+STATIC_INLINE_DEVICE_TREE void
+c_strcat(char *buf,
+ const char *c)
+{
+ char *end = strchr(buf, '\0');
+ while (*c) {
+ if (*c == '/' || *c == ',')
+ *end++ = '\\';
+ *end++ = *c++;
+ }
+ *end = '\0';
+}
+
+STATIC_INLINE_DEVICE_TREE int
+c_strlen(const char *c)
+{
+ int len = 0;
+ while (*c) {
+ if (*c == '/' || *c == ',')
+ len++;
+ len++;
+ c++;
}
+ return len;
}
+enum {
+ strlen_unsigned = 10,
+ strlen_unsigned_word = 18,
+};
-INLINE_DEVICE_TREE void *device_tree_find_bytes
-(device_node *root,
- const char *path);
+INLINE_DEVICE_TREE char *
+printd_uw_u(const char *name,
+ unsigned_word uw1,
+ unsigned u2)
+{
+ int sizeof_buf = (strlen(name)
+ + strlen("@")
+ + strlen_unsigned_word
+ + strlen(",")
+ + strlen_unsigned
+ + 1);
+ char *buf = (char*)zalloc(sizeof_buf);
+ strcpy(buf, name);
+ strcat(buf, "@");
+ u_strcat(buf, uw1);
+ strcat(buf, ",");
+ u_strcat(buf, u2);
+ ASSERT(strlen(buf) < sizeof_buf);
+ return buf;
+}
-/* dump out a device node and addresses */
+INLINE_DEVICE_TREE char *
+printd_uw_u_u(const char *name,
+ unsigned_word uw1,
+ unsigned u2,
+ unsigned u3)
+{
+ int sizeof_buf = (strlen(name)
+ + strlen("@")
+ + strlen_unsigned_word
+ + strlen(",")
+ + strlen_unsigned
+ + strlen(",")
+ + strlen_unsigned
+ + 1);
+ char *buf = (char*)zalloc(sizeof_buf);
+ strcpy(buf, name);
+ strcat(buf, "@");
+ u_strcat(buf, uw1);
+ strcat(buf, ",");
+ u_strcat(buf, u2);
+ strcat(buf, ",");
+ u_strcat(buf, u3);
+ ASSERT(strlen(buf) < sizeof_buf);
+ return buf;
+}
-INLINE_DEVICE_TREE void
-device_tree_dump(device_node *device,
- void *ignore_data_argument)
+INLINE_DEVICE_TREE char *
+printd_uw_u_u_c(const char *name,
+ unsigned_word uw1,
+ unsigned u2,
+ unsigned u3,
+ const char *c4)
{
- printf_filtered("(device_node@0x%x\n", device);
- printf_filtered(" (parent 0x%x)\n", device->parent);
- printf_filtered(" (children 0x%x)\n", device->children);
- printf_filtered(" (sibling 0x%x)\n", device->sibling);
- printf_filtered(" (name %s)\n", device->name ? device->name : "(null)");
- printf_filtered(" (type %d)\n", device->type);
- printf_filtered(" (handlers 0x%x)\n", device->callbacks);
- printf_filtered(" (addresses %d)\n", device->addresses);
- printf_filtered(" (data %d)\n", device->data);
- printf_filtered(")\n");
+ int sizeof_buf = (strlen(name)
+ + strlen("@")
+ + strlen_unsigned_word
+ + strlen(",")
+ + strlen_unsigned
+ + strlen(",")
+ + strlen_unsigned
+ + strlen(",")
+ + c_strlen(c4)
+ + 1);
+ char *buf = (char*)zalloc(sizeof_buf);
+ strcpy(buf, name);
+ strcat(buf, "@");
+ u_strcat(buf, uw1);
+ strcat(buf, ",");
+ u_strcat(buf, u2);
+ strcat(buf, ",");
+ u_strcat(buf, u3);
+ strcat(buf, ",");
+ c_strcat(buf, c4);
+ ASSERT(strlen(buf) < sizeof_buf);
+ return buf;
+}
+
+INLINE_DEVICE_TREE char *
+printd_c(const char *name,
+ const char *c1)
+{
+ int sizeof_buf = (strlen(name)
+ + strlen("@")
+ + c_strlen(c1)
+ + 1);
+ char *buf = (char*)zalloc(sizeof_buf);
+ strcpy(buf, name);
+ strcat(buf, "@");
+ c_strcat(buf, c1);
+ ASSERT(strlen(buf) < sizeof_buf);
+ return buf;
+}
+
+INLINE_DEVICE_TREE char *
+printd_c_uw(const char *name,
+ const char *c1,
+ unsigned_word uw2)
+{
+ int sizeof_buf = (strlen(name)
+ + strlen("@")
+ + c_strlen(c1)
+ + strlen(",")
+ + strlen_unsigned_word
+ + 1);
+ char *buf = (char*)zalloc(sizeof_buf);
+ strcpy(buf, name);
+ strcat(buf, "@");
+ c_strcat(buf, c1);
+ strcat(buf, ",");
+ u_strcat(buf, uw2);
+ ASSERT(strlen(buf) < sizeof_buf);
+ return buf;
}
#endif /* _DEVICE_TREE_C_ */