📄 hw-tree.c
字号:
hw_add_array_property (current, spec.property, words, sizeof(words[0]) * nr_words); break; } case '"': { parse_string_property (current, spec.property, spec.value); break; } case '!': { spec.value++; property = hw_tree_find_property (current, spec.value); if (property == NULL) hw_abort (current, "property %s not found\n", spec.value); hw_add_duplicate_property (current, spec.property, property); break; } default: { if (strcmp (spec.property, "reg") == 0 || strcmp (spec.property, "assigned-addresses") == 0 || strcmp (spec.property, "alternate-reg") == 0) { parse_reg_property (current, spec.property, spec.value); } else if (strcmp (spec.property, "ranges") == 0) { parse_ranges_property (current, spec.property, spec.value); } else if (isdigit(spec.value[0]) || (spec.value[0] == '-' && isdigit(spec.value[1])) || (spec.value[0] == '+' && isdigit(spec.value[1]))) { parse_integer_property(current, spec.property, spec.value); } else parse_string_property(current, spec.property, spec.value); break; } } } } return current;}static voidfinish_hw_tree (struct hw *me, void *data){ if (!hw_finished_p (me)) hw_finish (me);}voidhw_tree_finish (struct hw *root){ hw_tree_traverse (root, finish_hw_tree, NULL, NULL);}voidhw_tree_traverse (struct hw *root, hw_tree_traverse_function *prefix, hw_tree_traverse_function *postfix, void *data){ struct hw *child; if (prefix != NULL) prefix (root, data); for (child = hw_child (root); child != NULL; child = hw_sibling (child)) { hw_tree_traverse (child, prefix, postfix, data); } if (postfix != NULL) postfix (root, data);}struct printer { hw_tree_print_callback *print; void *file;};static voidprint_address (struct hw *bus, const hw_unit *phys, struct printer *p){ char unit[32]; hw_unit_encode (bus, phys, unit, sizeof(unit)); p->print (p->file, " %s", unit);}static voidprint_size (struct hw *bus, 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) { p->print (p->file, " 0x%lx", (unsigned long) size->cells[i]); i++; for (; i < size->nr_cells; i++) p->print (p->file, ",0x%lx", (unsigned long) size->cells[i]); } else p->print (p->file, " 0");}static voidprint_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, p); print_size (me, ®.size, p); }}static voidprint_ranges_property (struct hw *me, const struct hw_property *property, struct printer *p){ int range_nr; range_property_spec range; for (range_nr = 0; hw_find_range_array_property (me, property->name, range_nr, &range); range_nr++) { print_address (me, &range.child_address, p); print_address (hw_parent (me), &range.parent_address, p); print_size (me, &range.size, p); }}static voidprint_string (struct hw *me, const char *string, struct printer *p){ p->print (p->file, " \""); while (*string != '\0') { switch (*string) { case '"': p->print (p->file, "\\\""); break; case '\\': p->print (p->file, "\\\\"); break; default: p->print (p->file, "%c", *string); break; } string++; } p->print (p->file, "\"");}static voidprint_string_array_property (struct hw *me, const struct hw_property *property, struct printer *p){ int nr; string_property_spec string; for (nr = 0; hw_find_string_array_property (me, property->name, nr, &string); nr++) { print_string (me, string, p); }}static voidprint_properties (struct hw *me, struct printer *p){ const struct hw_property *property; for (property = hw_find_property (me, NULL); property != NULL; property = hw_next_property (property)) { if (hw_parent (me) == NULL) p->print (p->file, "/%s", property->name); else p->print (p->file, "%s/%s", hw_path (me), property->name); if (property->original != NULL) { p->print (p->file, " !"); p->print (p->file, "%s/%s", hw_path (property->original->owner), property->original->name); } else { switch (property->type) { case array_property: { if ((property->sizeof_array % sizeof (signed_cell)) == 0) { unsigned_cell *w = (unsigned_cell*) property->array; int cell_nr; for (cell_nr = 0; cell_nr < (property->sizeof_array / sizeof (unsigned_cell)); cell_nr++) { p->print (p->file, " 0x%lx", (unsigned long) BE2H_cell (w[cell_nr])); } } else { unsigned8 *w = (unsigned8*)property->array; p->print (p->file, " ["); while ((char*)w - (char*)property->array < property->sizeof_array) { p->print (p->file, " 0x%2x", BE2H_1 (*w)); w++; } } break; } case boolean_property: { int b = hw_find_boolean_property(me, property->name); p->print (p->file, " %s", b ? "true" : "false"); break; }#if NOT_YET case ihandle_property: { if (property->array != NULL) { device_instance *instance = hw_find_ihandle_property (me, property->name); 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); p->print (p->file, " *%s", spec.full_path); } break; }#endif case integer_property: { unsigned_word w = hw_find_integer_property (me, property->name); p->print (p->file, " 0x%lx", (unsigned long)w); break; } case range_array_property: { print_ranges_property (me, property, p); break; } case reg_array_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, p); break; } case string_array_property: { print_string_array_property (me, property, p); break; } } } p->print (p->file, "\n"); }}static voidprint_interrupts (struct hw *me, int my_port, struct hw *dest, int dest_port, 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); p->print (p->file, "%s > %s %s %s\n", hw_path (me), src, dst, hw_path (dest));}static voidprint_device (struct hw *me, void *data){ struct printer *p = data; p->print (p->file, "%s\n", hw_path (me)); print_properties (me, p); hw_port_traverse (me, print_interrupts, data);}voidhw_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, &p);}#if NOT_YETdevice_instance *tree_instance(struct hw *root, const char *device_specifier){ /* find the device node */ struct hw *me; name_specifier spec; if (!split_device_specifier(root, device_specifier, &spec)) return NULL; me = split_find_device(root, &spec); if (spec.name != NULL) return NULL; /* create the instance */ return device_create_instance(me, device_specifier, spec.last_args);}#endifstruct hw *hw_tree_find_device (struct hw *root, const char *path_to_device){ struct hw *node; name_specifier spec; /* parse the path */ split_device_specifier (root, path_to_device, &spec); if (spec.value != NULL) return NULL; /* something wierd */ /* now find it */ node = split_find_device (root, &spec); if (spec.name != NULL) return NULL; /* not a leaf */ return node;}const struct hw_property *hw_tree_find_property (struct hw *root, const char *path_to_property){ 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) return NULL; /* not a leaf */ return hw_find_property (root, spec.property);}inthw_tree_find_boolean_property (struct hw *root, const char *path_to_property){ 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_boolean_property (root, spec.property);}signed_cellhw_tree_find_integer_property (struct hw *root, const char *path_to_property){ 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_integer_property (root, spec.property);}#if NOT_YETdevice_instance *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);}#endifconst char *hw_tree_find_string_property (struct hw *root, const char *path_to_property){ 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_string_property (root, spec.property);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -