diff options
author | Avi Kivity <avi@redhat.com> | 2011-10-09 13:11:50 +0200 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-10-09 13:11:50 +0200 |
commit | df2921d326d0903ff684759ac8508f87396b7018 (patch) | |
tree | b9f9d2a2a116413591362278b2dc9d148c7ee943 /memory.c | |
parent | 306f66b42f961e38442d1721523dbb4906b33afb (diff) | |
parent | 02d6516c8ba00bdd6d96b622f000cb28c3449f43 (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.c | 121 |
1 files changed, 121 insertions, 0 deletions
@@ -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); + } +} |