diff options
author | Oliver O'Halloran <oohall@gmail.com> | 2019-08-02 18:00:03 +1000 |
---|---|---|
committer | Oliver O'Halloran <oohall@gmail.com> | 2019-08-16 15:51:55 +1000 |
commit | b310e8f79e6817e18bd0e3c606da50a00b425ef0 (patch) | |
tree | ce32f54dcd49d92af5e88bc7b849ee083187a820 | |
parent | a36a49440f60d5e8a9f8f61885bb99b376f149c5 (diff) | |
download | skiboot-b310e8f79e6817e18bd0e3c606da50a00b425ef0.zip skiboot-b310e8f79e6817e18bd0e3c606da50a00b425ef0.tar.gz skiboot-b310e8f79e6817e18bd0e3c606da50a00b425ef0.tar.bz2 |
hw/phb4: Prevent register accesses when in reset
While the the ETU is in reset we cannot access any of the PHB registers.
If a PHB register is accessed via the XSCOM indirect interface then
we'll cause an ETU reset error which may prevent the PHB from being
re-initialised once the reset is lifted.
Prevent register accesses while in reset by adding a flag that is set
while the ETU reset bit is high and checking that flag in the XSCOM
(ASB) backdoor register access path.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
-rw-r--r-- | hw/phb4.c | 10 | ||||
-rw-r--r-- | include/phb4.h | 1 |
2 files changed, 11 insertions, 0 deletions
@@ -214,6 +214,10 @@ static inline void phb4_write_reg_asb(struct phb4 *p, static uint64_t phb4_read_reg(struct phb4 *p, uint32_t offset) { + /* No register accesses are permitted while in reset */ + if (p->flags & PHB4_ETU_IN_RESET) + return -1ull; + if (p->flags & PHB4_CFG_USE_ASB) return phb4_read_reg_asb(p, offset); else @@ -222,6 +226,10 @@ static uint64_t phb4_read_reg(struct phb4 *p, uint32_t offset) static void phb4_write_reg(struct phb4 *p, uint32_t offset, uint64_t val) { + /* No register accesses are permitted while in reset */ + if (p->flags & PHB4_ETU_IN_RESET) + return; + if (p->flags & PHB4_CFG_USE_ASB) phb4_write_reg_asb(p, offset, val); else @@ -3282,6 +3290,7 @@ static int64_t phb4_creset(struct pci_slot *slot) phb4_err_clear(p); /* Actual reset */ + p->flags |= PHB4_ETU_IN_RESET; xscom_write(p->chip_id, p->pci_stk_xscom + XPEC_PCI_STK_ETU_RESET, 0x8000000000000000UL); @@ -3335,6 +3344,7 @@ static int64_t phb4_creset(struct pci_slot *slot) /* Clear PHB from reset */ xscom_write(p->chip_id, p->pci_stk_xscom + XPEC_PCI_STK_ETU_RESET, 0x0); + p->flags &= ~PHB4_ETU_IN_RESET; pci_slot_set_state(slot, PHB4_SLOT_CRESET_REINIT); /* After lifting PHB reset, wait while logic settles */ diff --git a/include/phb4.h b/include/phb4.h index af2e3ed..1c68ec2 100644 --- a/include/phb4.h +++ b/include/phb4.h @@ -151,6 +151,7 @@ struct phb4_err { #define PHB4_CFG_BLOCKED 0x00000004 #define PHB4_CAPP_RECOVERY 0x00000008 #define PHB4_CAPP_DISABLE 0x00000010 +#define PHB4_ETU_IN_RESET 0x00000020 struct phb4 { unsigned int index; /* 0..5 index inside p9 */ |