Message ID | 1255069742-15724-30-git-send-email-yamahata@valinux.co.jp |
---|---|
State | Under Review |
Headers | show |
On Fri, Oct 09, 2009 at 03:29:02PM +0900, Isaku Yamahata wrote: > make pci_info_device() print out bridge's filtering value like > io base/limit, subbus and subordinate bus. > > Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Acked-by: Michael S. Tsirkin <mst@redhat.com> Minor comment below. > --- > hw/pci.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > hw/pci.h | 1 + > 2 files changed, 56 insertions(+), 0 deletions(-) > > diff --git a/hw/pci.c b/hw/pci.c > index 6b51bba..6ce7a40 100644 > --- a/hw/pci.c > +++ b/hw/pci.c > @@ -864,6 +864,33 @@ static const pci_class_desc pci_class_descriptions[] = > { 0, NULL} > }; > > +static uint32_t pci_config_get_io_base(PCIDevice *d, > + uint32_t base, uint32_t base_upper16) > +{ > + uint32_t val; > + > + val = ((uint32_t)d->config[base] & PCI_IO_RANGE_MASK) << 8; I note that here you decided to cast a value to uint32_t before & ... > + if (d->config[base] & PCI_IO_RANGE_TYPE_32) { > + val |= (uint32_t)pci_get_word(d->config + PCI_IO_BASE_UPPER16) << 16; > + } > + return val; > +} > + > +static uint64_t pci_config_get_memory_base(PCIDevice *d, uint32_t base) > +{ > + return (pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK) << 16; But not here. Let's be consistent: both or none. > +} > + > +static uint64_t pci_config_get_pref_base(PCIDevice *d, > + uint32_t base, uint32_t upper) > +{ > + uint64_t val; > + val = ((uint64_t)pci_get_word(d->config + base) & > + PCI_PREF_RANGE_MASK) << 16; > + val |= (uint64_t)pci_get_long(d->config + upper) << 32; > + return val; > +} > + > static void pci_info_device(PCIBus *bus, PCIDevice *d) > { > Monitor *mon = cur_mon; > @@ -892,7 +919,35 @@ static void pci_info_device(PCIBus *bus, PCIDevice *d) > d->config[PCI_INTERRUPT_LINE]); > } > if (class == 0x0604) { > + uint64_t base; > + uint64_t limit; > + > monitor_printf(mon, " BUS %d.\n", d->config[0x19]); > + monitor_printf(mon, " secondary bus %d.\n", > + d->config[PCI_SECONDARY_BUS]); > + monitor_printf(mon, " subordinate bus %d.\n", > + d->config[PCI_SUBORDINATE_BUS]); > + > + base = pci_config_get_io_base(d, PCI_IO_BASE, PCI_IO_BASE_UPPER16); > + limit = pci_config_get_io_base(d, PCI_IO_LIMIT, PCI_IO_LIMIT_UPPER16); > + limit |= 0xfff; /* PCI bridge spec 3.2.5.6. */ > + monitor_printf(mon, " IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n", > + base, limit); > + > + base = pci_config_get_memory_base(d, PCI_MEMORY_BASE); > + limit= pci_config_get_memory_base(d, PCI_MEMORY_LIMIT); > + limit |= 0xfffff; /* PCI bridge spec 3.2.5.1. */ > + monitor_printf(mon, > + " memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n", > + base, limit); > + > + base = pci_config_get_pref_base(d, PCI_PREF_MEMORY_BASE, > + PCI_PREF_BASE_UPPER32); > + limit = pci_config_get_pref_base(d, PCI_PREF_MEMORY_LIMIT, > + PCI_PREF_LIMIT_UPPER32); > + limit |= 0xfffff; /* PCI bridge spec 3.2.5.8 */ > + monitor_printf(mon, " prefetchable memory range " > + "[0x%08"PRIx64", 0x%08"PRIx64"]\n", base, limit); > } > for(i = 0;i < PCI_NUM_REGIONS; i++) { > r = &d->io_regions[i]; > diff --git a/hw/pci.h b/hw/pci.h > index a933ef1..80efbf9 100644 > --- a/hw/pci.h > +++ b/hw/pci.h > @@ -173,6 +173,7 @@ typedef struct PCIIORegion { > #define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */ > #define PCI_IO_BASE 0x1c /* I/O range behind the bridge */ > #define PCI_IO_LIMIT 0x1d > +#define PCI_IO_RANGE_TYPE_32 0x01 > #define PCI_IO_RANGE_MASK (~0x0fUL) > #define PCI_MEMORY_BASE 0x20 /* Memory range behind */ > #define PCI_MEMORY_LIMIT 0x22 > -- > 1.6.0.2
diff --git a/hw/pci.c b/hw/pci.c index 6b51bba..6ce7a40 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -864,6 +864,33 @@ static const pci_class_desc pci_class_descriptions[] = { 0, NULL} }; +static uint32_t pci_config_get_io_base(PCIDevice *d, + uint32_t base, uint32_t base_upper16) +{ + uint32_t val; + + val = ((uint32_t)d->config[base] & PCI_IO_RANGE_MASK) << 8; + if (d->config[base] & PCI_IO_RANGE_TYPE_32) { + val |= (uint32_t)pci_get_word(d->config + PCI_IO_BASE_UPPER16) << 16; + } + return val; +} + +static uint64_t pci_config_get_memory_base(PCIDevice *d, uint32_t base) +{ + return (pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK) << 16; +} + +static uint64_t pci_config_get_pref_base(PCIDevice *d, + uint32_t base, uint32_t upper) +{ + uint64_t val; + val = ((uint64_t)pci_get_word(d->config + base) & + PCI_PREF_RANGE_MASK) << 16; + val |= (uint64_t)pci_get_long(d->config + upper) << 32; + return val; +} + static void pci_info_device(PCIBus *bus, PCIDevice *d) { Monitor *mon = cur_mon; @@ -892,7 +919,35 @@ static void pci_info_device(PCIBus *bus, PCIDevice *d) d->config[PCI_INTERRUPT_LINE]); } if (class == 0x0604) { + uint64_t base; + uint64_t limit; + monitor_printf(mon, " BUS %d.\n", d->config[0x19]); + monitor_printf(mon, " secondary bus %d.\n", + d->config[PCI_SECONDARY_BUS]); + monitor_printf(mon, " subordinate bus %d.\n", + d->config[PCI_SUBORDINATE_BUS]); + + base = pci_config_get_io_base(d, PCI_IO_BASE, PCI_IO_BASE_UPPER16); + limit = pci_config_get_io_base(d, PCI_IO_LIMIT, PCI_IO_LIMIT_UPPER16); + limit |= 0xfff; /* PCI bridge spec 3.2.5.6. */ + monitor_printf(mon, " IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n", + base, limit); + + base = pci_config_get_memory_base(d, PCI_MEMORY_BASE); + limit= pci_config_get_memory_base(d, PCI_MEMORY_LIMIT); + limit |= 0xfffff; /* PCI bridge spec 3.2.5.1. */ + monitor_printf(mon, + " memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n", + base, limit); + + base = pci_config_get_pref_base(d, PCI_PREF_MEMORY_BASE, + PCI_PREF_BASE_UPPER32); + limit = pci_config_get_pref_base(d, PCI_PREF_MEMORY_LIMIT, + PCI_PREF_LIMIT_UPPER32); + limit |= 0xfffff; /* PCI bridge spec 3.2.5.8 */ + monitor_printf(mon, " prefetchable memory range " + "[0x%08"PRIx64", 0x%08"PRIx64"]\n", base, limit); } for(i = 0;i < PCI_NUM_REGIONS; i++) { r = &d->io_regions[i]; diff --git a/hw/pci.h b/hw/pci.h index a933ef1..80efbf9 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -173,6 +173,7 @@ typedef struct PCIIORegion { #define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */ #define PCI_IO_BASE 0x1c /* I/O range behind the bridge */ #define PCI_IO_LIMIT 0x1d +#define PCI_IO_RANGE_TYPE_32 0x01 #define PCI_IO_RANGE_MASK (~0x0fUL) #define PCI_MEMORY_BASE 0x20 /* Memory range behind */ #define PCI_MEMORY_LIMIT 0x22
make pci_info_device() print out bridge's filtering value like io base/limit, subbus and subordinate bus. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> --- hw/pci.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/pci.h | 1 + 2 files changed, 56 insertions(+), 0 deletions(-)