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 /hw/phb4.c | |
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>
Diffstat (limited to 'hw/phb4.c')
-rw-r--r-- | hw/phb4.c | 10 |
1 files changed, 10 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 */ |