diff options
Diffstat (limited to 'sim/ppc/device_tree.c')
-rw-r--r-- | sim/ppc/device_tree.c | 926 |
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_ */ |