From c68970d45db864ad80f1387cbd1e3792e8f15c54 Mon Sep 17 00:00:00 2001 Message-Id: From: Blue Swirl Date: Sun, 11 Sep 2011 20:22:05 +0000 Subject: [PATCH] memory: simple memory tree printer Add a monitor command 'info mtree' to show the memory hierarchy much like /proc/iomem in Linux. Signed-off-by: Blue Swirl --- memory.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ memory.h | 2 + monitor.c | 7 ++++ 3 files changed, 110 insertions(+), 0 deletions(-) diff --git a/memory.c b/memory.c index ba74435..6b33fc4 100644 --- a/memory.c +++ b/memory.c @@ -17,6 +17,7 @@ #include "bitops.h" #include "kvm.h" #include +#include "monitor.h" unsigned memory_region_transaction_depth = 0; @@ -1256,3 +1257,103 @@ void set_system_io_map(MemoryRegion *mr) address_space_io.root = mr; memory_region_update_topology(); } + +typedef struct MemoryRegionList MemoryRegionList; +typedef struct MemoryRegionListHead MemoryRegionListHead; + +struct MemoryRegionList { + const MemoryRegion *mr; + QLIST_ENTRY(MemoryRegionList) queue; +}; + +struct MemoryRegionListHead { + QLIST_HEAD(queue, MemoryRegionList) head; +}; + +static void mtree_print_mr(Monitor *mon, const MemoryRegion *mr, + unsigned int level, target_phys_addr_t base, + MemoryRegionListHead *print_queue) +{ + const MemoryRegion *submr; + unsigned int i; + + for (i = 0; i < level; i++) { + monitor_printf(mon, " "); + } + + if (mr->alias) { + if (print_queue) { + MemoryRegionList *ml; + bool found = false; + + /* check if the alias is already in the queue */ + QLIST_FOREACH(ml, &print_queue->head, queue) { + if (ml->mr == mr->alias) { + found = true; + } + } + + if (!found) { + ml = g_malloc(sizeof(*ml)); + ml->mr = mr->alias; + QLIST_INSERT_HEAD(&print_queue->head, ml, queue); + } + } + monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " : alias %s @%s " + TARGET_FMT_plx "-" TARGET_FMT_plx "\n", + base + mr->addr, + base + mr->addr + (target_phys_addr_t)mr->size - 1, + mr->name, + mr->alias->name, + mr->alias_offset + mr->alias->addr, + mr->alias_offset + mr->alias->addr + + (target_phys_addr_t)mr->size - 1); + + } else { + monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " : %s\n", + base + mr->addr, + base + mr->addr + (target_phys_addr_t)mr->size - 1, + mr->name); + } + QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) { + mtree_print_mr(mon, submr, level + 1, base + mr->addr, print_queue); + } +} + +void mtree_info(Monitor *mon) +{ + MemoryRegionListHead *ml_head, *ml_head2, *ml_tmp; + MemoryRegionList *ml, *ml2; + + ml_head = g_malloc(sizeof(*ml)); + QLIST_INIT(&ml_head->head); + + monitor_printf(mon, "memory\n"); + mtree_print_mr(mon, address_space_memory.root, 0, 0, ml_head); + + ml_head2 = g_malloc(sizeof(*ml)); + + /* print aliased regions */ + for (;;) { + QLIST_INIT(&ml_head2->head); + + QLIST_FOREACH_SAFE(ml, &ml_head->head, queue, ml2) { + monitor_printf(mon, "%s\n", ml->mr->name); + mtree_print_mr(mon, ml->mr, 0, 0, ml_head2); + g_free(ml); + } + if (QLIST_EMPTY(&ml_head->head)) { + break; + } + ml_tmp = ml_head; + ml_head = ml_head2; + ml_head2 = ml_tmp; + } + +#ifdef TARGET_I386 + monitor_printf(mon, "I/O\n"); + mtree_print_mr(mon, address_space_io.root, 0, 0, ml_head); +#endif + g_free(ml_head2); + g_free(ml_head); +} diff --git a/memory.h b/memory.h index 06b83ae..09d8e29 100644 --- a/memory.h +++ b/memory.h @@ -500,6 +500,8 @@ void memory_region_transaction_begin(void); */ void memory_region_transaction_commit(void); +void mtree_info(Monitor *mon); + #endif #endif diff --git a/monitor.c b/monitor.c index 8ec2c5e..f86fff6 100644 --- a/monitor.c +++ b/monitor.c @@ -2978,6 +2978,13 @@ static const mon_cmd_t info_cmds[] = { }, #endif { + .name = "mtree", + .args_type = "", + .params = "", + .help = "show memory tree", + .mhandler.info = mtree_info, + }, + { .name = "jit", .args_type = "", .params = "", -- 1.7.2.5