diff options
author | Philippe Bergheaud <felix@linux.vnet.ibm.com> | 2016-07-05 07:08:06 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2016-07-08 08:22:03 -0400 |
commit | 6e0c50f9e814220ada60497c522b60a8e1cc1e92 (patch) | |
tree | 8d5b73479501c57446aeadb0a64032d4c024bd64 | |
parent | f5c9df9a442f586b183947627210e167ded81d19 (diff) |
cxl: Refine slice error debug messages
The PSL Slice Error Register (PSL_SERR_An) reports implementation
dependent AFU errors, in the form of a bitmap. The PSL_SERR_An
register content is printed in the form of hex dump debug message.
This patch decodes the PSL_ERR_An register contents, and prints a
specific error message for each possible error bit. It also dumps
the secondary registers AFU_ERR_An and PSL_DSISR_An, that may
contain extra debug information.
This patch also removes the large WARN message that used to report
the cxl slice error interrupt, and replaces it by a short informative
message, that draws attention to AFU implementation errors.
Signed-off-by: Philippe Bergheaud <felix@linux.vnet.ibm.com>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | drivers/misc/cxl/cxl.h | 15 | ||||
-rw-r--r-- | drivers/misc/cxl/guest.c | 9 | ||||
-rw-r--r-- | drivers/misc/cxl/irq.c | 29 | ||||
-rw-r--r-- | drivers/misc/cxl/native.c | 12 |
4 files changed, 57 insertions, 8 deletions
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h index aafffa8554e2..36b3237fc2b1 100644 --- a/drivers/misc/cxl/cxl.h +++ b/drivers/misc/cxl/cxl.h | |||
@@ -189,6 +189,18 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0}; | |||
189 | #define CXL_PSL_ID_An_F (1ull << (63-31)) | 189 | #define CXL_PSL_ID_An_F (1ull << (63-31)) |
190 | #define CXL_PSL_ID_An_L (1ull << (63-30)) | 190 | #define CXL_PSL_ID_An_L (1ull << (63-30)) |
191 | 191 | ||
192 | /****** CXL_PSL_SERR_An ****************************************************/ | ||
193 | #define CXL_PSL_SERR_An_afuto (1ull << (63-0)) | ||
194 | #define CXL_PSL_SERR_An_afudis (1ull << (63-1)) | ||
195 | #define CXL_PSL_SERR_An_afuov (1ull << (63-2)) | ||
196 | #define CXL_PSL_SERR_An_badsrc (1ull << (63-3)) | ||
197 | #define CXL_PSL_SERR_An_badctx (1ull << (63-4)) | ||
198 | #define CXL_PSL_SERR_An_llcmdis (1ull << (63-5)) | ||
199 | #define CXL_PSL_SERR_An_llcmdto (1ull << (63-6)) | ||
200 | #define CXL_PSL_SERR_An_afupar (1ull << (63-7)) | ||
201 | #define CXL_PSL_SERR_An_afudup (1ull << (63-8)) | ||
202 | #define CXL_PSL_SERR_An_AE (1ull << (63-30)) | ||
203 | |||
192 | /****** CXL_PSL_SCNTL_An ****************************************************/ | 204 | /****** CXL_PSL_SCNTL_An ****************************************************/ |
193 | #define CXL_PSL_SCNTL_An_CR (0x1ull << (63-15)) | 205 | #define CXL_PSL_SCNTL_An_CR (0x1ull << (63-15)) |
194 | /* Programming Modes: */ | 206 | /* Programming Modes: */ |
@@ -916,4 +928,7 @@ extern const struct cxl_backend_ops *cxl_ops; | |||
916 | 928 | ||
917 | /* check if the given pci_dev is on the the cxl vphb bus */ | 929 | /* check if the given pci_dev is on the the cxl vphb bus */ |
918 | bool cxl_pci_is_vphb_device(struct pci_dev *dev); | 930 | bool cxl_pci_is_vphb_device(struct pci_dev *dev); |
931 | |||
932 | /* decode AFU error bits in the PSL register PSL_SERR_An */ | ||
933 | void cxl_afu_decode_psl_serr(struct cxl_afu *afu, u64 serr); | ||
919 | #endif | 934 | #endif |
diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c index 1edba5248620..ee7148e78ca7 100644 --- a/drivers/misc/cxl/guest.c +++ b/drivers/misc/cxl/guest.c | |||
@@ -196,15 +196,18 @@ static irqreturn_t guest_slice_irq_err(int irq, void *data) | |||
196 | { | 196 | { |
197 | struct cxl_afu *afu = data; | 197 | struct cxl_afu *afu = data; |
198 | int rc; | 198 | int rc; |
199 | u64 serr; | 199 | u64 serr, afu_error, dsisr; |
200 | 200 | ||
201 | WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq); | ||
202 | rc = cxl_h_get_fn_error_interrupt(afu->guest->handle, &serr); | 201 | rc = cxl_h_get_fn_error_interrupt(afu->guest->handle, &serr); |
203 | if (rc) { | 202 | if (rc) { |
204 | dev_crit(&afu->dev, "Couldn't read PSL_SERR_An: %d\n", rc); | 203 | dev_crit(&afu->dev, "Couldn't read PSL_SERR_An: %d\n", rc); |
205 | return IRQ_HANDLED; | 204 | return IRQ_HANDLED; |
206 | } | 205 | } |
207 | dev_crit(&afu->dev, "PSL_SERR_An: 0x%.16llx\n", serr); | 206 | afu_error = cxl_p2n_read(afu, CXL_AFU_ERR_An); |
207 | dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); | ||
208 | cxl_afu_decode_psl_serr(afu, serr); | ||
209 | dev_crit(&afu->dev, "AFU_ERR_An: 0x%.16llx\n", afu_error); | ||
210 | dev_crit(&afu->dev, "PSL_DSISR_An: 0x%.16llx\n", dsisr); | ||
208 | 211 | ||
209 | rc = cxl_h_ack_fn_error_interrupt(afu->guest->handle, serr); | 212 | rc = cxl_h_ack_fn_error_interrupt(afu->guest->handle, serr); |
210 | if (rc) | 213 | if (rc) |
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c index f3a7d4aa1cd5..dec60f58a767 100644 --- a/drivers/misc/cxl/irq.c +++ b/drivers/misc/cxl/irq.c | |||
@@ -371,3 +371,32 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie) | |||
371 | 371 | ||
372 | ctx->irq_count = 0; | 372 | ctx->irq_count = 0; |
373 | } | 373 | } |
374 | |||
375 | void cxl_afu_decode_psl_serr(struct cxl_afu *afu, u64 serr) | ||
376 | { | ||
377 | dev_crit(&afu->dev, | ||
378 | "PSL Slice error received. Check AFU for root cause.\n"); | ||
379 | dev_crit(&afu->dev, "PSL_SERR_An: 0x%016llx\n", serr); | ||
380 | if (serr & CXL_PSL_SERR_An_afuto) | ||
381 | dev_crit(&afu->dev, "AFU MMIO Timeout\n"); | ||
382 | if (serr & CXL_PSL_SERR_An_afudis) | ||
383 | dev_crit(&afu->dev, | ||
384 | "MMIO targeted Accelerator that was not enabled\n"); | ||
385 | if (serr & CXL_PSL_SERR_An_afuov) | ||
386 | dev_crit(&afu->dev, "AFU CTAG Overflow\n"); | ||
387 | if (serr & CXL_PSL_SERR_An_badsrc) | ||
388 | dev_crit(&afu->dev, "Bad Interrupt Source\n"); | ||
389 | if (serr & CXL_PSL_SERR_An_badctx) | ||
390 | dev_crit(&afu->dev, "Bad Context Handle\n"); | ||
391 | if (serr & CXL_PSL_SERR_An_llcmdis) | ||
392 | dev_crit(&afu->dev, "LLCMD to Disabled AFU\n"); | ||
393 | if (serr & CXL_PSL_SERR_An_llcmdto) | ||
394 | dev_crit(&afu->dev, "LLCMD Timeout to AFU\n"); | ||
395 | if (serr & CXL_PSL_SERR_An_afupar) | ||
396 | dev_crit(&afu->dev, "AFU MMIO Parity Error\n"); | ||
397 | if (serr & CXL_PSL_SERR_An_afudup) | ||
398 | dev_crit(&afu->dev, "AFU MMIO Duplicate CTAG Error\n"); | ||
399 | if (serr & CXL_PSL_SERR_An_AE) | ||
400 | dev_crit(&afu->dev, | ||
401 | "AFU asserted JDONE with JERROR in AFU Directed Mode\n"); | ||
402 | } | ||
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index 04c27e41b654..3bcdaee11ba1 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c | |||
@@ -862,7 +862,7 @@ void cxl_native_psl_irq_dump_regs(struct cxl_context *ctx) | |||
862 | dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2); | 862 | dev_crit(&ctx->afu->dev, "PSL_FIR2: 0x%016llx\n", fir2); |
863 | if (ctx->afu->adapter->native->sl_ops->register_serr_irq) { | 863 | if (ctx->afu->adapter->native->sl_ops->register_serr_irq) { |
864 | serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An); | 864 | serr = cxl_p1n_read(ctx->afu, CXL_PSL_SERR_An); |
865 | dev_crit(&ctx->afu->dev, "PSL_SERR_An: 0x%016llx\n", serr); | 865 | cxl_afu_decode_psl_serr(ctx->afu, serr); |
866 | } | 866 | } |
867 | dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice); | 867 | dev_crit(&ctx->afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice); |
868 | dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug); | 868 | dev_crit(&ctx->afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug); |
@@ -956,21 +956,23 @@ void native_irq_wait(struct cxl_context *ctx) | |||
956 | static irqreturn_t native_slice_irq_err(int irq, void *data) | 956 | static irqreturn_t native_slice_irq_err(int irq, void *data) |
957 | { | 957 | { |
958 | struct cxl_afu *afu = data; | 958 | struct cxl_afu *afu = data; |
959 | u64 fir_slice, errstat, serr, afu_debug; | 959 | u64 fir_slice, errstat, serr, afu_debug, afu_error, dsisr; |
960 | 960 | ||
961 | /* | 961 | /* |
962 | * slice err interrupt is only used with full PSL (no XSL) | 962 | * slice err interrupt is only used with full PSL (no XSL) |
963 | */ | 963 | */ |
964 | WARN(irq, "CXL SLICE ERROR interrupt %i\n", irq); | ||
965 | |||
966 | serr = cxl_p1n_read(afu, CXL_PSL_SERR_An); | 964 | serr = cxl_p1n_read(afu, CXL_PSL_SERR_An); |
967 | fir_slice = cxl_p1n_read(afu, CXL_PSL_FIR_SLICE_An); | 965 | fir_slice = cxl_p1n_read(afu, CXL_PSL_FIR_SLICE_An); |
968 | errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An); | 966 | errstat = cxl_p2n_read(afu, CXL_PSL_ErrStat_An); |
969 | afu_debug = cxl_p1n_read(afu, CXL_AFU_DEBUG_An); | 967 | afu_debug = cxl_p1n_read(afu, CXL_AFU_DEBUG_An); |
970 | dev_crit(&afu->dev, "PSL_SERR_An: 0x%016llx\n", serr); | 968 | afu_error = cxl_p2n_read(afu, CXL_AFU_ERR_An); |
969 | dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); | ||
970 | cxl_afu_decode_psl_serr(afu, serr); | ||
971 | dev_crit(&afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice); | 971 | dev_crit(&afu->dev, "PSL_FIR_SLICE_An: 0x%016llx\n", fir_slice); |
972 | dev_crit(&afu->dev, "CXL_PSL_ErrStat_An: 0x%016llx\n", errstat); | 972 | dev_crit(&afu->dev, "CXL_PSL_ErrStat_An: 0x%016llx\n", errstat); |
973 | dev_crit(&afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug); | 973 | dev_crit(&afu->dev, "CXL_PSL_AFU_DEBUG_An: 0x%016llx\n", afu_debug); |
974 | dev_crit(&afu->dev, "AFU_ERR_An: 0x%.16llx\n", afu_error); | ||
975 | dev_crit(&afu->dev, "PSL_DSISR_An: 0x%.16llx\n", dsisr); | ||
974 | 976 | ||
975 | cxl_p1n_write(afu, CXL_PSL_SERR_An, serr); | 977 | cxl_p1n_write(afu, CXL_PSL_SERR_An, serr); |
976 | 978 | ||