[Skiboot] [PATCH 1/5] phb4: Complete reset implementation
Russell Currey
ruscur at russell.cc
Fri Jun 9 16:06:02 AEST 2017
This implements complete reset (creset) functionality for POWER9 DD1.
Only partially tested and contends with some DD1 errata, but it's a start.
Signed-off-by: Russell Currey <ruscur at russell.cc>
---
hw/phb4.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
include/phb4.h | 1 +
2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/hw/phb4.c b/hw/phb4.c
index 3843456f..c97861aa 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -2114,6 +2114,7 @@ static int64_t phb4_freset(struct pci_slot *slot)
static int64_t phb4_creset(struct pci_slot *slot)
{
struct phb4 *p = phb_to_phb4(slot->phb);
+ uint64_t pbcq_status;
switch (slot->state) {
case PHB4_SLOT_NORMAL:
@@ -2125,16 +2126,55 @@ static int64_t phb4_creset(struct pci_slot *slot)
if (p->flags & PHB4_CAPP_RECOVERY)
do_capp_recovery_scoms(p);
#endif
- /* XXX TODO XXX */
+
+ /* Clear error inject register, preventing recursive errors */
+ xscom_write(p->chip_id, p->pe_xscom + 0x2, 0x0);
+
+ /* Force fence on the PHB to work around a non-existent PE */
+ if (!phb4_fenced(p))
+ xscom_write(p->chip_id, p->pe_stk_xscom + 0x2,
+ 0x000000f000000000);
+
+ /* Clear errors in NFIR and raise ETU reset */
+ xscom_read(p->chip_id, p->pe_stk_xscom + 0x0, &p->nfir_cache);
+ xscom_read(p->chip_id, p->pci_stk_xscom + 0x0, &p->pfir_cache);
+
+ xscom_write(p->chip_id, p->pci_stk_xscom + 0x0,
+ 0x8000000000000000);
+
+ /* DD1 errata: write to PEST to force update */
+ phb4_ioda_sel(p, IODA3_TBL_PESTA, PHB4_RESERVED_PE_NUM(p), false);
+ out_be64(p->regs + PHB_IODA_DATA0, 0);
pci_slot_set_state(slot, PHB4_SLOT_CRESET_WAIT_CQ);
slot->retries = 500;
return pci_slot_set_sm_timeout(slot, msecs_to_tb(10));
case PHB4_SLOT_CRESET_WAIT_CQ:
- /* XXX TODO XXX */
+ // Wait until operations are complete
+ xscom_read(p->chip_id, p->pe_stk_xscom + 0xc, &pbcq_status);
+ if (!(pbcq_status & 0xC000000000000000)) {
+ PHBDBG(p, "CRESET: No pending transactions\n");
+
+ xscom_write(p->chip_id, p->pe_stk_xscom + 0x1,
+ ~p->nfir_cache);
+ xscom_write(p->chip_id, p->pci_stk_xscom + 0x1,
+ ~p->pfir_cache);
+
+ // Clear PHB from reset
+ xscom_write(p->chip_id, p->pci_stk_xscom + 0x0, 0x0);
+
+ pci_slot_set_state(slot, PHB4_SLOT_CRESET_REINIT);
+ return pci_slot_set_sm_timeout(slot, msecs_to_tb(100));
+ }
+
+ if (slot->retries-- == 0) {
+ PHBERR(p, "Timeout waiting for pending transaction\n");
+ goto error;
+ }
pci_slot_set_state(slot, PHB4_SLOT_CRESET_REINIT);
return pci_slot_set_sm_timeout(slot, msecs_to_tb(100));
case PHB4_SLOT_CRESET_REINIT:
+ PHBDBG(p, "CRESET: Reinitialization\n");
p->flags &= ~PHB4_AIB_FENCED;
p->flags &= ~PHB4_CAPP_RECOVERY;
phb4_init_hw(p, false);
@@ -2148,6 +2188,7 @@ static int64_t phb4_creset(struct pci_slot *slot)
slot->state);
}
+error:
/* Mark the PHB as dead and expect it to be removed */
p->state = PHB4_STATE_BROKEN;
return OPAL_HARDWARE;
diff --git a/include/phb4.h b/include/phb4.h
index 3ec8a5b8..3a349f05 100644
--- a/include/phb4.h
+++ b/include/phb4.h
@@ -275,6 +275,7 @@ struct phb4 {
uint64_t mbt_cache[32][2];
uint64_t mdt_cache[512]; /* max num of PEs */
uint64_t mist_cache[4096/4];/* max num of MSIs */
+ uint64_t pfir_cache; /* Used by complete reset */
uint64_t nfir_cache; /* Used by complete reset */
bool err_pending;
struct phb4_err err;
--
2.13.1
More information about the Skiboot
mailing list