powerpc/powernv/pci: Add support for PHB4 diagnostics
authorRussell Currey <ruscur@russell.cc>
Wed, 14 Jun 2017 04:20:00 +0000 (14:20 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 27 Jun 2017 02:14:27 +0000 (12:14 +1000)
As with P7IOC and PHB3, add kernel-side support for decoding and printing
diagnostic data for PHB4.

Signed-off-by: Russell Currey <ruscur@russell.cc>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/opal-api.h
arch/powerpc/platforms/powernv/pci.c

index cb3e624..0b543f0 100644 (file)
@@ -667,12 +667,14 @@ enum {
 
 enum {
        OPAL_PHB_ERROR_DATA_TYPE_P7IOC = 1,
-       OPAL_PHB_ERROR_DATA_TYPE_PHB3 = 2
+       OPAL_PHB_ERROR_DATA_TYPE_PHB3 = 2,
+       OPAL_PHB_ERROR_DATA_TYPE_PHB4 = 3
 };
 
 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 {
@@ -802,6 +804,75 @@ struct OpalIoPhb3ErrorData {
        __be64 pestB[OPAL_PHB3_NUM_PEST_REGS];
 };
 
+struct OpalIoPhb4ErrorData {
+       struct OpalIoPhbErrorCommon common;
+
+       __be32 brdgCtl;
+
+       /* 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 ETU 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 phbTxeErrorStatus;               /* D00 */
+       __be64 phbTxeFirstErrorStatus;          /* D08 */
+       __be64 phbTxeErrorLog0;                 /* D40 */
+       __be64 phbTxeErrorLog1;                 /* D48 */
+       __be64 phbRxeArbErrorStatus;            /* D80 */
+       __be64 phbRxeArbFirstErrorStatus;       /* D88 */
+       __be64 phbRxeArbErrorLog0;              /* DC0 */
+       __be64 phbRxeArbErrorLog1;              /* DC8 */
+       __be64 phbRxeMrgErrorStatus;            /* E00 */
+       __be64 phbRxeMrgFirstErrorStatus;       /* E08 */
+       __be64 phbRxeMrgErrorLog0;              /* E40 */
+       __be64 phbRxeMrgErrorLog1;              /* E48 */
+       __be64 phbRxeTceErrorStatus;            /* E80 */
+       __be64 phbRxeTceFirstErrorStatus;       /* E88 */
+       __be64 phbRxeTceErrorLog0;              /* EC0 */
+       __be64 phbRxeTceErrorLog1;              /* EC8 */
+
+       /* PHB4 REGB Error Regs */
+       __be64 phbPblErrorStatus;               /* 1900 */
+       __be64 phbPblFirstErrorStatus;          /* 1908 */
+       __be64 phbPblErrorLog0;                 /* 1940 */
+       __be64 phbPblErrorLog1;                 /* 1948 */
+       __be64 phbPcieDlpErrorLog1;             /* 1AA0 */
+       __be64 phbPcieDlpErrorLog2;             /* 1AA8 */
+       __be64 phbPcieDlpErrorStatus;           /* 1AB0 */
+       __be64 phbRegbErrorStatus;              /* 1C00 */
+       __be64 phbRegbFirstErrorStatus;         /* 1C08 */
+       __be64 phbRegbErrorLog0;                /* 1C40 */
+       __be64 phbRegbErrorLog1;                /* 1C48 */
+
+       __be64 pestA[OPAL_PHB4_NUM_PEST_REGS];
+       __be64 pestB[OPAL_PHB4_NUM_PEST_REGS];
+};
+
 enum {
        OPAL_REINIT_CPUS_HILE_BE        = (1 << 0),
        OPAL_REINIT_CPUS_HILE_LE        = (1 << 1),
index 209ad47..7905d17 100644 (file)
@@ -426,6 +426,108 @@ static void pnv_pci_dump_phb3_diag_data(struct pci_controller *hose,
        pnv_pci_dump_pest(data->pestA, data->pestB, OPAL_PHB3_NUM_PEST_REGS);
 }
 
+static void pnv_pci_dump_phb4_diag_data(struct pci_controller *hose,
+                                       struct OpalIoPhbErrorCommon *common)
+{
+       struct OpalIoPhb4ErrorData *data;
+
+       data = (struct OpalIoPhb4ErrorData*)common;
+       pr_info("PHB4 PHB#%d Diag-data (Version: %d)\n",
+               hose->global_number, be32_to_cpu(common->version));
+       if (data->brdgCtl)
+               pr_info("brdgCtl:    %08x\n",
+                       be32_to_cpu(data->brdgCtl));
+       if (data->deviceStatus || data->slotStatus   ||
+           data->linkStatus   || data->devCmdStatus ||
+           data->devSecStatus)
+               pr_info("RootSts:    %08x %08x %08x %08x %08x\n",
+                       be32_to_cpu(data->deviceStatus),
+                       be32_to_cpu(data->slotStatus),
+                       be32_to_cpu(data->linkStatus),
+                       be32_to_cpu(data->devCmdStatus),
+                       be32_to_cpu(data->devSecStatus));
+       if (data->rootErrorStatus || data->uncorrErrorStatus ||
+           data->corrErrorStatus)
+               pr_info("RootErrSts: %08x %08x %08x\n",
+                       be32_to_cpu(data->rootErrorStatus),
+                       be32_to_cpu(data->uncorrErrorStatus),
+                       be32_to_cpu(data->corrErrorStatus));
+       if (data->tlpHdr1 || data->tlpHdr2 ||
+           data->tlpHdr3 || data->tlpHdr4)
+               pr_info("RootErrLog: %08x %08x %08x %08x\n",
+                       be32_to_cpu(data->tlpHdr1),
+                       be32_to_cpu(data->tlpHdr2),
+                       be32_to_cpu(data->tlpHdr3),
+                       be32_to_cpu(data->tlpHdr4));
+       if (data->sourceId)
+               pr_info("sourceId:   %08x\n", be32_to_cpu(data->sourceId));
+       if (data->nFir)
+               pr_info("nFir:       %016llx %016llx %016llx\n",
+                       be64_to_cpu(data->nFir),
+                       be64_to_cpu(data->nFirMask),
+                       be64_to_cpu(data->nFirWOF));
+       if (data->phbPlssr || data->phbCsr)
+               pr_info("PhbSts:     %016llx %016llx\n",
+                       be64_to_cpu(data->phbPlssr),
+                       be64_to_cpu(data->phbCsr));
+       if (data->lemFir)
+               pr_info("Lem:        %016llx %016llx %016llx\n",
+                       be64_to_cpu(data->lemFir),
+                       be64_to_cpu(data->lemErrorMask),
+                       be64_to_cpu(data->lemWOF));
+       if (data->phbErrorStatus)
+               pr_info("PhbErr:     %016llx %016llx %016llx %016llx\n",
+                       be64_to_cpu(data->phbErrorStatus),
+                       be64_to_cpu(data->phbFirstErrorStatus),
+                       be64_to_cpu(data->phbErrorLog0),
+                       be64_to_cpu(data->phbErrorLog1));
+       if (data->phbTxeErrorStatus)
+               pr_info("PhbTxeErr:  %016llx %016llx %016llx %016llx\n",
+                       be64_to_cpu(data->phbTxeErrorStatus),
+                       be64_to_cpu(data->phbTxeFirstErrorStatus),
+                       be64_to_cpu(data->phbTxeErrorLog0),
+                       be64_to_cpu(data->phbTxeErrorLog1));
+       if (data->phbRxeArbErrorStatus)
+               pr_info("RxeArbErr:  %016llx %016llx %016llx %016llx\n",
+                       be64_to_cpu(data->phbRxeArbErrorStatus),
+                       be64_to_cpu(data->phbRxeArbFirstErrorStatus),
+                       be64_to_cpu(data->phbRxeArbErrorLog0),
+                       be64_to_cpu(data->phbRxeArbErrorLog1));
+       if (data->phbRxeMrgErrorStatus)
+               pr_info("RxeMrgErr:  %016llx %016llx %016llx %016llx\n",
+                       be64_to_cpu(data->phbRxeMrgErrorStatus),
+                       be64_to_cpu(data->phbRxeMrgFirstErrorStatus),
+                       be64_to_cpu(data->phbRxeMrgErrorLog0),
+                       be64_to_cpu(data->phbRxeMrgErrorLog1));
+       if (data->phbRxeTceErrorStatus)
+               pr_info("RxeTceErr:  %016llx %016llx %016llx %016llx\n",
+                       be64_to_cpu(data->phbRxeTceErrorStatus),
+                       be64_to_cpu(data->phbRxeTceFirstErrorStatus),
+                       be64_to_cpu(data->phbRxeTceErrorLog0),
+                       be64_to_cpu(data->phbRxeTceErrorLog1));
+
+       if (data->phbPblErrorStatus)
+               pr_info("PblErr:     %016llx %016llx %016llx %016llx\n",
+                       be64_to_cpu(data->phbPblErrorStatus),
+                       be64_to_cpu(data->phbPblFirstErrorStatus),
+                       be64_to_cpu(data->phbPblErrorLog0),
+                       be64_to_cpu(data->phbPblErrorLog1));
+       if (data->phbPcieDlpErrorStatus)
+               pr_info("PcieDlp:    %016llx %016llx %016llx\n",
+                       be64_to_cpu(data->phbPcieDlpErrorLog1),
+                       be64_to_cpu(data->phbPcieDlpErrorLog2),
+                       be64_to_cpu(data->phbPcieDlpErrorStatus));
+       if (data->phbRegbErrorStatus)
+               pr_info("RegbErr:    %016llx %016llx %016llx %016llx\n",
+                       be64_to_cpu(data->phbRegbErrorStatus),
+                       be64_to_cpu(data->phbRegbFirstErrorStatus),
+                       be64_to_cpu(data->phbRegbErrorLog0),
+                       be64_to_cpu(data->phbRegbErrorLog1));
+
+
+       pnv_pci_dump_pest(data->pestA, data->pestB, OPAL_PHB4_NUM_PEST_REGS);
+}
+
 void pnv_pci_dump_phb_diag_data(struct pci_controller *hose,
                                unsigned char *log_buff)
 {
@@ -442,6 +544,9 @@ void pnv_pci_dump_phb_diag_data(struct pci_controller *hose,
        case OPAL_PHB_ERROR_DATA_TYPE_PHB3:
                pnv_pci_dump_phb3_diag_data(hose, common);
                break;
+       case OPAL_PHB_ERROR_DATA_TYPE_PHB4:
+               pnv_pci_dump_phb4_diag_data(hose, common);
+               break;
        default:
                pr_warn("%s: Unrecognized ioType %d\n",
                        __func__, be32_to_cpu(common->ioType));