[Skiboot] [PATCH 1/4] phb4: Implement diag data
Russell Currey
ruscur at russell.cc
Mon Apr 10 11:57:34 AEST 2017
Implement PHB4 diagnostic data, similar to PHB3. There are a few
registers that have changed, but everything is largely the same.
Signed-off-by: Russell Currey <ruscur at russell.cc>
---
hw/phb4.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++
include/opal-api.h | 58 ++++++++++++++++++++++++++-
include/phb4-regs.h | 86 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 253 insertions(+), 2 deletions(-)
diff --git a/hw/phb4.c b/hw/phb4.c
index 571f7037..6c7bb9fe 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -1526,12 +1526,123 @@ static void phb4_err_ER_clear(struct phb4 *p)
static void phb4_read_phb_status(struct phb4 *p,
struct OpalIoPhb4ErrorData *stat)
{
+ uint16_t val = 0;
+ uint32_t i;
+ uint64_t val64 = 0;
+ uint64_t *pPEST;
+
memset(stat, 0, sizeof(struct OpalIoPhb4ErrorData));
/* Error data common part */
stat->common.version = OPAL_PHB_ERROR_DATA_VERSION_1;
stat->common.ioType = OPAL_PHB_ERROR_DATA_TYPE_PHB4;
stat->common.len = sizeof(struct OpalIoPhb4ErrorData);
+
+ /*
+ * TODO: investigate reading registers through ASB instead of AIB.
+ *
+ * Until this is implemented, some registers may be unreadable through
+ * a fence.
+ */
+
+ /* Grab RC bridge control, make it 32-bit */
+ phb4_pcicfg_read16(&p->phb, 0, PCI_CFG_BRCTL, &val);
+ stat->brdgCtl = val;
+
+ /* XXX: No UTL registers on PHB4? */
+
+ /*
+ * Grab various RC PCIe capability registers. All device, slot
+ * and link status are 16-bit, so we grab the pair control+status
+ * for each of them
+ */
+ phb4_pcicfg_read32(&p->phb, 0, p->ecap + PCICAP_EXP_DEVCTL,
+ &stat->deviceStatus);
+ phb4_pcicfg_read32(&p->phb, 0, p->ecap + PCICAP_EXP_SLOTCTL,
+ &stat->slotStatus);
+ phb4_pcicfg_read32(&p->phb, 0, p->ecap + PCICAP_EXP_LCTL,
+ &stat->linkStatus);
+
+ /*
+ * I assume those are the standard config space header, cmd & status
+ * together makes 32-bit. Secondary status is 16-bit so I'll clear
+ * the top on that one
+ */
+ phb4_pcicfg_read32(&p->phb, 0, PCI_CFG_CMD, &stat->devCmdStatus);
+ phb4_pcicfg_read16(&p->phb, 0, PCI_CFG_SECONDARY_STATUS, &val);
+ stat->devSecStatus = val;
+
+ /* Grab a bunch of AER regs */
+ phb4_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_RERR_STA,
+ &stat->rootErrorStatus);
+ phb4_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_UE_STATUS,
+ &stat->uncorrErrorStatus);
+ phb4_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_CE_STATUS,
+ &stat->corrErrorStatus);
+ phb4_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_HDR_LOG0,
+ &stat->tlpHdr1);
+ phb4_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_HDR_LOG1,
+ &stat->tlpHdr2);
+ phb4_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_HDR_LOG2,
+ &stat->tlpHdr3);
+ phb4_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_HDR_LOG3,
+ &stat->tlpHdr4);
+ phb4_pcicfg_read32(&p->phb, 0, p->aercap + PCIECAP_AER_SRCID,
+ &stat->sourceId);
+
+ /* PEC NFIR, same as P8/PHB3 */
+ xscom_read(p->chip_id, p->pe_stk_xscom + 0x0, &stat->nFir);
+ xscom_read(p->chip_id, p->pe_stk_xscom + 0x3, &stat->nFirMask);
+ xscom_read(p->chip_id, p->pe_stk_xscom + 0x8, &stat->nFirWOF);
+
+ /* PHB4 inbound and outbound error Regs */
+ stat->phbPlssr = phb4_read_reg_asb(p, PHB_CPU_LOADSTORE_STATUS);
+ stat->phbCsr = phb4_read_reg_asb(p, PHB_DMA_CHAN_STATUS);
+ stat->lemFir = phb4_read_reg_asb(p, PHB_LEM_FIR_ACCUM);
+ stat->lemErrorMask = phb4_read_reg_asb(p, PHB_LEM_ERROR_MASK);
+ stat->lemWOF = phb4_read_reg_asb(p, PHB_LEM_WOF);
+ stat->phbErrorStatus = phb4_read_reg_asb(p, PHB_ERR_STATUS);
+ stat->phbFirstErrorStatus = phb4_read_reg_asb(p, PHB_ERR1_STATUS);
+ stat->phbErrorLog0 = phb4_read_reg_asb(p, PHB_ERR_LOG_0);
+ stat->phbErrorLog1 = phb4_read_reg_asb(p, PHB_ERR_LOG_1);
+ stat->mmioErrorStatus = phb4_read_reg_asb(p, PHB_TXE_ERR_STATUS);
+ stat->mmioFirstErrorStatus = phb4_read_reg_asb(p, PHB_TXE_ERR1_STATUS);
+ stat->mmioErrorLog0 = phb4_read_reg_asb(p, PHB_TXE_ERR_LOG_0);
+ stat->mmioErrorLog1 = phb4_read_reg_asb(p, PHB_TXE_ERR_LOG_1);
+ stat->dma0ErrorStatus = phb4_read_reg_asb(p, PHB_RXE_ARB_ERR_STATUS);
+ stat->dma0FirstErrorStatus = phb4_read_reg_asb(p, PHB_RXE_ARB_ERR1_STATUS);
+ stat->dma0ErrorLog0 = phb4_read_reg_asb(p, PHB_RXE_ARB_ERR_LOG_0);
+ stat->dma0ErrorLog1 = phb4_read_reg_asb(p, PHB_RXE_ARB_ERR_LOG_1);
+ stat->dma1ErrorStatus = phb4_read_reg_asb(p, PHB_RXE_MRG_ERR_STATUS);
+ stat->dma1FirstErrorStatus = phb4_read_reg_asb(p, PHB_RXE_MRG_ERR1_STATUS);
+ stat->dma1ErrorLog0 = phb4_read_reg_asb(p, PHB_RXE_MRG_ERR_LOG_0);
+ stat->dma1ErrorLog1 = phb4_read_reg_asb(p, PHB_RXE_MRG_ERR_LOG_1);
+ stat->dma2ErrorStatus = phb4_read_reg_asb(p, PHB_RXE_TCE_ERR_STATUS);
+ stat->dma2FirstErrorStatus = phb4_read_reg_asb(p, PHB_RXE_TCE_ERR1_STATUS);
+ stat->dma2ErrorLog0 = phb4_read_reg_asb(p, PHB_RXE_TCE_ERR_LOG_0);
+ stat->dma2ErrorLog1 = phb4_read_reg_asb(p, PHB_RXE_TCE_ERR_LOG_1);
+
+ /*
+ * Grab PESTA & B content. The error bit (bit#0) should
+ * be fetched from IODA and the left content from memory
+ * resident tables.
+ */
+ pPEST = (uint64_t *)p->tbl_pest;
+ val64 = PHB_IODA_AD_AUTOINC;
+ val64 = SETFIELD(PHB_IODA_AD_TSEL, val64, IODA3_TBL_PESTA);
+ phb4_write_reg_asb(p, PHB_IODA_ADDR, val64);
+ for (i = 0; i < OPAL_PHB4_NUM_PEST_REGS; i++) {
+ stat->pestA[i] = phb4_read_reg_asb(p, PHB_IODA_DATA0);
+ stat->pestA[i] |= pPEST[2 * i];
+ }
+
+ val64 = PHB_IODA_AD_AUTOINC;
+ val64 = SETFIELD(PHB_IODA_AD_TSEL, val64, IODA3_TBL_PESTB);
+ phb4_write_reg_asb(p, PHB_IODA_ADDR, val64);
+ for (i = 0; i < OPAL_PHB4_NUM_PEST_REGS; i++) {
+ stat->pestB[i] = phb4_read_reg_asb(p, PHB_IODA_DATA0);
+ stat->pestB[i] |= pPEST[2 * i + 1];
+ }
}
static int64_t phb4_set_pe(struct phb *phb,
diff --git a/include/opal-api.h b/include/opal-api.h
index 7966200e..101e4be7 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -809,7 +809,8 @@ enum {
enum {
OPAL_P7IOC_NUM_PEST_REGS = 128,
- OPAL_PHB3_NUM_PEST_REGS = 256
+ OPAL_PHB3_NUM_PEST_REGS = 256,
+ OPAL_PHB4_NUM_PEST_REGS = 512
};
struct OpalIoPhbErrorCommon {
@@ -941,7 +942,60 @@ struct OpalIoPhb3ErrorData {
struct OpalIoPhb4ErrorData {
struct OpalIoPhbErrorCommon common;
- // FIXME add phb4 specific stuff
+
+ __be32 brdgCtl;
+
+ /* XXX missing UTL registers? */
+
+ /* PHB4 cfg regs */
+ __be32 deviceStatus;
+ __be32 slotStatus;
+ __be32 linkStatus;
+ __be32 devCmdStatus;
+ __be32 devSecStatus;
+
+ /* cfg AER regs */
+ __be32 rootErrorStatus;
+ __be32 uncorrErrorStatus;
+ __be32 corrErrorStatus;
+ __be32 tlpHdr1;
+ __be32 tlpHdr2;
+ __be32 tlpHdr3;
+ __be32 tlpHdr4;
+ __be32 sourceId;
+
+ /* PHB4 MMIO Error Regs */
+ __be64 nFir; /* 000 */
+ __be64 nFirMask; /* 003 */
+ __be64 nFirWOF; /* 008 */
+ __be64 phbPlssr; /* 120 */
+ __be64 phbCsr; /* 110 */
+ __be64 lemFir; /* C00 */
+ __be64 lemErrorMask; /* C18 */
+ __be64 lemWOF; /* C40 */
+ __be64 phbErrorStatus; /* C80 */
+ __be64 phbFirstErrorStatus; /* C88 */
+ __be64 phbErrorLog0; /* CC0 */
+ __be64 phbErrorLog1; /* CC8 */
+ __be64 mmioErrorStatus; /* D00 */
+ __be64 mmioFirstErrorStatus; /* D08 */
+ __be64 mmioErrorLog0; /* D40 */
+ __be64 mmioErrorLog1; /* D48 */
+ __be64 dma0ErrorStatus; /* D80 */
+ __be64 dma0FirstErrorStatus; /* D88 */
+ __be64 dma0ErrorLog0; /* DC0 */
+ __be64 dma0ErrorLog1; /* DC8 */
+ __be64 dma1ErrorStatus; /* E00 */
+ __be64 dma1FirstErrorStatus; /* E08 */
+ __be64 dma1ErrorLog0; /* E40 */
+ __be64 dma1ErrorLog1; /* E48 */
+ __be64 dma2ErrorStatus; /* E80 */
+ __be64 dma2FirstErrorStatus; /* E88 */
+ __be64 dma2ErrorLog0; /* EC0 */
+ __be64 dma2ErrorLog1; /* EC8 */
+
+ __be64 pestA[OPAL_PHB4_NUM_PEST_REGS];
+ __be64 pestB[OPAL_PHB4_NUM_PEST_REGS];
};
enum {
diff --git a/include/phb4-regs.h b/include/phb4-regs.h
index 48953e40..2ae95801 100644
--- a/include/phb4-regs.h
+++ b/include/phb4-regs.h
@@ -187,6 +187,92 @@
#define PHB_PCIE_LANE_EQ_CNTL22 0x1B00 /* DD1 only */
#define PHB_PCIE_LANE_EQ_CNTL23 0x1B08 /* DD1 only */
+/* Fundamental register set B - some missing from PHB3 */
+#define PHB_VERSION 0x800
+#define PHB_CONTROL 0x810
+#define PHB_AIB_FENCE_CTRL 0x860
+#define PHB_TCE_TAG_ENABLE 0x868
+#define PHB_TCE_WATERMARK 0x870
+#define PHB_TIMEOUT_CTRL1 0x878
+#define PHB_TIMEOUT_CTRL2 0x880
+#define PHB_QUIESCE_DMA_G 0x888
+#define PHB_TCE_TAG_STATUS 0x908
+
+/* FIR & Error registers - identical to PHB3 */
+#define PHB_LEM_FIR_ACCUM 0xc00
+#define PHB_LEM_FIR_AND_MASK 0xc08
+#define PHB_LEM_FIR_OR_MASK 0xc10
+#define PHB_LEM_ERROR_MASK 0xc18
+#define PHB_LEM_ERROR_AND_MASK 0xc20
+#define PHB_LEM_ERROR_OR_MASK 0xc28
+#define PHB_LEM_ACTION0 0xc30
+#define PHB_LEM_ACTION1 0xc38
+#define PHB_LEM_WOF 0xc40
+#define PHB_ERR_STATUS 0xc80
+#define PHB_ERR1_STATUS 0xc88
+#define PHB_ERR_INJECT 0xc90
+#define PHB_ERR_LEM_ENABLE 0xc98
+#define PHB_ERR_IRQ_ENABLE 0xca0
+#define PHB_ERR_FREEZE_ENABLE 0xca8
+#define PHB_ERR_AIB_FENCE_ENABLE 0xcb0
+#define PHB_ERR_LOG_0 0xcc0
+#define PHB_ERR_LOG_1 0xcc8
+#define PHB_ERR_STATUS_MASK 0xcd0
+#define PHB_ERR1_STATUS_MASK 0xcd8
+
+/*
+ * Instead of MMIO outbound, inboundA and inboundB in PHB3,
+ * PHB4 has TXE (outbound), RXE_ARB, RXE_MRG and RXE_TCE.
+ */
+
+#define PHB_TXE_ERR_STATUS 0xd00
+#define PHB_TXE_ERR1_STATUS 0xd08
+#define PHB_TXE_ERR_INJECT 0xd10
+#define PHB_TXE_ERR_LEM_ENABLE 0xd18
+#define PHB_TXE_ERR_IRQ_ENABLE 0xd20
+#define PHB_TXE_ERR_FREEZE_ENABLE 0xd28
+#define PHB_TXE_ERR_AIB_FENCE_ENABLE 0xd30
+#define PHB_TXE_ERR_LOG_0 0xd40
+#define PHB_TXE_ERR_LOG_1 0xd48
+#define PHB_TXE_ERR_STATUS_MASK 0xd50
+#define PHB_TXE_ERR1_STATUS_MASK 0xd58
+
+#define PHB_RXE_ARB_ERR_STATUS 0xd80
+#define PHB_RXE_ARB_ERR1_STATUS 0xd88
+#define PHB_RXE_ARB_ERR_INJECT 0xd90
+#define PHB_RXE_ARB_ERR_LEM_ENABLE 0xd98
+#define PHB_RXE_ARB_ERR_IRQ_ENABLE 0xda0
+#define PHB_RXE_ARB_ERR_FREEZE_ENABLE 0xda8
+#define PHB_RXE_ARB_ERR_AIB_FENCE_ENABLE 0xdb0
+#define PHB_RXE_ARB_ERR_LOG_0 0xdc0
+#define PHB_RXE_ARB_ERR_LOG_1 0xdc8
+#define PHB_RXE_ARB_ERR_STATUS_MASK 0xdd0
+#define PHB_RXE_ARB_ERR1_STATUS_MASK 0xdd8
+
+#define PHB_RXE_MRG_ERR_STATUS 0xe00
+#define PHB_RXE_MRG_ERR1_STATUS 0xe08
+#define PHB_RXE_MRG_ERR_INJECT 0xe10
+#define PHB_RXE_MRG_ERR_LEM_ENABLE 0xe18
+#define PHB_RXE_MRG_ERR_IRQ_ENABLE 0xe20
+#define PHB_RXE_MRG_ERR_FREEZE_ENABLE 0xe28
+#define PHB_RXE_MRG_ERR_AIB_FENCE_ENABLE 0xe30
+#define PHB_RXE_MRG_ERR_LOG_0 0xe40
+#define PHB_RXE_MRG_ERR_LOG_1 0xe48
+#define PHB_RXE_MRG_ERR_STATUS_MASK 0xe50
+#define PHB_RXE_MRG_ERR1_STATUS_MASK 0xe58
+
+#define PHB_RXE_TCE_ERR_STATUS 0xe80
+#define PHB_RXE_TCE_ERR1_STATUS 0xe88
+#define PHB_RXE_TCE_ERR_INJECT 0xe90
+#define PHB_RXE_TCE_ERR_LEM_ENABLE 0xe98
+#define PHB_RXE_TCE_ERR_IRQ_ENABLE 0xea0
+#define PHB_RXE_TCE_ERR_FREEZE_ENABLE 0xea8
+#define PHB_RXE_TCE_ERR_AIB_FENCE_ENABLE 0xeb0
+#define PHB_RXE_TCE_ERR_LOG_0 0xec0
+#define PHB_RXE_TCE_ERR_LOG_1 0xec8
+#define PHB_RXE_TCE_ERR_STATUS_MASK 0xed0
+#define PHB_RXE_TCE_ERR1_STATUS_MASK 0xed8
+
/*
* PHB4 xscom address defines
*/
--
2.12.1
More information about the Skiboot
mailing list