📄 tree.c
字号:
case '!': spec.value++; property = tree_find_property(current, spec.value); if (property == NULL) device_error(current, "property %s not found\n", spec.value); device_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;}INLINE_TREE\(void)tree_traverse(device *root, tree_traverse_function *prefix, tree_traverse_function *postfix, void *data){ device *child; if (prefix != NULL) prefix(root, data); for (child = device_child(root); child != NULL; child = device_sibling(child)) { tree_traverse(child, prefix, postfix, data); } if (postfix != NULL) postfix(root, data);}STATIC_INLINE_TREE\(void)print_address(device *bus, const device_unit *phys){ char unit[32]; device_encode_unit(bus, phys, unit, sizeof(unit)); printf_filtered(" %s", unit);}STATIC_INLINE_TREE\(void)print_size(device *bus, const device_unit *size){ int i; for (i = 0; i < size->nr_cells; i++) if (size->cells[i] != 0) break; if (i < size->nr_cells) { printf_filtered(" 0x%lx", (unsigned long)size->cells[i]); i++; for (; i < size->nr_cells; i++) printf_filtered(",0x%lx", (unsigned long)size->cells[i]); } else printf_filtered(" 0");}STATIC_INLINE_TREE\(void)print_reg_property(device *me, const device_property *property){ int reg_nr; reg_property_spec reg; for (reg_nr = 0; device_find_reg_array_property(me, property->name, reg_nr, ®); reg_nr++) { print_address(device_parent(me), ®.address); print_size(me, ®.size); }}STATIC_INLINE_TREE\(void)print_ranges_property(device *me, const device_property *property){ int range_nr; range_property_spec range; for (range_nr = 0; device_find_range_array_property(me, property->name, range_nr, &range); range_nr++) { print_address(me, &range.child_address); print_address(device_parent(me), &range.parent_address); print_size(me, &range.size); }}STATIC_INLINE_TREE\(void)print_string(const char *string){ printf_filtered(" \""); while (*string != '\0') { switch (*string) { case '"': printf_filtered("\\\""); break; case '\\': printf_filtered("\\\\"); break; default: printf_filtered("%c", *string); break; } string++; } printf_filtered("\"");}STATIC_INLINE_TREE\(void)print_string_array_property(device *me, const device_property *property){ int nr; string_property_spec string; for (nr = 0; device_find_string_array_property(me, property->name, nr, &string); nr++) { print_string(string); }}STATIC_INLINE_TREE\(void)print_properties(device *me){ const device_property *property; for (property = device_find_property(me, NULL); property != NULL; property = device_next_property(property)) { printf_filtered("%s/%s", device_path(me), property->name); if (property->original != NULL) { printf_filtered(" !"); printf_filtered("%s/%s", device_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++) { printf_filtered(" 0x%lx", (unsigned long)BE2H_cell(w[cell_nr])); } } else { unsigned8 *w = (unsigned8*)property->array; printf_filtered(" ["); while ((char*)w - (char*)property->array < property->sizeof_array) { printf_filtered(" 0x%2x", BE2H_1(*w)); w++; } } break; case boolean_property: { int b = device_find_boolean_property(me, property->name); printf_filtered(" %s", b ? "true" : "false"); } break; case ihandle_property: { if (property->array != NULL) { device_instance *instance = device_find_ihandle_property(me, property->name); printf_filtered(" *%s", device_instance_path(instance)); } else { /* not yet initialized, ask the device for the path */ ihandle_runtime_property_spec spec; device_find_ihandle_runtime_property(me, property->name, &spec); printf_filtered(" *%s", spec.full_path); } } break; case integer_property: { unsigned_word w = device_find_integer_property(me, property->name); printf_filtered(" 0x%lx", (unsigned long)w); } break; case range_array_property: print_ranges_property(me, property); break; case reg_array_property: print_reg_property(me, property); break; case string_property: { const char *s = device_find_string_property(me, property->name); print_string(s); } break; case string_array_property: print_string_array_property(me, property); break; } } printf_filtered("\n"); }}STATIC_INLINE_TREE\(void)print_interrupts(device *me, int my_port, device *dest, int dest_port, void *ignore_or_null){ char src[32]; char dst[32]; device_interrupt_encode(me, my_port, src, sizeof(src), output_port); device_interrupt_encode(dest, dest_port, dst, sizeof(dst), input_port); printf_filtered("%s > %s %s %s\n", device_path(me), src, dst, device_path(dest));}STATIC_INLINE_TREE\(void)print_device(device *me, void *ignore_or_null){ printf_filtered("%s\n", device_path(me)); print_properties(me); device_interrupt_traverse(me, print_interrupts, NULL);}INLINE_TREE\(void)tree_print(device *root){ tree_traverse(root, print_device, NULL, NULL);}INLINE_TREE\(void)tree_usage(int verbose){ if (verbose == 1) { printf_filtered("\n"); printf_filtered("A device/property specifier has the form:\n"); printf_filtered("\n"); printf_filtered(" /path/to/a/device [ property-value ]\n"); printf_filtered("\n"); printf_filtered("and a possible device is\n"); printf_filtered("\n"); } if (verbose > 1) { printf_filtered("\n"); printf_filtered("A device/property specifier (<spec>) has the format:\n"); printf_filtered("\n"); printf_filtered(" <spec> ::= <path> [ <value> ] ;\n"); printf_filtered(" <path> ::= { <prefix> } { <node> \"/\" } <node> ;\n"); printf_filtered(" <prefix> ::= ( | \"/\" | \"../\" | \"./\" ) ;\n"); printf_filtered(" <node> ::= <name> [ \"@\" <unit> ] [ \":\" <args> ] ;\n"); printf_filtered(" <unit> ::= <number> { \",\" <number> } ;\n"); printf_filtered("\n"); printf_filtered("Where:\n"); printf_filtered("\n"); printf_filtered(" <name> is the name of a device (list below)\n"); printf_filtered(" <unit> is the unit-address relative to the parent bus\n"); printf_filtered(" <args> additional arguments used when creating the device\n"); printf_filtered(" <value> ::= ( <number> # integer property\n"); printf_filtered(" | \"[\" { <number> } # array property (byte)\n"); printf_filtered(" | \"{\" { <number> } # array property (cell)\n"); printf_filtered(" | [ \"true\" | \"false\" ] # boolean property\n"); printf_filtered(" | \"*\" <path> # ihandle property\n"); printf_filtered(" | \"!\" <path> # copy property\n"); printf_filtered(" | \">\" [ <number> ] <path> # attach interrupt\n"); printf_filtered(" | \"<\" <path> # attach child interrupt\n"); printf_filtered(" | \"\\\"\" <text> # string property\n"); printf_filtered(" | <text> # string property\n"); printf_filtered(" ) ;\n"); printf_filtered("\n"); printf_filtered("And the following are valid device names:\n"); printf_filtered("\n"); }}INLINE_TREE\(device_instance *)tree_instance(device *root, const char *device_specifier){ /* find the device node */ device *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);}INLINE_TREE\(device *)tree_find_device(device *root, const char *path_to_device){ device *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;}INLINE_TREE\(const device_property *)tree_find_property(device *root, const char *path_to_property){ name_specifier spec; if (!split_property_specifier(root, path_to_property, &spec)) device_error(root, "Invalid property path %s", path_to_property); root = split_find_device(root, &spec); return device_find_property(root, spec.property);}INLINE_TREE\(int)tree_find_boolean_property(device *root, const char *path_to_property){ name_specifier spec; if (!split_property_specifier(root, path_to_property, &spec)) device_error(root, "Invalid property path %s", path_to_property); root = split_find_device(root, &spec); return device_find_boolean_property(root, spec.property);}INLINE_TREE\(signed_cell)tree_find_integer_property(device *root, const char *path_to_property){ name_specifier spec; if (!split_property_specifier(root, path_to_property, &spec)) device_error(root, "Invalid property path %s", path_to_property); root = split_find_device(root, &spec); return device_find_integer_property(root, spec.property);}INLINE_TREE\(device_instance *)tree_find_ihandle_property(device *root, const char *path_to_property){ name_specifier spec; if (!split_property_specifier(root, path_to_property, &spec)) device_error(root, "Invalid property path %s", path_to_property); root = split_find_device(root, &spec); return device_find_ihandle_property(root, spec.property);}INLINE_TREE\(const char *)tree_find_string_property(device *root, const char *path_to_property){ name_specifier spec; if (!split_property_specifier(root, path_to_property, &spec)) device_error(root, "Invalid property path %s", path_to_property); root = split_find_device(root, &spec); return device_find_string_property(root, spec.property);}#endif /* _PARSE_C_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -