*/
-#include "sim-main.h"
-
+#include "hw-main.h"
#include "hw-base.h"
#include "hw-tree.h"
hw_tree_parse (struct hw *current,
const char *fmt,
...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ current = hw_tree_vparse (current, fmt, ap);
+ va_end (ap);
+ return current;
+}
+
+struct hw *
+hw_tree_vparse (struct hw *current,
+ const char *fmt,
+ va_list ap)
{
char device_specifier[1024];
name_specifier spec;
/* format the path */
- {
- va_list ap;
- va_start (ap, fmt);
- vsprintf (device_specifier, fmt, ap);
- va_end (ap);
- if (strlen (device_specifier) >= sizeof (device_specifier))
- hw_abort (NULL, "device_tree_add_deviced: buffer overflow\n");
- }
+ vsprintf (device_specifier, fmt, ap);
+ if (strlen (device_specifier) >= sizeof (device_specifier))
+ hw_abort (NULL, "device_tree_add_deviced: buffer overflow\n");
/* construct the tree down to the final struct hw */
current = split_fill_path (current, device_specifier, &spec);
char *dest_hw_name = split_value (&spec);
struct hw *dest;
/* find my name */
- my_port = hw_port_decode (current, my_port_name,
- output_port);
+ if (!hw_finished_p (current))
+ hw_finish (current);
+ my_port = hw_port_decode (current, my_port_name, output_port);
/* find the dest device and port */
- dest = split_fill_path(current, dest_hw_name, &dest_spec);
+ dest = split_fill_path (current, dest_hw_name, &dest_spec);
+ if (!hw_finished_p (dest))
+ hw_finish (dest);
dest_port = hw_port_decode (dest, dest_port_name,
input_port);
/* connect the two */
}
-static void hw_printf
-(struct hw *,
- const char *,
- ...) __attribute__ ((format (printf, 2, 3)));
-
-static void
-hw_printf (struct hw *me,
- const char *fmt,
- ...)
-{
- va_list ap;
- va_start (ap, fmt);
- sim_io_vprintf (hw_system (me), fmt, ap);
- va_end (ap);
-}
-
+\f
+struct printer {
+ hw_tree_print_callback *print;
+ void *file;
+};
static void
print_address (struct hw *bus,
- const hw_unit *phys)
+ const hw_unit *phys,
+ struct printer *p)
{
char unit[32];
hw_unit_encode (bus, phys, unit, sizeof(unit));
- hw_printf (bus, " %s", unit);
+ p->print (p->file, " %s", unit);
}
static void
print_size (struct hw *bus,
- const hw_unit *size)
+ const hw_unit *size,
+ struct printer *p)
{
int i;
for (i = 0; i < size->nr_cells; i++)
if (size->cells[i] != 0)
break;
if (i < size->nr_cells) {
- hw_printf (bus, " 0x%lx", (unsigned long) size->cells[i]);
+ p->print (p->file, " 0x%lx", (unsigned long) size->cells[i]);
i++;
for (; i < size->nr_cells; i++)
- hw_printf (bus, ",0x%lx", (unsigned long) size->cells[i]);
+ p->print (p->file, ",0x%lx", (unsigned long) size->cells[i]);
}
else
- hw_printf (bus, " 0");
+ p->print (p->file, " 0");
}
static void
-print_reg_property(struct hw *me,
- const struct hw_property *property)
+print_reg_property (struct hw *me,
+ const struct hw_property *property,
+ struct printer *p)
{
int reg_nr;
reg_property_spec reg;
for (reg_nr = 0;
hw_find_reg_array_property (me, property->name, reg_nr, ®);
reg_nr++) {
- print_address (hw_parent (me), ®.address);
- print_size (me, ®.size);
+ print_address (hw_parent (me), ®.address, p);
+ print_size (me, ®.size, p);
}
}
static void
-print_ranges_property(struct hw *me,
- const struct hw_property *property)
+print_ranges_property (struct hw *me,
+ const struct hw_property *property,
+ struct printer *p)
{
int range_nr;
range_property_spec range;
hw_find_range_array_property (me, property->name, range_nr, &range);
range_nr++)
{
- print_address (me, &range.child_address);
- print_address (hw_parent (me), &range.parent_address);
- print_size (me, &range.size);
+ print_address (me, &range.child_address, p);
+ print_address (hw_parent (me), &range.parent_address, p);
+ print_size (me, &range.size, p);
}
}
static void
print_string (struct hw *me,
- const char *string)
+ const char *string,
+ struct printer *p)
{
- hw_printf (me, " \"");
+ p->print (p->file, " \"");
while (*string != '\0') {
switch (*string) {
case '"':
- hw_printf (me, "\\\"");
+ p->print (p->file, "\\\"");
break;
case '\\':
- hw_printf (me, "\\\\");
+ p->print (p->file, "\\\\");
break;
default:
- hw_printf (me, "%c", *string);
+ p->print (p->file, "%c", *string);
break;
}
string++;
}
- hw_printf (me, "\"");
+ p->print (p->file, "\"");
}
static void
print_string_array_property (struct hw *me,
- const struct hw_property *property)
+ const struct hw_property *property,
+ struct printer *p)
{
int nr;
string_property_spec string;
hw_find_string_array_property (me, property->name, nr, &string);
nr++)
{
- print_string (me, string);
+ print_string (me, string, p);
}
}
static void
-print_properties (struct hw *me)
+print_properties (struct hw *me,
+ struct printer *p)
{
const struct hw_property *property;
for (property = hw_find_property (me, NULL);
property = hw_next_property (property))
{
if (hw_parent (me) == NULL)
- hw_printf (me, "/%s", property->name);
+ p->print (p->file, "/%s", property->name);
else
- hw_printf (me, "%s/%s", hw_path (me), property->name);
+ p->print (p->file, "%s/%s", hw_path (me), property->name);
if (property->original != NULL)
{
- hw_printf (me, " !");
- hw_printf (me, "%s/%s",
+ p->print (p->file, " !");
+ p->print (p->file, "%s/%s",
hw_path (property->original->owner),
property->original->name);
}
cell_nr < (property->sizeof_array / sizeof (unsigned_cell));
cell_nr++)
{
- hw_printf (me, " 0x%lx", (unsigned long) BE2H_cell (w[cell_nr]));
+ p->print (p->file, " 0x%lx", (unsigned long) BE2H_cell (w[cell_nr]));
}
}
else
{
unsigned8 *w = (unsigned8*)property->array;
- hw_printf (me, " [");
+ p->print (p->file, " [");
while ((char*)w - (char*)property->array < property->sizeof_array) {
- hw_printf (me, " 0x%2x", BE2H_1 (*w));
+ p->print (p->file, " 0x%2x", BE2H_1 (*w));
w++;
}
}
case boolean_property:
{
int b = hw_find_boolean_property(me, property->name);
- hw_printf (me, " %s", b ? "true" : "false");
+ p->print (p->file, " %s", b ? "true" : "false");
break;
}
#if NOT_YET
if (property->array != NULL)
{
device_instance *instance = hw_find_ihandle_property (me, property->name);
- hw_printf (me, " *%s", device_instance_path(instance));
+ p->print (p->file, " *%s", device_instance_path(instance));
}
else
{
/* not yet initialized, ask the device for the path */
ihandle_runtime_property_spec spec;
hw_find_ihandle_runtime_property (me, property->name, &spec);
- hw_printf (me, " *%s", spec.full_path);
+ p->print (p->file, " *%s", spec.full_path);
}
break;
}
case integer_property:
{
unsigned_word w = hw_find_integer_property (me, property->name);
- hw_printf (me, " 0x%lx", (unsigned long)w);
+ p->print (p->file, " 0x%lx", (unsigned long)w);
break;
}
case range_array_property:
{
- print_ranges_property (me, property);
+ print_ranges_property (me, property, p);
break;
}
case reg_array_property:
{
- print_reg_property (me, property);
+ print_reg_property (me, property, p);
break;
}
case string_property:
{
const char *s = hw_find_string_property (me, property->name);
- print_string (me, s);
+ print_string (me, s, p);
break;
}
case string_array_property:
{
- print_string_array_property (me, property);
+ print_string_array_property (me, property, p);
break;
}
}
}
- hw_printf (me, "\n");
+ p->print (p->file, "\n");
}
}
int my_port,
struct hw *dest,
int dest_port,
- void *ignore_or_null)
+ void *data)
{
+ struct printer *p = data;
char src[32];
char dst[32];
hw_port_encode (me, my_port, src, sizeof(src), output_port);
hw_port_encode (dest, dest_port, dst, sizeof(dst), input_port);
- hw_printf (me, "%s > %s %s %s\n",
- hw_path (me),
- src, dst,
- hw_path (dest));
+ p->print (p->file,
+ "%s > %s %s %s\n",
+ hw_path (me),
+ src, dst,
+ hw_path (dest));
}
static void
print_device (struct hw *me,
- void *ignore_or_null)
+ void *data)
{
- hw_printf (me, "%s\n", hw_path (me));
- print_properties (me);
- hw_port_traverse (me, print_interrupts, NULL);
+ struct printer *p = data;
+ p->print (p->file, "%s\n", hw_path (me));
+ print_properties (me, p);
+ hw_port_traverse (me, print_interrupts, data);
}
void
-hw_tree_print (struct hw *root)
+hw_tree_print (struct hw *root,
+ hw_tree_print_callback *print,
+ void *file)
{
+ struct printer p;
+ p.print = print;
+ p.file = file;
hw_tree_traverse (root,
print_device, NULL,
- NULL);
+ &p);
}
if (!split_property_specifier (root, path_to_property, &spec))
hw_abort (root, "Invalid property path %s", path_to_property);
root = split_find_device (root, &spec);
+ if (spec.name != NULL)
+ return NULL; /* not a leaf */
return hw_find_property (root, spec.property);
}
if (!split_property_specifier (root, path_to_property, &spec))
hw_abort (root, "Invalid property path %s", path_to_property);
root = split_find_device (root, &spec);
+ if (spec.name != NULL)
+ hw_abort (root, "device \"%s\" not found (property \"%s\")",
+ spec.name, path_to_property);
return hw_find_boolean_property (root, spec.property);
}
if (!split_property_specifier (root, path_to_property, &spec))
hw_abort (root, "Invalid property path %s", path_to_property);
root = split_find_device (root, &spec);
+ if (spec.name != NULL)
+ hw_abort (root, "device \"%s\" not found (property \"%s\")",
+ spec.name, path_to_property);
return hw_find_integer_property (root, spec.property);
}
hw_tree_find_ihandle_property (struct hw *root,
const char *path_to_property)
{
+ struct hw *root;
name_specifier spec;
if (!split_property_specifier (root, path_to_property, &spec))
hw_abort (root, "Invalid property path %s", path_to_property);
root = split_find_device (root, &spec);
+ if (spec.name != NULL)
+ hw_abort (root, "device \"%s\" not found (property \"%s\")",
+ spec.name, path_to_property);
return hw_find_ihandle_property (root, spec.property);
}
#endif
if (!split_property_specifier (root, path_to_property, &spec))
hw_abort (root, "Invalid property path %s", path_to_property);
root = split_find_device (root, &spec);
+ if (spec.name != NULL)
+ hw_abort (root, "device \"%s\" not found (property \"%s\")",
+ spec.name, path_to_property);
return hw_find_string_property (root, spec.property);
}