diff options
author | Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> | 2015-03-11 16:03:01 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-03-26 11:12:18 +1100 |
commit | 6c98c74a97dab762c996d884a53a8eaf4dc8e427 (patch) | |
tree | c24d4287e8beed8a1b6bf5e8c473a3272c1d33cc /hw | |
parent | a2f6ec1ec030f9f038615f889a75376c4db99d91 (diff) | |
download | skiboot-6c98c74a97dab762c996d884a53a8eaf4dc8e427.zip skiboot-6c98c74a97dab762c996d884a53a8eaf4dc8e427.tar.gz skiboot-6c98c74a97dab762c996d884a53a8eaf4dc8e427.tar.bz2 |
opal: Recover from TFMR SPURR/PURR parity error.
Recovery process for SPURR/PURR parity error:
- Set SPURR/PURR Register with valid value or zero
- Reset TFMR SPURR/PURR parity error bit.
To inject TFMR PURR parity error issue:
$ putscom pu.ex 10013281 0004080000000000 -all
To inject TFMR SPURR parity error issue:
$ putscom pu.ex 10013281 0005080000000000 -all
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/chiptod.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/hw/chiptod.c b/hw/chiptod.c index 1c77cb7..d51ce2b 100644 --- a/hw/chiptod.c +++ b/hw/chiptod.c @@ -705,6 +705,28 @@ static bool tfmr_recover_non_tb_errors(uint64_t tfmr) tfmr_reset_errors |= SPR_TFMR_DEC_PARITY_ERR; } + /* + * Reset PURR/SPURR to recover. We also need help from KVM + * layer to handle this change in PURR/SPURR. That needs + * to be handled in kernel KVM layer. For now, to recover just + * reset it. + */ + if (tfmr & SPR_TFMR_PURR_PARITY_ERR) { + /* set PURR register with sane value or reset it. */ + mtspr(SPR_PURR, 0); + + /* set bit 57 to clear TFMR PURR parity error. */ + tfmr_reset_errors |= SPR_TFMR_PURR_PARITY_ERR; + } + + if (tfmr & SPR_TFMR_SPURR_PARITY_ERR) { + /* set PURR register with sane value or reset it. */ + mtspr(SPR_SPURR, 0); + + /* set bit 58 to clear TFMR PURR parity error. */ + tfmr_reset_errors |= SPR_TFMR_SPURR_PARITY_ERR; + } + /* Write TFMR twice to clear the error */ mtspr(SPR_TFMR, base_tfmr | tfmr_reset_errors); mtspr(SPR_TFMR, base_tfmr | tfmr_reset_errors); @@ -857,6 +879,8 @@ int chiptod_recover_tb_errors(void) * Now that TB is running, check for TFMR non-TB errors. */ if ((tfmr & SPR_TFMR_HDEC_PARITY_ERROR) || + (tfmr & SPR_TFMR_PURR_PARITY_ERR) || + (tfmr & SPR_TFMR_SPURR_PARITY_ERR) || (tfmr & SPR_TFMR_DEC_PARITY_ERR)) { if (!tfmr_recover_non_tb_errors(tfmr)) { rc = 0; |