aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2015-03-11 16:01:46 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-03-26 11:12:18 +1100
commitfcca42f63e16aa186e3ef1bb088fb5abfef3590e (patch)
tree4252e1ba89d06648979c1bc25d52dd7d3bb74fdb /hw
parent9650f6b0a40dc21a6796c1ec66a7e5ddbb927947 (diff)
downloadskiboot-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.c41
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;