[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH V2 16/20] pci: split up up pci_update mappings
From: |
Isaku Yamahata |
Subject: |
[Qemu-devel] [PATCH V2 16/20] pci: split up up pci_update mappings |
Date: |
Fri, 13 Nov 2009 13:29:52 +0900 |
From: Michael S. Tsirkin <address@hidden>
Split bar address math into a separate function.
In particular, this gets rid of an ugly forward goto
into scope that we have there.
Signed-off-by: Michael S. Tsirkin <address@hidden>
Acked-by: Isaku Yamahata <address@hidden>
---
hw/pci.c | 125 +++++++++++++++++++++++++++++++++----------------------------
1 files changed, 68 insertions(+), 57 deletions(-)
diff --git a/hw/pci.c b/hw/pci.c
index bb3236c..24345b0 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -720,14 +720,77 @@ static void pci_bridge_filter(PCIDevice *d, pcibus_t
*addr, pcibus_t *size,
}
}
+static pcibus_t pci_bar_address(PCIDevice *d,
+ int reg, uint8_t type, pcibus_t size)
+{
+ pcibus_t new_addr, last_addr;
+ int bar = pci_bar(d, reg);
+ uint16_t cmd = pci_get_word(d->config + PCI_COMMAND);
+
+ if (type & PCI_BASE_ADDRESS_SPACE_IO) {
+ if (!(cmd & PCI_COMMAND_IO)) {
+ return PCI_BAR_UNMAPPED;
+ }
+ new_addr = pci_get_long(d->config + bar) & ~(size - 1);
+ last_addr = new_addr + size - 1;
+ /* NOTE: we have only 64K ioports on PC */
+ if (last_addr <= new_addr || new_addr == 0 || last_addr > UINT16_MAX) {
+ return PCI_BAR_UNMAPPED;
+ }
+ return new_addr;
+ }
+
+ if (!(cmd & PCI_COMMAND_MEMORY)) {
+ return PCI_BAR_UNMAPPED;
+ }
+ if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+ new_addr = pci_get_quad(d->config + bar);
+ } else {
+ new_addr = pci_get_long(d->config + bar);
+ }
+ /* the ROM slot has a specific enable bit */
+ if (reg == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE)) {
+ return PCI_BAR_UNMAPPED;
+ }
+ new_addr &= ~(size - 1);
+ last_addr = new_addr + size - 1;
+ /* NOTE: we do not support wrapping */
+ /* XXX: as we cannot support really dynamic
+ mappings, we handle specific values as invalid
+ mappings. */
+ if (last_addr <= new_addr || new_addr == 0 ||
+ last_addr == PCI_BAR_UNMAPPED) {
+ return PCI_BAR_UNMAPPED;
+ }
+
+ /* Now pcibus_t is 64bit.
+ * Check if 32 bit BAR wraps around explicitly.
+ * Without this, PC ide doesn't work well.
+ * TODO: remove this work around.
+ */
+ if (!(type & PCI_BASE_ADDRESS_MEM_TYPE_64) && last_addr >= UINT32_MAX) {
+ return PCI_BAR_UNMAPPED;
+ }
+
+ /*
+ * OS is allowed to set BAR beyond its addressable
+ * bits. For example, 32 bit OS can set 64bit bar
+ * to >4G. Check it. TODO: we might need to support
+ * it in the future for e.g. PAE.
+ */
+ if (last_addr >= TARGET_PHYS_ADDR_MAX) {
+ return PCI_BAR_UNMAPPED;
+ }
+
+ return new_addr;
+}
+
static void pci_update_mappings(PCIDevice *d)
{
PCIIORegion *r;
- int cmd, i;
- pcibus_t last_addr, new_addr;
- pcibus_t filtered_size;
+ int i;
+ pcibus_t new_addr, filtered_size;
- cmd = pci_get_word(d->config + PCI_COMMAND);
for(i = 0; i < PCI_NUM_REGIONS; i++) {
r = &d->io_regions[i];
@@ -735,59 +798,7 @@ static void pci_update_mappings(PCIDevice *d)
if (!r->size)
continue;
- if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
- if (cmd & PCI_COMMAND_IO) {
- new_addr = pci_get_long(d->config + pci_bar(d, i));
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we have only 64K ioports on PC */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr >= 0x10000) {
- new_addr = PCI_BAR_UNMAPPED;
- }
- } else {
- new_addr = PCI_BAR_UNMAPPED;
- }
- } else {
- if (cmd & PCI_COMMAND_MEMORY) {
- if (r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
- new_addr = pci_get_quad(d->config + pci_bar(d, i));
- } else {
- new_addr = pci_get_long(d->config + pci_bar(d, i));
- }
- /* the ROM slot has a specific enable bit */
- if (i == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE))
- goto no_mem_map;
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we do not support wrapping */
- /* XXX: as we cannot support really dynamic
- mappings, we handle specific values as invalid
- mappings. */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr == PCI_BAR_UNMAPPED ||
-
- /* Now pcibus_t is 64bit.
- * Check if 32 bit BAR wrap around explicitly.
- * Without this, PC ide doesn't work well.
- * TODO: remove this work around.
- */
- (!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) &&
- last_addr >= UINT32_MAX) ||
-
- /*
- * OS is allowed to set BAR beyond its addressable
- * bits. For example, 32 bit OS can set 64bit bar
- * to >4G. Check it.
- */
- last_addr >= TARGET_PHYS_ADDR_MAX) {
- new_addr = PCI_BAR_UNMAPPED;
- }
- } else {
- no_mem_map:
- new_addr = PCI_BAR_UNMAPPED;
- }
- }
+ new_addr = pci_bar_address(d, i, r->type, r->size);
/* bridge filtering */
filtered_size = r->size;
--
1.6.0.2
- [Qemu-devel] [PATCH V2 07/20] pci: remove pci_sub_bus() by open coding., (continued)
- [Qemu-devel] [PATCH V2 07/20] pci: remove pci_sub_bus() by open coding., Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 09/20] pci_host: remove unnecessary & 0xff., Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 13/20] pci: move typedef, PCIHostState, PCIExpressHost to qemu-common.h., Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 17/20] pci: remove magic number, 256 in pci.c, Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 14/20] pci: remove unused constants., Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 19/20] pci: pci bridge related clean up., Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 06/20] pci: shorten pci_host_{conf, data}_register_xxx function a bit., Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 12/20] pci: remove some unnecessary comment in pci.h, Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 15/20] pci: clean up of pci_update_mappings(), Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 08/20] pci: s/pci_find_host_bus/pci_find_root_bus/g, Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 16/20] pci: split up up pci_update mappings,
Isaku Yamahata <=
- [Qemu-devel] [PATCH V2 18/20] pci: fix pci_config_get_io_base()., Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 10/20] pci: kill unnecessary included in pci.c, Isaku Yamahata, 2009/11/12
- [Qemu-devel] [PATCH V2 20/20] pci: convert goto into scope in bridge_filter, Isaku Yamahata, 2009/11/13
- [Qemu-devel] [PATCH V2 04/20] pci: remove pci_addr_to_config() by open code, Isaku Yamahata, 2009/11/13