diff options
author | Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> | 2015-03-11 16:01:46 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-03-26 11:12:18 +1100 |
commit | fcca42f63e16aa186e3ef1bb088fb5abfef3590e (patch) | |
tree | 4252e1ba89d06648979c1bc25d52dd7d3bb74fdb | |
parent | 9650f6b0a40dc21a6796c1ec66a7e5ddbb927947 (diff) | |
download | skiboot-fcca42f63e16aa186e3ef1bb088fb5abfef3590e.zip skiboot-fcca42f63e16aa186e3ef1bb088fb5abfef3590e.tar.gz skiboot-fcca42f63e16aa186e3ef1bb088fb5abfef3590e.tar.bz2 |
opal: Recover from TFMR HDEC parity error.
Recovery process for HDEC parity error:
- Reset HDEC Register.
- Reset TFMR HDEC parity error bit.
To inject HDEC parity error issue:
$ putscom pu.ex 10013281 0002080000000000 -all
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | hw/chiptod.c | 41 | ||||
-rw-r--r-- | include/processor.h | 1 |
2 files changed, 42 insertions, 0 deletions
diff --git a/hw/chiptod.c b/hw/chiptod.c index b00c3cf..6f6800f 100644 --- a/hw/chiptod.c +++ b/hw/chiptod.c @@ -685,6 +685,35 @@ static bool tfmr_recover_tb_errors(uint64_t tfmr) return true; } +static bool tfmr_recover_non_tb_errors(uint64_t tfmr) +{ + uint64_t tfmr_reset_errors = 0; + + if (tfmr & SPR_TFMR_HDEC_PARITY_ERROR) { + /* Reset HDEC register */ + mtspr(SPR_HDEC, 0); + + /* Set bit 26 to clear TFMR HDEC parity error. */ + tfmr_reset_errors |= SPR_TFMR_HDEC_PARITY_ERROR; + } + + /* Write TFMR twice to clear the error */ + mtspr(SPR_TFMR, base_tfmr | tfmr_reset_errors); + mtspr(SPR_TFMR, base_tfmr | tfmr_reset_errors); + + /* Get fresh copy of TFMR */ + tfmr = mfspr(SPR_TFMR); + + /* Check if TFMR non-TB errors still present. */ + if (tfmr & tfmr_reset_errors) { + prerror( + "CHIPTOD: TFMR non-TB error recovery failed! TFMR=0x%016lx\n", + mfspr(SPR_TFMR)); + return false; + } + return true; +} + /* * TFMR parity error recovery as per pc_workbook: * MT(TFMR) bits 11 and 60 are b’1’ @@ -815,6 +844,18 @@ int chiptod_recover_tb_errors(void) /* We have successfully able to get TB running. */ rc = 1; } + + /* + * Now that TB is running, check for TFMR non-TB errors. + */ + if (tfmr & SPR_TFMR_HDEC_PARITY_ERROR) { + if (!tfmr_recover_non_tb_errors(tfmr)) { + rc = 0; + goto error_out; + } + rc = 1; + } + error_out: unlock(&chiptod_lock); return rc; diff --git a/include/processor.h b/include/processor.h index 31ed72d..9140564 100644 --- a/include/processor.h +++ b/include/processor.h @@ -63,6 +63,7 @@ #define SPR_PVR 0x11f /* RO: Processor version register */ #define SPR_HSPRG0 0x130 /* RW: Hypervisor scratch 0 */ #define SPR_HSPRG1 0x131 /* RW: Hypervisor scratch 1 */ +#define SPR_HDEC 0x136 /* RW: Hypervisor Decrementer */ #define SPR_HSRR0 0x13a /* RW: HV Exception save/restore reg 0 */ #define SPR_HSRR1 0x13b /* RW: HV Exception save/restore reg 1 */ #define SPR_TFMR 0x13d |