[Skiboot] [PATCH v2 6/9] phb4: Enable PHB MMIO in phb4_root_port_init()

Michael Neuling mikey at neuling.org
Mon Oct 23 21:22:19 AEDT 2017


Linux EEH flow is somewhat broken. It saves the PCIe config space of
the PHB on boot, which it then uses to restore on EEH recovery. It
does this to restore MMIO bars and some other pieces.

Unfortunately this save is done before any drivers are bound to
devices under the PHB. A number of other things are configured in the
PHB after drivers start, hence some configuration space settings
aren't saved correctly. These include bus master and MMIO bits in the
command register.

Linux tried to hack around this in this linux commit
  bf898ec5cb powerpc/eeh: Enable PCI_COMMAND_MASTER for PCI bridges
This sets the bus master bit but ignores the MMIO bit.

Hence we lose MMIO after a full PHB reset. This causes the next MMIO
access to the device to fail and for us to perform a PE freeze
recovery, which still doesn't set the MMIO bit and hence we still
fail.

This works around this by forcing MMIO on during
phb4_root_port_init().

With this we can recovery from a PHB fence event on POWER9.

Signed-off-by: Michael Neuling <mikey at neuling.org>
---
v2: Move the hacking of MMIO bit from phb4_rc_write() to
  phb4_root_port_init() which is more palatable. It also better
  describes the problem. I'm still not super happy with this, but
  modulo rewriting our EEH stack, this works.
---
 hw/phb4.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/phb4.c b/hw/phb4.c
index b75cec0480..cb24188a42 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -139,7 +139,6 @@ static void phb4_init_hw(struct phb4 *p, bool first_init);
 #define PHBERR(p, fmt, a...)	prlog(PR_ERR, "PHB#%04x[%d:%d]: " fmt, \
 				      (p)->phb.opal_id, (p)->chip_id, \
 				      (p)->index,  ## a)
-
 #ifdef LOG_CFG
 #define PHBLOGCFG(p, fmt, a...)	PHBDBG(p, fmt, ## a)
 #else
@@ -639,7 +638,8 @@ static void phb4_root_port_init(struct phb *phb, struct pci_device *dev,
 
 	/* Enable SERR and parity checking */
 	pci_cfg_read16(phb, bdfn, PCI_CFG_CMD, &val16);
-	val16 |= (PCI_CFG_CMD_SERR_EN | PCI_CFG_CMD_PERR_RESP);
+	val16 |= (PCI_CFG_CMD_SERR_EN | PCI_CFG_CMD_PERR_RESP |
+		  PCI_CFG_CMD_MEM_EN);
 	pci_cfg_write16(phb, bdfn, PCI_CFG_CMD, val16);
 
 	/* Enable reporting various errors */
-- 
2.14.1



More information about the Skiboot mailing list