aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/chiptod.c41
-rw-r--r--include/processor.h1
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