diff options
author | Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> | 2015-03-11 16:00:26 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-03-26 11:12:18 +1100 |
commit | c426521c4b4286e49c15eaefc0a7b953effc25ec (patch) | |
tree | 4295d9d745ab13204a48c86f01baba007c95cd76 /hw | |
parent | 2c6f80c7fd80edcd29b9ced904c104d5b3e83e99 (diff) | |
download | skiboot-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.c | 9 |
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; |