[OpenBIOS] [PATCH 1/2] PPC: Fix PCI configuration space address access

Mark Cave-Ayland mark.cave-ayland at ilande.co.uk
Sat Aug 31 17:05:09 CEST 2013


This patch corrects two long-standing bugs with PPC PCI configuration space
access. Firstly fix the calculation of PCI configuration space addresses by
the PCI_ADDR macro; this was incorrectly using arch->cfg_base which is the
mapped address and has nothing to do with the PCI configuration space
address. Instead just set bit 31 to initiate a configuration cycle as per the
PCI specification.

Secondly, fix pci_config_read32() and pci_config_write16() which were
incorrectly adding the register offset to the PCI IO dataport address causing
them to write into unknown address space for registers > 0. It appears that
this only worked purely by coincidence with QEMU due to the way in which the
configuration address was calculated for an oversized PCI configuration IO
dataport MemoryRegion.

Reported-by: Hervé Poussineau <hpoussin at reactos.org>
CC: Hervé Poussineau <hpoussin at reactos.org>
CC: Andreas Färber <afaerber at suse.de>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
 openbios-devel/include/arch/ppc/pci.h |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/openbios-devel/include/arch/ppc/pci.h b/openbios-devel/include/arch/ppc/pci.h
index cccefb1..d96bd7e 100644
--- a/openbios-devel/include/arch/ppc/pci.h
+++ b/openbios-devel/include/arch/ppc/pci.h
@@ -12,7 +12,7 @@
 /* PCI Configuration Mechanism #1 */
 
 #define PCI_ADDR(bus, dev, fn) \
-    ((pci_addr) (arch->cfg_base \
+    ((pci_addr) (0x80000000u \
 		| (uint32_t) (bus) << 16 \
 		| (uint32_t) (dev) << 11 \
 		| (uint32_t) (fn) << 8))
@@ -41,7 +41,7 @@ static inline uint32_t pci_config_read32(pci_addr dev, uint8_t reg)
 {
 	uint32_t res;
 	out_le32((unsigned *)arch->cfg_addr, dev | reg);
-	res = in_le32((unsigned *)(arch->cfg_data + reg));
+	res = in_le32((unsigned *)(arch->cfg_data));
 	return res;
 }
 
@@ -60,7 +60,7 @@ static inline void pci_config_write16(pci_addr dev, uint8_t reg, uint16_t val)
 static inline void pci_config_write32(pci_addr dev, uint8_t reg, uint32_t val)
 {
 	out_le32((unsigned *)arch->cfg_addr, dev | reg);
-	out_le32((unsigned *)(arch->cfg_data + reg), val);
+	out_le32((unsigned *)(arch->cfg_data), val);
 }
 #else /* !PCI_CONFIG_1 */
 #error PCI Configuration Mechanism is not specified or implemented
-- 
1.7.10.4




More information about the OpenBIOS mailing list