aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorRussell Currey <ruscur@russell.cc>2016-03-21 12:00:04 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-03-31 16:41:17 +1100
commit52c432bd7eda4cad158393ca48f3dafabb3867d9 (patch)
tree9e1b168a0264b68ee7d9fdaf2f0e6b4cb0c106e0 /core
parent48f460a753f96289ff02e7f442353cff87f4962c (diff)
downloadskiboot-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.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/core/hmi.c b/core/hmi.c
index 127686f..71fdf48 100644
--- a/core/hmi.c
+++ b/core/hmi.c
@@ -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;
}