aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2015-03-11 16:00:26 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-03-26 11:12:18 +1100
commitc426521c4b4286e49c15eaefc0a7b953effc25ec (patch)
tree4295d9d745ab13204a48c86f01baba007c95cd76 /hw
parent2c6f80c7fd80edcd29b9ced904c104d5b3e83e99 (diff)
downloadskiboot-c426521c4b4286e49c15eaefc0a7b953effc25ec.zip
skiboot-c426521c4b4286e49c15eaefc0a7b953effc25ec.tar.gz
skiboot-c426521c4b4286e49c15eaefc0a7b953effc25ec.tar.bz2
opal: Handle TFMR firmware control error.
Handle TFMR firmware control error reported through HMER[bit 5] and TFMR bit 46 and 27. There are three reason for this error: 1. TFMR command was received but the state machine was in the wrong state for that command. e.g. TFMR move_chip_tod_to_tb command was received while in state 0 (RESET state). 2. Two tfmr commands were set which should be mutually exclusive. e.g. move_chip_tod_to_tb and load_tod_mod 3. Cycle counter used by the PURR overflows due to missing TB59 step. When we get this error TB is in not-valid state (corrupted - TFMR bit 27) and has stopped running. To recover, clear tb errors by writing 1 to TFMR bit 46, 27 and 24. This will reset the time machine state. And then fall through existing code which takes TB through correct states and reloads it with valid TOD value. To inject TFMR firmware control error set TFMR bit 16 and 18 at the same time. 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.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/hw/chiptod.c b/hw/chiptod.c
index c7de0a4..22c265c 100644
--- a/hw/chiptod.c
+++ b/hw/chiptod.c
@@ -656,6 +656,13 @@ static bool tfmr_recover_tb_errors(uint64_t tfmr)
/* write 1 to bit 45 to clear the error */
tfmr_reset_error |= SPR_TFMR_TB_RESIDUE_ERR;
}
+
+ if (tfmr & SPR_TFMR_FW_CONTROL_ERR)
+ tfmr_reset_error |= SPR_TFMR_FW_CONTROL_ERR;
+
+ if (tfmr & SPR_TFMR_TBST_CORRUPT)
+ tfmr_reset_error |= SPR_TFMR_TBST_CORRUPT;
+
mtspr(SPR_TFMR, tfmr_reset_error);
/* We have to write "Clear TB Errors" again */
@@ -709,6 +716,8 @@ int chiptod_recover_tb_errors(void)
*/
if ((tfmr & SPR_TFMR_TB_MISSING_STEP) ||
(tfmr & SPR_TFMR_TB_RESIDUE_ERR) ||
+ (tfmr & SPR_TFMR_FW_CONTROL_ERR) ||
+ (tfmr & SPR_TFMR_TBST_CORRUPT) ||
(tfmr & SPR_TFMR_TB_MISSING_SYNC)) {
if (!tfmr_recover_tb_errors(tfmr)) {
rc = 0;