From 6aa47f9b219be5e0ed237207f056deca5ace982b Mon Sep 17 00:00:00 2001 From: HATAYAMA Daisuke Date: Tue, 13 Mar 2012 18:19:18 +0900 Subject: [PATCH 1/4] Add a helper function for iterating resource objects This patch introduces a helper function foreach_resource_tree(), which can be used as an iterator for an access to resource objects starting from root object given as the first argument. The next patch that follows will use this. This is exported together with the related data structure, struct resource_data, globally for extension modules. Signed-off-by: HATAYAMA Daisuke --- defs.h | 9 +++++++ memory.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 0 deletions(-) diff --git a/defs.h b/defs.h index bddf2bc..7d6f20c 100755 --- a/defs.h +++ b/defs.h @@ -3950,6 +3950,15 @@ void alter_stackbuf(struct bt_info *); int vaddr_type(ulong, struct task_context *); char *format_stack_entry(struct bt_info *bt, char *, ulong, ulong); int in_user_stack(ulong, ulong); +struct resource_data { + unsigned long start; + unsigned long end; + char *name; + int depth; + int width; +}; +typedef void (*foreach_resource_function)(struct resource_data *r); +void foreach_resource_tree(ulong root, foreach_resource_function f); /* * filesys.c diff --git a/memory.c b/memory.c index 4ed8119..be2c540 100755 --- a/memory.c +++ b/memory.c @@ -16266,3 +16266,74 @@ get_kmem_cache_by_name(char *request) return found; } #endif /* NOT_USED */ + +enum { MAX_IORES_LEVEL = 5 }; + +void foreach_resource_tree(ulong root, foreach_resource_function f) +{ + struct resource_data r; + ulong p, q, root_end, parent, child, sibling, start, end, name; + char buf[BUFSIZE]; + int width, depth; + + readmem(root + MEMBER_OFFSET("resource", "end"), KVADDR, &root_end, + sizeof(ulong), "resource child", FAULT_ON_ERROR); + + width = root_end < 0x10000 ? 4 : 8; + + readmem(root + MEMBER_OFFSET("resource", "child"), KVADDR, &child, + sizeof(ulong), "resource child", FAULT_ON_ERROR); + + for (p = child; p;) { + + readmem(p + MEMBER_OFFSET("resource", "start"), KVADDR, &start, + sizeof(ulong), "resource child", FAULT_ON_ERROR); + + readmem(p + MEMBER_OFFSET("resource", "end"), KVADDR, &end, + sizeof(ulong), "resource child", FAULT_ON_ERROR); + + readmem(p + MEMBER_OFFSET("resource", "name"), KVADDR, &name, + sizeof(ulong), "resource name", FAULT_ON_ERROR); + + readmem(name, KVADDR, buf, sizeof(buf), "buf", FAULT_ON_ERROR); + + for (depth = 0, q = p; depth < MAX_IORES_LEVEL; depth++, q = parent) { + readmem(q + MEMBER_OFFSET("resource", "parent"), + KVADDR, &parent, sizeof(ulong), + "calc resource depth", FAULT_ON_ERROR); + if (parent == root) + break; + } + + r.start = start; + r.end = end; + r.name = name ? buf : NULL; + r.depth = depth; + r.width = width; + + f(&r); + + readmem(p + MEMBER_OFFSET("resource", "child"), KVADDR, &child, + sizeof(ulong), "resource child", FAULT_ON_ERROR); + + if (child) { + p = child; + continue; + } + + for (;;) { + readmem(p + MEMBER_OFFSET("resource", "sibling"), + KVADDR, &sibling, sizeof(ulong), + "resource sibling", FAULT_ON_ERROR); + readmem(p + MEMBER_OFFSET("resource", "parent"), + KVADDR, &parent, sizeof(ulong), + "resource parent", FAULT_ON_ERROR); + if (!sibling && parent) + p = parent; + else + break; + } + + p = sibling; + } +} -- 1.7.4.4