Message ID | CAAu8pHtUY5H4y+KDVONfk3mfY7bsk6_9OfXG5U7b0jBjMuEK3Q@mail.gmail.com |
---|---|
State | New |
Headers | show |
Tried it, good tool to inspect guest memory layout. It would be more nice if some symbol could be used to show hierarchies. 0000000000000000-7ffffffffffffffe : pci |__00000000feba0000-00000000febbffff : e1000-mmio |__00000000febf0000-00000000febf0fff : cirrus-mmio |__000000fc000000-00000000fdffffff : cirrus-pci-bar0 |__00000000fc000000-00000000fc7fffff : vga.vram 于 2011-9-26 4:19, Blue Swirl 写道: > Add a monitor command 'info mtree' to show the memory hierarchy > much like /proc/iomem in Linux. > > Signed-off-by: Blue Swirl<blauwirbel@gmail.com> > --- > i386: > memory > 0000000000000000-7ffffffffffffffe : system > 00000000000ec000-00000000000effff : alias pam-ram @pc.ram > 00000000000ec000-00000000000effff > 00000000000e8000-00000000000ebfff : alias pam-ram @pc.ram > 00000000000e8000-00000000000ebfff > 00000000000e4000-00000000000e7fff : alias pam-ram @pc.ram > 00000000000e4000-00000000000e7fff > 00000000000e0000-00000000000e3fff : alias pam-ram @pc.ram > 00000000000e0000-00000000000e3fff > 00000000000dc000-00000000000dffff : alias pam-ram @pc.ram > 00000000000dc000-00000000000dffff > 00000000000d8000-00000000000dbfff : alias pam-ram @pc.ram > 00000000000d8000-00000000000dbfff > 00000000000d4000-00000000000d7fff : alias pam-ram @pc.ram > 00000000000d4000-00000000000d7fff > 00000000000d0000-00000000000d3fff : alias pam-ram @pc.ram > 00000000000d0000-00000000000d3fff > 00000000000cc000-00000000000cffff : alias pam-ram @pc.ram > 00000000000cc000-00000000000cffff > 00000000000c8000-00000000000cbfff : alias pam-rom @pc.ram > 00000000000c8000-00000000000cbfff > 00000000000c4000-00000000000c7fff : alias pam-rom @pc.ram > 00000000000c4000-00000000000c7fff > 00000000000c0000-00000000000c3fff : alias pam-rom @pc.ram > 00000000000c0000-00000000000c3fff > 00000000000f0000-00000000000fffff : alias pam-rom @pc.ram > 00000000000f0000-00000000000fffff > 00000000000a0000-00000000000bffff : alias smram-region @pci > 00000000000a0000-00000000000bffff > 4000000000000000-7fffffffffffffff : alias pci-hole64 @pci > 4000000000000000-7fffffffffffffff > 0000000008000000-00000000ffffffff : alias pci-hole @pci > 0000000008000000-00000000ffffffff > 0000000000000000-0000000007ffffff : alias ram-below-4g @pc.ram > 0000000000000000-0000000007ffffff > 00000000fee00000-00000000feefffff : apic > pci > 0000000000000000-7ffffffffffffffe : pci > 00000000feba0000-00000000febbffff : e1000-mmio > 00000000febf0000-00000000febf0fff : cirrus-mmio > 00000000fc000000-00000000fdffffff : cirrus-pci-bar0 > 00000000fc000000-00000000fc7fffff : vga.vram > 00000000fd000000-00000000fd3fffff : cirrus-bitblt-mmio > 00000000fc000000-00000000fc7fffff : cirrus-linear-io > 00000000000a0000-00000000000bffff : cirrus-lowmem-container > 00000000000a0000-00000000000bffff : cirrus-low-memory > 00000000000c0000-00000000000dffff : pc.rom > 00000000000e0000-00000000000fffff : alias isa-bios @pc.bios > 00000000fffe0000-00000000ffffffff > 00000000fffe0000-00000000ffffffff : pc.bios > pc.ram > 0000000000000000-0000000007ffffff : pc.ram > pc.bios > 00000000fffe0000-00000000ffffffff : pc.bios > I/O > 0000000000000000-000000000000ffff : io > 000000000000c000-000000000000c03f : e1000-io > 000000000000c040-000000000000c04f : piix-bmdma-container > 000000000000c04c-000000000000c04f : bmdma > 000000000000c048-000000000000c04b : piix-bmdma > 000000000000c044-000000000000c047 : bmdma > 000000000000c040-000000000000c043 : piix-bmdma > 0000000000000cfc-0000000000000cff : pci-conf-data > 0000000000000cf8-0000000000000cfb : pci-conf-idx > > PPC (HEAD) > memory > 00000000-fffffffe : system > 800a0000-800affff : alias vga.chain4 @vga.vram 80000000-8000ffff > 80880000-808fffff : macio > 808e0000-808fffff : macio-nvram > 808a0000-808a0fff : pmac-ide > 80896000-80895fff : (null) > 80893000-8089303f : alias escc-bar @escc 80013000-8001303f > 80888000-80888fff : dbdma > 80880000-80880fff : heathrow-pic > 80800000-8080ffff : vga.rom > 80000000-807fffff : vga.vram > 800a0000-800bffff : vga-lowmem > 80013000-8001303f : escc > fee00000-fee00fff : pci-data-idx > fec00000-fec00fff : pci-conf-idx > fe000000-fe1fffff : isa-mmio > escc > 80013000-8001303f : escc > vga.vram > 80000000-807fffff : vga.vram > > PPC with my pci-hole patch: > memory > 00000000-fffffffe : system > 80013000-8001303f : escc > fee00000-fee00fff : pci-data-idx > fec00000-fec00fff : pci-conf-idx > 80000000-fdffffff : alias pci-hole @pci-mmio 80000000-fdffffff > fe000000-fe1fffff : isa-mmio > pci-mmio > 00000000-ffffffff : pci-mmio > 000a0000-000affff : alias vga.chain4 @vga.vram 80000000-8000ffff > 80880000-808fffff : macio > 808e0000-808fffff : macio-nvram > 808a0000-808a0fff : pmac-ide > 80896000-80895fff : (null) > 80893000-8089303f : alias escc-bar @escc 80013000-8001303f > 80888000-80888fff : dbdma > 80880000-80880fff : heathrow-pic > 80800000-8080ffff : vga.rom > 80000000-807fffff : vga.vram > 000a0000-000bffff : vga-lowmem > escc > 80013000-8001303f : escc > vga.vram > 80000000-807fffff : vga.vram > > Sparc64: > 0000000000000000-7ffffffffffffffe : system > 000001ff00000000-000001ffffffffff : pci-mmio > 000001ff000a0000-000001ff000affff : alias vga.chain4 @vga.vram > 0000000000800000-000000000080ffff > 000001ff03000000-000001ff037fffff : isa-mmio > 000001ff02000000-000001ff02ffffff : isa-mmio > 000001ff01000000-000001ff0100ffff : vga.rom > 000001ff00800000-000001ff00ffffff : vga.vram > 000001ff00000000-000001ff000fffff : alias pci_bridge_mem > @pci_pridge_pci 0000000000000000-00000000000fffff > 000001ff00000000-000001ff000fffff : alias pci_bridge_pref_mem > @pci_pridge_pci 0000000000000000-00000000000fffff > 000001ff00000000-000001ff000fffff : alias pci_bridge_mem > @pci_pridge_pci 0000000000000000-00000000000fffff > 000001ff00000000-000001ff000fffff : alias pci_bridge_pref_mem > @pci_pridge_pci 0000000000000000-00000000000fffff > 000001ff000a0000-000001ff000bffff : vga-lowmem > 000001fe02000000-000001fe0200ffff : apb-pci-ioport > 000001fe01000000-000001fe01ffffff : apb-pci-config > 000001fe00000000-000001fe0000ffff : apb-config > pci_pridge_pci > ^ > 0000000000000000-7ffffffffffffffe : pci_pridge_pci > pci_pridge_pci > 0000000000000000-7ffffffffffffffe : pci_pridge_pci > vga.vram > 0000000000800000-0000000000ffffff : vga.vram > > --- > 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<assert.h> > +#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 = "",
On 09/25/2011 11:19 PM, Blue Swirl wrote: > Add a monitor command 'info mtree' to show the memory hierarchy > much like /proc/iomem in Linux. > > > 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<assert.h> > +#include "monitor.h" This is a unfortunate - now the monitor and memory.c are interdependent; this makes it harder to write unit tests (at least without ifdefs). I guess we can disentangle it later using some kind of generic walker. > 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; > +}; Straight typedef of QLIST_HEAD(queue, MemoryRegionList) would be nicer. > + > +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) { print_queue is never NULL, why test? > + 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); Adding mr->alias->addr doesn't help much - it doesn't give you an absolute address, just relative to the alias target's container. If it's deep enough in the tree the address is meaningless. > + > + } 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)); Wrong type. g_new() is much better for this. > + 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)); Again. > + > + /* 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); > + } I think you can eliminate more duplicates by adding a bool ->printed to the queue entry, and always using the same queue. Iterate until no un ->printed elements remain. > + 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 >
On Mon, Sep 26, 2011 at 9:45 AM, Avi Kivity <avi@redhat.com> wrote: > On 09/25/2011 11:19 PM, Blue Swirl wrote: >> >> Add a monitor command 'info mtree' to show the memory hierarchy >> much like /proc/iomem in Linux. >> >> >> 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<assert.h> >> +#include "monitor.h" > > This is a unfortunate - now the monitor and memory.c are interdependent; > this makes it harder to write unit tests (at least without ifdefs). > > I guess we can disentangle it later using some kind of generic walker. monitor.c could pass a pointer to a fprintf-like function and a void *opaque for Monitor *mon. >> 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; >> +}; > > Straight typedef of QLIST_HEAD(queue, MemoryRegionList) would be nicer. OK. >> + >> +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) { > > print_queue is never NULL, why test? Leftover from previous version. I'll remove the test. >> + 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); > > Adding mr->alias->addr doesn't help much - it doesn't give you an absolute > address, just relative to the alias target's container. If it's deep enough > in the tree the address is meaningless. Right, it looked a bit nicer this way but I'll remove that. >> + >> + } 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)); > > Wrong type. g_new() is much better for this. > >> + 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)); > > Again. OK for both. >> + >> + /* 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); >> + } > > I think you can eliminate more duplicates by adding a bool ->printed to the > queue entry, and always using the same queue. Iterate until no un ->printed > elements remain. Good idea, that could avoid the forever loop. >> + 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 >> > > -- > error compiling committee.c: too many arguments to function > >
From c68970d45db864ad80f1387cbd1e3792e8f15c54 Mon Sep 17 00:00:00 2001 Message-Id: <c68970d45db864ad80f1387cbd1e3792e8f15c54.1316981935.git.blauwirbel@gmail.com> From: Blue Swirl <blauwirbel@gmail.com> 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 <blauwirbel@gmail.com> --- 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 <assert.h> +#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
Add a monitor command 'info mtree' to show the memory hierarchy much like /proc/iomem in Linux. Signed-off-by: Blue Swirl <blauwirbel@gmail.com> --- i386: memory 0000000000000000-7ffffffffffffffe : system 00000000000ec000-00000000000effff : alias pam-ram @pc.ram 00000000000ec000-00000000000effff 00000000000e8000-00000000000ebfff : alias pam-ram @pc.ram 00000000000e8000-00000000000ebfff 00000000000e4000-00000000000e7fff : alias pam-ram @pc.ram 00000000000e4000-00000000000e7fff 00000000000e0000-00000000000e3fff : alias pam-ram @pc.ram 00000000000e0000-00000000000e3fff 00000000000dc000-00000000000dffff : alias pam-ram @pc.ram 00000000000dc000-00000000000dffff 00000000000d8000-00000000000dbfff : alias pam-ram @pc.ram 00000000000d8000-00000000000dbfff 00000000000d4000-00000000000d7fff : alias pam-ram @pc.ram 00000000000d4000-00000000000d7fff 00000000000d0000-00000000000d3fff : alias pam-ram @pc.ram 00000000000d0000-00000000000d3fff 00000000000cc000-00000000000cffff : alias pam-ram @pc.ram 00000000000cc000-00000000000cffff 00000000000c8000-00000000000cbfff : alias pam-rom @pc.ram 00000000000c8000-00000000000cbfff 00000000000c4000-00000000000c7fff : alias pam-rom @pc.ram 00000000000c4000-00000000000c7fff 00000000000c0000-00000000000c3fff : alias pam-rom @pc.ram 00000000000c0000-00000000000c3fff 00000000000f0000-00000000000fffff : alias pam-rom @pc.ram 00000000000f0000-00000000000fffff 00000000000a0000-00000000000bffff : alias smram-region @pci 00000000000a0000-00000000000bffff 4000000000000000-7fffffffffffffff : alias pci-hole64 @pci 4000000000000000-7fffffffffffffff 0000000008000000-00000000ffffffff : alias pci-hole @pci 0000000008000000-00000000ffffffff 0000000000000000-0000000007ffffff : alias ram-below-4g @pc.ram 0000000000000000-0000000007ffffff 00000000fee00000-00000000feefffff : apic pci 0000000000000000-7ffffffffffffffe : pci 00000000feba0000-00000000febbffff : e1000-mmio 00000000febf0000-00000000febf0fff : cirrus-mmio 00000000fc000000-00000000fdffffff : cirrus-pci-bar0 00000000fc000000-00000000fc7fffff : vga.vram 00000000fd000000-00000000fd3fffff : cirrus-bitblt-mmio 00000000fc000000-00000000fc7fffff : cirrus-linear-io 00000000000a0000-00000000000bffff : cirrus-lowmem-container 00000000000a0000-00000000000bffff : cirrus-low-memory 00000000000c0000-00000000000dffff : pc.rom 00000000000e0000-00000000000fffff : alias isa-bios @pc.bios 00000000fffe0000-00000000ffffffff 00000000fffe0000-00000000ffffffff : pc.bios pc.ram 0000000000000000-0000000007ffffff : pc.ram pc.bios 00000000fffe0000-00000000ffffffff : pc.bios I/O 0000000000000000-000000000000ffff : io 000000000000c000-000000000000c03f : e1000-io 000000000000c040-000000000000c04f : piix-bmdma-container 000000000000c04c-000000000000c04f : bmdma 000000000000c048-000000000000c04b : piix-bmdma 000000000000c044-000000000000c047 : bmdma 000000000000c040-000000000000c043 : piix-bmdma 0000000000000cfc-0000000000000cff : pci-conf-data 0000000000000cf8-0000000000000cfb : pci-conf-idx PPC (HEAD) memory 00000000-fffffffe : system 800a0000-800affff : alias vga.chain4 @vga.vram 80000000-8000ffff 80880000-808fffff : macio 808e0000-808fffff : macio-nvram 808a0000-808a0fff : pmac-ide 80896000-80895fff : (null) 80893000-8089303f : alias escc-bar @escc 80013000-8001303f 80888000-80888fff : dbdma 80880000-80880fff : heathrow-pic 80800000-8080ffff : vga.rom 80000000-807fffff : vga.vram 800a0000-800bffff : vga-lowmem 80013000-8001303f : escc fee00000-fee00fff : pci-data-idx fec00000-fec00fff : pci-conf-idx fe000000-fe1fffff : isa-mmio escc 80013000-8001303f : escc vga.vram 80000000-807fffff : vga.vram PPC with my pci-hole patch: memory 00000000-fffffffe : system 80013000-8001303f : escc fee00000-fee00fff : pci-data-idx fec00000-fec00fff : pci-conf-idx 80000000-fdffffff : alias pci-hole @pci-mmio 80000000-fdffffff fe000000-fe1fffff : isa-mmio pci-mmio 00000000-ffffffff : pci-mmio 000a0000-000affff : alias vga.chain4 @vga.vram 80000000-8000ffff 80880000-808fffff : macio 808e0000-808fffff : macio-nvram 808a0000-808a0fff : pmac-ide 80896000-80895fff : (null) 80893000-8089303f : alias escc-bar @escc 80013000-8001303f 80888000-80888fff : dbdma 80880000-80880fff : heathrow-pic 80800000-8080ffff : vga.rom 80000000-807fffff : vga.vram 000a0000-000bffff : vga-lowmem escc 80013000-8001303f : escc vga.vram 80000000-807fffff : vga.vram Sparc64: 0000000000000000-7ffffffffffffffe : system 000001ff00000000-000001ffffffffff : pci-mmio 000001ff000a0000-000001ff000affff : alias vga.chain4 @vga.vram 0000000000800000-000000000080ffff 000001ff03000000-000001ff037fffff : isa-mmio 000001ff02000000-000001ff02ffffff : isa-mmio 000001ff01000000-000001ff0100ffff : vga.rom 000001ff00800000-000001ff00ffffff : vga.vram 000001ff00000000-000001ff000fffff : alias pci_bridge_mem @pci_pridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff : alias pci_bridge_pref_mem @pci_pridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff : alias pci_bridge_mem @pci_pridge_pci 0000000000000000-00000000000fffff 000001ff00000000-000001ff000fffff : alias pci_bridge_pref_mem @pci_pridge_pci 0000000000000000-00000000000fffff 000001ff000a0000-000001ff000bffff : vga-lowmem 000001fe02000000-000001fe0200ffff : apb-pci-ioport 000001fe01000000-000001fe01ffffff : apb-pci-config 000001fe00000000-000001fe0000ffff : apb-config pci_pridge_pci ^ 0000000000000000-7ffffffffffffffe : pci_pridge_pci pci_pridge_pci 0000000000000000-7ffffffffffffffe : pci_pridge_pci vga.vram 0000000000800000-0000000000ffffff : vga.vram --- memory.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ memory.h | 2 + monitor.c | 7 ++++ 3 files changed, 110 insertions(+), 0 deletions(-)