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 /hw | |
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>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/chiptod.c | 41 |
1 files changed, 41 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; |