aboutsummaryrefslogtreecommitdiff
path: root/memory.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-10-09 13:11:50 +0200
committerAvi Kivity <avi@redhat.com>2011-10-09 13:11:50 +0200
commitdf2921d326d0903ff684759ac8508f87396b7018 (patch)
treeb9f9d2a2a116413591362278b2dc9d148c7ee943 /memory.c
parent306f66b42f961e38442d1721523dbb4906b33afb (diff)
parent02d6516c8ba00bdd6d96b622f000cb28c3449f43 (diff)
Merge remote-tracking branch 'upstream' into memory/batch
* upstream: (87 commits) target-alpha: Fix compilation errors for 32 bit hosts target-alpha: Add high-resolution access to wall clock and an alarm. target-alpha: Implement HALT IPR. target-alpha: Implement WAIT IPR. target-alpha: Add CLIPPER emulation. target-alpha: Add custom PALcode image for CLIPPER emulation. target-alpha: Honor icount for RPCC instruction. tcg/s390: Remove unused tcg_out_addi() tcg/ia64: Remove unused tcg_out_addi() ARM: fix segfault ppc64: Fix linker script pseries: Implement set-time-of-day RTAS function pseries: Refactor spapr irq allocation PPC: Clean up BookE timer code PPC: booke timers KVM: PPC: Use HIOR setting for -M pseries with PR KVM KVM: Update kernel headers KVM: Update kernel headers PPC: Fix heathrow PIC to use little endian MMIO PPC: Fix via-cuda memory registration ... Conflicts: hw/milkymist-uart.c hw/ppce500_mpc8544ds.c Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'memory.c')
-rw-r--r--memory.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/memory.c b/memory.c
index 71e769e8b8..f46e6268c2 100644
--- a/memory.c
+++ b/memory.c
@@ -1271,3 +1271,124 @@ void set_system_io_map(MemoryRegion *mr)
address_space_io.root = mr;
memory_region_update_topology();
}
+
+typedef struct MemoryRegionList MemoryRegionList;
+
+struct MemoryRegionList {
+ const MemoryRegion *mr;
+ bool printed;
+ QTAILQ_ENTRY(MemoryRegionList) queue;
+};
+
+typedef QTAILQ_HEAD(queue, MemoryRegionList) MemoryRegionListHead;
+
+static void mtree_print_mr(fprintf_function mon_printf, void *f,
+ const MemoryRegion *mr, unsigned int level,
+ target_phys_addr_t base,
+ MemoryRegionListHead *alias_print_queue)
+{
+ MemoryRegionList *new_ml, *ml, *next_ml;
+ MemoryRegionListHead submr_print_queue;
+ const MemoryRegion *submr;
+ unsigned int i;
+
+ if (!mr) {
+ return;
+ }
+
+ for (i = 0; i < level; i++) {
+ mon_printf(f, " ");
+ }
+
+ if (mr->alias) {
+ MemoryRegionList *ml;
+ bool found = false;
+
+ /* check if the alias is already in the queue */
+ QTAILQ_FOREACH(ml, alias_print_queue, queue) {
+ if (ml->mr == mr->alias && !ml->printed) {
+ found = true;
+ }
+ }
+
+ if (!found) {
+ ml = g_new(MemoryRegionList, 1);
+ ml->mr = mr->alias;
+ ml->printed = false;
+ QTAILQ_INSERT_TAIL(alias_print_queue, ml, queue);
+ }
+ mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d): alias %s @%s "
+ TARGET_FMT_plx "-" TARGET_FMT_plx "\n",
+ base + mr->addr,
+ base + mr->addr + (target_phys_addr_t)mr->size - 1,
+ mr->priority,
+ mr->name,
+ mr->alias->name,
+ mr->alias_offset,
+ mr->alias_offset + (target_phys_addr_t)mr->size - 1);
+ } else {
+ mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d): %s\n",
+ base + mr->addr,
+ base + mr->addr + (target_phys_addr_t)mr->size - 1,
+ mr->priority,
+ mr->name);
+ }
+
+ QTAILQ_INIT(&submr_print_queue);
+
+ QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {
+ new_ml = g_new(MemoryRegionList, 1);
+ new_ml->mr = submr;
+ QTAILQ_FOREACH(ml, &submr_print_queue, queue) {
+ if (new_ml->mr->addr < ml->mr->addr ||
+ (new_ml->mr->addr == ml->mr->addr &&
+ new_ml->mr->priority > ml->mr->priority)) {
+ QTAILQ_INSERT_BEFORE(ml, new_ml, queue);
+ new_ml = NULL;
+ break;
+ }
+ }
+ if (new_ml) {
+ QTAILQ_INSERT_TAIL(&submr_print_queue, new_ml, queue);
+ }
+ }
+
+ QTAILQ_FOREACH(ml, &submr_print_queue, queue) {
+ mtree_print_mr(mon_printf, f, ml->mr, level + 1, base + mr->addr,
+ alias_print_queue);
+ }
+
+ QTAILQ_FOREACH_SAFE(next_ml, &submr_print_queue, queue, ml) {
+ g_free(ml);
+ }
+}
+
+void mtree_info(fprintf_function mon_printf, void *f)
+{
+ MemoryRegionListHead ml_head;
+ MemoryRegionList *ml, *ml2;
+
+ QTAILQ_INIT(&ml_head);
+
+ mon_printf(f, "memory\n");
+ mtree_print_mr(mon_printf, f, address_space_memory.root, 0, 0, &ml_head);
+
+ /* print aliased regions */
+ QTAILQ_FOREACH(ml, &ml_head, queue) {
+ if (!ml->printed) {
+ mon_printf(f, "%s\n", ml->mr->name);
+ mtree_print_mr(mon_printf, f, ml->mr, 0, 0, &ml_head);
+ }
+ }
+
+ QTAILQ_FOREACH_SAFE(ml, &ml_head, queue, ml2) {
+ g_free(ml2);
+ }
+
+ if (address_space_io.root &&
+ !QTAILQ_EMPTY(&address_space_io.root->subregions)) {
+ QTAILQ_INIT(&ml_head);
+ mon_printf(f, "I/O\n");
+ mtree_print_mr(mon_printf, f, address_space_io.root, 0, 0, &ml_head);
+ }
+}