diff options
author | Russell Currey <ruscur@russell.cc> | 2016-03-21 12:00:04 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-03-31 16:41:17 +1100 |
commit | 52c432bd7eda4cad158393ca48f3dafabb3867d9 (patch) | |
tree | 9e1b168a0264b68ee7d9fdaf2f0e6b4cb0c106e0 /core | |
parent | 48f460a753f96289ff02e7f442353cff87f4962c (diff) | |
download | skiboot-52c432bd7eda4cad158393ca48f3dafabb3867d9.zip skiboot-52c432bd7eda4cad158393ca48f3dafabb3867d9.tar.gz skiboot-52c432bd7eda4cad158393ca48f3dafabb3867d9.tar.bz2 |
hmi: Rework HMI event handling of FIR read failure
If reading the FIR with XSCOM failed, the existing code would not raise
a HMI under the assumption that the CPU was asleep and nothing is wrong.
Now that it is possible to check whether or not the CPU was asleep,
raise an unrecoverable HMI if the read failed for other reasons, and
skip the CPU if it was asleep.
If the CPU is asleep when it's not meant to be and that is the cause of
the HMI, an unrecoverable "catchall" HMI will be raised since no other
components will claim responsibility for it.
Signed-off-by: Russell Currey <ruscur@russell.cc>
Reviewed-by: Alistair Popple <alistair@popple.id.au>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/hmi.c | 19 |
1 files changed, 17 insertions, 2 deletions
@@ -299,6 +299,7 @@ static bool decode_core_fir(struct cpu_thread *cpu, uint32_t core_id; int i; bool found = false; + int64_t ret; /* Sanity check */ if (!cpu || !hmi_evt) @@ -307,9 +308,23 @@ static bool decode_core_fir(struct cpu_thread *cpu, core_id = pir_to_core_id(cpu->pir); /* Get CORE FIR register value. */ - if (xscom_read(cpu->chip_id, XSCOM_ADDR_P8_EX(core_id, CORE_FIR), - &core_fir) != 0) { + ret = xscom_read(cpu->chip_id, XSCOM_ADDR_P8_EX(core_id, CORE_FIR), + &core_fir); + + if (ret == OPAL_HARDWARE) { prerror("HMI: XSCOM error reading CORE FIR\n"); + /* If the FIR can't be read, we should checkstop. */ + return true; + } else if (ret == OPAL_WRONG_STATE) { + /* + * CPU is asleep, so it probably didn't cause the checkstop. + * If no other HMI cause is found a "catchall" checkstop + * will be raised, so if this CPU should've been awake the + * error will be handled appropriately. + */ + prlog(PR_DEBUG, + "HMI: FIR read failed, chip %d core %d asleep\n", + cpu->chip_id, core_id); return false; } |