[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH V6 17/32] pci: 64bit bar support.
From: |
Isaku Yamahata |
Subject: |
[Qemu-devel] [PATCH V6 17/32] pci: 64bit bar support. |
Date: |
Fri, 30 Oct 2009 21:21:11 +0900 |
implemented pci 64bit bar support.
The tricky bit is pci_update_mapping().
An OS is allowed to set the BAR such that OS can't address the area
pointed by BAR. It doesn't make sense, though.
In that case, don't map the BAR.
Signed-off-by: Isaku Yamahata <address@hidden>
---
hw/pci.c | 35 ++++++++++++++++++++++++++++++-----
hw/pci.h | 1 +
2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/hw/pci.c b/hw/pci.c
index b462bd6..7da3db9 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -484,8 +484,14 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
wmask |= PCI_ROM_ADDRESS_ENABLE;
}
pci_set_long(pci_dev->config + addr, type);
- pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);
- pci_set_long(pci_dev->cmask + addr, 0xffffffff);
+ if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) &&
+ r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+ pci_set_quad(pci_dev->wmask + addr, wmask);
+ pci_set_quad(pci_dev->cmask + addr, ~0ULL);
+ } else {
+ pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);
+ pci_set_long(pci_dev->cmask + addr, 0xffffffff);
+ }
}
static void pci_update_mappings(PCIDevice *d)
@@ -513,7 +519,11 @@ static void pci_update_mappings(PCIDevice *d)
}
} else {
if (cmd & PCI_COMMAND_MEMORY) {
- new_addr = pci_get_long(d->config + pci_bar(d, i));
+ 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;
@@ -531,7 +541,15 @@ static void pci_update_mappings(PCIDevice *d)
* Without this, PC ide doesn't work well.
* TODO: remove this work around.
*/
- last_addr >= UINT32_MAX) {
+ (!(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 {
@@ -773,8 +791,15 @@ static void pci_info_device(PCIDevice *d)
" [0x%04"FMT_PCIBUS"].\n",
r->addr, r->addr + r->size - 1);
} else {
- monitor_printf(mon, "32 bit memory at 0x%08"FMT_PCIBUS
+ const char *type = r->type & PCI_BASE_ADDRESS_MEM_TYPE_64 ?
+ "64 bit" : "32 bit";
+ const char *prefetch =
+ r->type & PCI_BASE_ADDRESS_MEM_PREFETCH ?
+ " prefetchable" : "";
+
+ monitor_printf(mon, "%s%s memory at 0x%08"FMT_PCIBUS
" [0x%08"FMT_PCIBUS"].\n",
+ type, prefetch,
r->addr, r->addr + r->size - 1);
}
}
diff --git a/hw/pci.h b/hw/pci.h
index 305c030..e83faf5 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -114,6 +114,7 @@ typedef struct PCIIORegion {
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
--
1.6.0.2
- [Qemu-devel] [PATCH V6 00/32] pci: various pci clean up and pci express support., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 10/32] pci: clean up of pci_default_read_config., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 06/32] pci: use helper functions to access pci config space., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 05/32] pci: helper functions to access PCIDevice::config, Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 11/32] pci: make pci_bar() aware of header type 1., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 17/32] pci: 64bit bar support.,
Isaku Yamahata <=
- [Qemu-devel] [PATCH V6 16/32] pci: typedef pcibus_t as uint64_t instead of uint32_t., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 02/32] pci: introduce constant PCI_NUM_PINS for the number of interrupt pins, 4., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 14/32] pci: introduce pcibus_t to represent pci bus address/size instead of uint32_t, Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 15/32] pci: introduce FMT_PCIBUS for printf format for pcibus_t., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 01/32] pci: fix PCI_DPRINTF() wrt variadic macro., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 18/32] pci: remove bus_num member from struct PCIBus., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 21/32] pci: move pci host stuff from pci.c to pci_host.c, Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 27/32] pci: teach pci_default_config_write() ROM bar for normal/bridge device ., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 26/32] pci: use range helper functions., Isaku Yamahata, 2009/10/30
- [Qemu-devel] [PATCH V6 03/32] pci: use PCI_SLOT() and PCI_FUNC()., Isaku Yamahata, 2009/10/30