1 /* Copyright 2013-2018 IBM Corp.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 * implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define pr_fmt(fmt) "HMI: " fmt
18
19 #include <skiboot.h>
20 #include <opal.h>
21 #include <opal-msg.h>
22 #include <processor.h>
23 #include <chiptod.h>
24 #include <xscom.h>
25 #include <xscom-p8-regs.h>
26 #include <xscom-p9-regs.h>
27 #include <pci.h>
28 #include <cpu.h>
29 #include <chip.h>
30 #include <npu-regs.h>
31 #include <npu2-regs.h>
32 #include <npu2.h>
33 #include <npu.h>
34 #include <capp.h>
35 #include <nvram.h>
36 #include <cpu.h>
37
38 /*
39 * HMER register layout:
40 * +===+==========+============================+========+===================+
41 * |Bit|Name |Description |PowerKVM|Action |
42 * | | | |HMI | |
43 * | | | |enabled | |
44 * | | | |for this| |
45 * | | | |bit ? | |
46 * +===+==========+============================+========+===================+
47 * |0 |malfunctio|A processor core in the |Yes |Raise attn from |
48 * | |n_allert |system has checkstopped | |sapphire resulting |
49 * | | |(failed recovery) and has | |xstop |
50 * | | |requested a CP Sparing | | |
51 * | | |to occur. This is | | |
52 * | | |broadcasted to every | | |
53 * | | |processor in the system | | |
54 * |---+----------+----------------------------+--------+-------------------|
55 * |1 |Reserved |reserved |n/a | |
56 * |---+----------+----------------------------+--------+-------------------|
57 * |2 |proc_recv_|Processor recovery occurred |Yes |Log message and |
58 * | |done |error-bit in fir not masked | |continue working. |
59 * | | |(see bit 11) | | |
60 * |---+----------+----------------------------+--------+-------------------|
61 * |3 |proc_recv_|Processor went through |Yes |Log message and |
62 * | |error_mask|recovery for an error which | |continue working. |
63 * | |ed |is actually masked for | | |
64 * | | |reporting | | |
65 * |---+----------+----------------------------+--------+-------------------|
66 * |4 | |Timer facility experienced |Yes |Raise attn from |
67 * | |tfac_error|an error. | |sapphire resulting |
68 * | | |TB, DEC, HDEC, PURR or SPURR| |xstop |
69 * | | |may be corrupted (details in| | |
70 * | | |TFMR) | | |
71 * |---+----------+----------------------------+--------+-------------------|
72 * |5 | |TFMR SPR itself is |Yes |Raise attn from |
73 * | |tfmr_parit|corrupted. | |sapphire resulting |
74 * | |y_error |Entire timing facility may | |xstop |
75 * | | |be compromised. | | |
76 * |---+----------+----------------------------+--------+-------------------|
77 * |6 |ha_overflo| UPS (Uniterrupted Power |No |N/A |
78 * | |w_warning |System) Overflow indication | | |
79 * | | |indicating that the UPS | | |
80 * | | |DirtyAddrTable has | | |
81 * | | |reached a limit where it | | |
82 * | | |requires PHYP unload support| | |
83 * |---+----------+----------------------------+--------+-------------------|
84 * |7 |reserved |reserved |n/a |n/a |
85 * |---+----------+----------------------------+--------+-------------------|
86 * |8 |xscom_fail|An XSCOM operation caused by|No |We handle it by |
87 * | | |a cache inhibited load/store| |manually reading |
88 * | | |from this thread failed. A | |HMER register. |
89 * | | |trap register is | | |
90 * | | |available. | | |
91 * | | | | | |
92 * |---+----------+----------------------------+--------+-------------------|
93 * |9 |xscom_done|An XSCOM operation caused by|No |We handle it by |
94 * | | |a cache inhibited load/store| |manually reading |
95 * | | |from this thread completed. | |HMER register. |
96 * | | |If hypervisor | | |
97 * | | |intends to use this bit, it | | |
98 * | | |is responsible for clearing | | |
99 * | | |it before performing the | | |
100 * | | |xscom operation. | | |
101 * | | |NOTE: this bit should always| | |
102 * | | |be masked in HMEER | | |
103 * |---+----------+----------------------------+--------+-------------------|
104 * |10 |reserved |reserved |n/a |n/a |
105 * |---+----------+----------------------------+--------+-------------------|
106 * |11 |proc_recv_|Processor recovery occurred |y |Log message and |
107 * | |again |again before bit2 or bit3 | |continue working. |
108 * | | |was cleared | | |
109 * |---+----------+----------------------------+--------+-------------------|
110 * |12-|reserved |was temperature sensor |n/a |n/a |
111 * |15 | |passed the critical point on| | |
112 * | | |the way up | | |
113 * |---+----------+----------------------------+--------+-------------------|
114 * |16 | |SCOM has set a reserved FIR |No |n/a |
115 * | |scom_fir_h|bit to cause recovery | | |
116 * | |m | | | |
117 * |---+----------+----------------------------+--------+-------------------|
118 * |17 |trig_fir_h|Debug trigger has set a |No |n/a |
119 * | |mi |reserved FIR bit to cause | | |
120 * | | |recovery | | |
121 * |---+----------+----------------------------+--------+-------------------|
122 * |18 |reserved |reserved |n/a |n/a |
123 * |---+----------+----------------------------+--------+-------------------|
124 * |19 |reserved |reserved |n/a |n/a |
125 * |---+----------+----------------------------+--------+-------------------|
126 * |20 |hyp_resour|A hypervisor resource error |y |Raise attn from |
127 * | |ce_err |occurred: data parity error | |sapphire resulting |
128 * | | |on, SPRC0:3; SPR_Modereg or | |xstop. |
129 * | | |HMEER. | | |
130 * | | |Note: this bit will cause an| | |
131 * | | |check_stop when (HV=1, PR=0 | | |
132 * | | |and EE=0) | | |
133 * |---+----------+----------------------------+--------+-------------------|
134 * |21-| |if bit 8 is active, the |No |We handle it by |
135 * |23 |xscom_stat|reason will be detailed in | |Manually reading |
136 * | |us |these bits. see chapter 11.1| |HMER register. |
137 * | | |This bits are information | | |
138 * | | |only and always masked | | |
139 * | | |(mask = '0') | | |
140 * | | |If hypervisor intends to use| | |
141 * | | |this bit, it is responsible | | |
142 * | | |for clearing it before | | |
143 * | | |performing the xscom | | |
144 * | | |operation. | | |
145 * |---+----------+----------------------------+--------+-------------------|
146 * |24-|Not |Not implemented |n/a |n/a |
147 * |63 |implemente| | | |
148 * | |d | | | |
149 * +-- +----------+----------------------------+--------+-------------------+
150 *
151 * Above HMER bits can be enabled/disabled by modifying
152 * SPR_HMEER_HMI_ENABLE_MASK #define in include/processor.h
153 * If you modify support for any of the bits listed above, please make sure
154 * you change the above table to refelct that.
155 *
156 * NOTE: Per Dave Larson, never enable 8,9,21-23
157 */
158
159 /* Used for tracking cpu threads inside hmi handling. */
160 #define HMI_STATE_CLEANUP_DONE 0x100
161 #define CORE_THREAD_MASK 0x0ff
162 #define SUBCORE_THREAD_MASK(s_id, t_count) \
163 ((((1UL) << (t_count)) - 1) << ((s_id) * (t_count)))
164 #define SINGLE_THREAD_MASK(t_id) ((1UL) << (t_id))
165
166 /*
167 * Number of iterations for the various timeouts. We can't use the timebase
168 * as it might be broken. We measured experimentally that 40 millions loops
169 * of cpu_relax() gives us more than 1s. The margin is comfortable enough.
170 */
171 #define TIMEOUT_LOOPS 40000000
172
173 /* TFMR other errors. (other than bit 26 and 45) */
174 #define SPR_TFMR_OTHER_ERRORS \
175 (SPR_TFMR_TBST_CORRUPT | SPR_TFMR_TB_MISSING_SYNC | \
176 SPR_TFMR_TB_MISSING_STEP | SPR_TFMR_FW_CONTROL_ERR | \
177 SPR_TFMR_PURR_PARITY_ERR | SPR_TFMR_SPURR_PARITY_ERR | \
178 SPR_TFMR_DEC_PARITY_ERR | SPR_TFMR_TFMR_CORRUPT | \
179 SPR_TFMR_CHIP_TOD_INTERRUPT)
180
181 /* TFMR "all core" errors (sent to all threads) */
182 #define SPR_TFMR_CORE_ERRORS \
183 (SPR_TFMR_TBST_CORRUPT | SPR_TFMR_TB_MISSING_SYNC | \
184 SPR_TFMR_TB_MISSING_STEP | SPR_TFMR_FW_CONTROL_ERR | \
185 SPR_TFMR_TFMR_CORRUPT | SPR_TFMR_TB_RESIDUE_ERR | \
186 SPR_TFMR_HDEC_PARITY_ERROR)
187
188 /* TFMR "thread" errors */
189 #define SPR_TFMR_THREAD_ERRORS \
190 (SPR_TFMR_PURR_PARITY_ERR | SPR_TFMR_SPURR_PARITY_ERR | \
191 SPR_TFMR_DEC_PARITY_ERR)
192
193 static const struct core_xstop_bit_info {
194 uint8_t bit; /* CORE FIR bit number */
195 enum OpalHMI_CoreXstopReason reason;
196 } xstop_bits[] = {
197 { 3, CORE_CHECKSTOP_IFU_REGFILE },
198 { 5, CORE_CHECKSTOP_IFU_LOGIC },
199 { 8, CORE_CHECKSTOP_PC_DURING_RECOV },
200 { 10, CORE_CHECKSTOP_ISU_REGFILE },
201 { 12, CORE_CHECKSTOP_ISU_LOGIC },
202 { 21, CORE_CHECKSTOP_FXU_LOGIC },
203 { 25, CORE_CHECKSTOP_VSU_LOGIC },
204 { 26, CORE_CHECKSTOP_PC_RECOV_IN_MAINT_MODE },
205 { 32, CORE_CHECKSTOP_LSU_REGFILE },
206 { 36, CORE_CHECKSTOP_PC_FWD_PROGRESS },
207 { 38, CORE_CHECKSTOP_LSU_LOGIC },
208 { 45, CORE_CHECKSTOP_PC_LOGIC },
209 { 48, CORE_CHECKSTOP_PC_HYP_RESOURCE },
210 { 52, CORE_CHECKSTOP_PC_HANG_RECOV_FAILED },
211 { 54, CORE_CHECKSTOP_PC_AMBI_HANG_DETECTED },
212 { 63, CORE_CHECKSTOP_PC_SPRD_HYP_ERR_INJ },
213 };
214
215 static const struct core_recoverable_bit_info {
216 uint8_t bit; /* CORE FIR bit number */
217 const char *reason;
218 } recoverable_bits[] = {
219 { 0, "IFU - SRAM (ICACHE parity, etc)" },
220 { 2, "IFU - RegFile" },
221 { 4, "IFU - Logic" },
222 { 9, "ISU - RegFile" },
223 { 11, "ISU - Logic" },
224 { 13, "ISU - Recoverable due to not in MT window" },
225 { 24, "VSU - Logic" },
226 { 27, "VSU - DFU logic" },
227 { 29, "LSU - SRAM (DCACHE parity, etc)" },
228 { 31, "LSU - RegFile" },
229 /* The following 3 bits may be set by SRAM errors. */
230 { 33, "LSU - TLB multi hit" },
231 { 34, "LSU - SLB multi hit" },
232 { 35, "LSU - ERAT multi hit" },
233 { 37, "LSU - Logic" },
234 { 39, "LSU - Recoverable due to not in MT window" },
235 { 43, "PC - Thread hang recovery" },
236 };
237
238 static const struct nx_xstop_bit_info {
239 uint8_t bit; /* NX FIR bit number */
240 enum OpalHMI_NestAccelXstopReason reason;
241 } nx_dma_xstop_bits[] = {
242 { 1, NX_CHECKSTOP_SHM_INVAL_STATE_ERR },
243 { 15, NX_CHECKSTOP_DMA_INVAL_STATE_ERR_1 },
244 { 16, NX_CHECKSTOP_DMA_INVAL_STATE_ERR_2 },
245 { 20, NX_CHECKSTOP_DMA_CH0_INVAL_STATE_ERR },
246 { 21, NX_CHECKSTOP_DMA_CH1_INVAL_STATE_ERR },
247 { 22, NX_CHECKSTOP_DMA_CH2_INVAL_STATE_ERR },
248 { 23, NX_CHECKSTOP_DMA_CH3_INVAL_STATE_ERR },
249 { 24, NX_CHECKSTOP_DMA_CH4_INVAL_STATE_ERR },
250 { 25, NX_CHECKSTOP_DMA_CH5_INVAL_STATE_ERR },
251 { 26, NX_CHECKSTOP_DMA_CH6_INVAL_STATE_ERR },
252 { 27, NX_CHECKSTOP_DMA_CH7_INVAL_STATE_ERR },
253 { 31, NX_CHECKSTOP_DMA_CRB_UE },
254 { 32, NX_CHECKSTOP_DMA_CRB_SUE },
255 };
256
257 static const struct nx_xstop_bit_info nx_pbi_xstop_bits[] = {
258 { 12, NX_CHECKSTOP_PBI_ISN_UE },
259 };
260
261 static struct lock hmi_lock = LOCK_UNLOCKED;
262 static uint32_t malf_alert_scom;
263 static uint32_t nx_status_reg;
264 static uint32_t nx_dma_engine_fir;
265 static uint32_t nx_pbi_fir;
266
setup_scom_addresses(void)267 static int setup_scom_addresses(void)
268 {
269 switch (proc_gen) {
270 case proc_gen_p8:
271 malf_alert_scom = P8_MALFUNC_ALERT;
272 nx_status_reg = P8_NX_STATUS_REG;
273 nx_dma_engine_fir = P8_NX_DMA_ENGINE_FIR;
274 nx_pbi_fir = P8_NX_PBI_FIR;
275 return 1;
276 case proc_gen_p9:
277 malf_alert_scom = P9_MALFUNC_ALERT;
278 nx_status_reg = P9_NX_STATUS_REG;
279 nx_dma_engine_fir = P9_NX_DMA_ENGINE_FIR;
280 nx_pbi_fir = P9_NX_PBI_FIR;
281 return 1;
282 default:
283 prerror("%s: Unknown CPU type\n", __func__);
284 break;
285 }
286 return 0;
287 }
288
queue_hmi_event(struct OpalHMIEvent * hmi_evt,int recover,uint64_t * out_flags)289 static int queue_hmi_event(struct OpalHMIEvent *hmi_evt, int recover, uint64_t *out_flags)
290 {
291 size_t size;
292
293 /* Don't queue up event if recover == -1 */
294 if (recover == -1)
295 return 0;
296
297 /* set disposition */
298 if (recover == 1)
299 hmi_evt->disposition = OpalHMI_DISPOSITION_RECOVERED;
300 else if (recover == 0)
301 hmi_evt->disposition = OpalHMI_DISPOSITION_NOT_RECOVERED;
302
303 /*
304 * V2 of struct OpalHMIEvent is of (5 * 64 bits) size and well packed
305 * structure. Hence use uint64_t pointer to pass entire structure
306 * using 5 params in generic message format. Instead of hard coding
307 * num_params divide the struct size by 8 bytes to get exact
308 * num_params value.
309 */
310 size = ALIGN_UP(sizeof(*hmi_evt), sizeof(u64));
311
312 *out_flags |= OPAL_HMI_FLAGS_NEW_EVENT;
313
314 /* queue up for delivery to host. */
315 return _opal_queue_msg(OPAL_MSG_HMI_EVT, NULL, NULL,
316 size, hmi_evt);
317 }
318
read_core_fir(uint32_t chip_id,uint32_t core_id,uint64_t * core_fir)319 static int read_core_fir(uint32_t chip_id, uint32_t core_id, uint64_t *core_fir)
320 {
321 int rc;
322
323 switch (proc_gen) {
324 case proc_gen_p8:
325 rc = xscom_read(chip_id,
326 XSCOM_ADDR_P8_EX(core_id, P8_CORE_FIR), core_fir);
327 break;
328 case proc_gen_p9:
329 rc = xscom_read(chip_id,
330 XSCOM_ADDR_P9_EC(core_id, P9_CORE_FIR), core_fir);
331 break;
332 default:
333 rc = OPAL_HARDWARE;
334 }
335 return rc;
336 }
337
read_core_wof(uint32_t chip_id,uint32_t core_id,uint64_t * core_wof)338 static int read_core_wof(uint32_t chip_id, uint32_t core_id, uint64_t *core_wof)
339 {
340 int rc;
341
342 switch (proc_gen) {
343 case proc_gen_p9:
344 rc = xscom_read(chip_id,
345 XSCOM_ADDR_P9_EC(core_id, P9_CORE_WOF), core_wof);
346 break;
347 default:
348 rc = OPAL_HARDWARE;
349 }
350 return rc;
351 }
352
decode_core_fir(struct cpu_thread * cpu,struct OpalHMIEvent * hmi_evt)353 static bool decode_core_fir(struct cpu_thread *cpu,
354 struct OpalHMIEvent *hmi_evt)
355 {
356 uint64_t core_fir;
357 uint32_t core_id;
358 int i, swkup_rc;
359 bool found = false;
360 int64_t ret;
361 const char *loc;
362
363 /* Sanity check */
364 if (!cpu || !hmi_evt)
365 return false;
366
367 core_id = pir_to_core_id(cpu->pir);
368
369 /* Force the core to wakeup, otherwise reading core_fir is unrealiable
370 * if stop-state 5 is enabled.
371 */
372 swkup_rc = dctl_set_special_wakeup(cpu);
373
374 /* Get CORE FIR register value. */
375 ret = read_core_fir(cpu->chip_id, core_id, &core_fir);
376
377 if (!swkup_rc)
378 dctl_clear_special_wakeup(cpu);
379
380
381 if (ret == OPAL_WRONG_STATE) {
382 /*
383 * CPU is asleep, so it probably didn't cause the checkstop.
384 * If no other HMI cause is found a "catchall" checkstop
385 * will be raised, so if this CPU should've been awake the
386 * error will be handled appropriately.
387 */
388 prlog(PR_DEBUG,
389 "FIR read failed, chip %d core %d asleep\n",
390 cpu->chip_id, core_id);
391 return false;
392 } else if (ret != OPAL_SUCCESS) {
393 prerror("XSCOM error reading CORE FIR\n");
394 /* If the FIR can't be read, we should checkstop. */
395 return true;
396 }
397
398 if (!core_fir)
399 return false;
400
401 loc = chip_loc_code(cpu->chip_id);
402 prlog(PR_INFO, "[Loc: %s]: CHIP ID: %x, CORE ID: %x, FIR: %016llx\n",
403 loc ? loc : "Not Available",
404 cpu->chip_id, core_id, core_fir);
405
406 /* Check CORE FIR bits and populate HMI event with error info. */
407 for (i = 0; i < ARRAY_SIZE(xstop_bits); i++) {
408 if (core_fir & PPC_BIT(xstop_bits[i].bit)) {
409 found = true;
410 hmi_evt->u.xstop_error.xstop_reason
411 |= xstop_bits[i].reason;
412 }
413 }
414 return found;
415 }
416
find_core_checkstop_reason(struct OpalHMIEvent * hmi_evt,uint64_t * out_flags)417 static void find_core_checkstop_reason(struct OpalHMIEvent *hmi_evt,
418 uint64_t *out_flags)
419 {
420 struct cpu_thread *cpu;
421
422 /* Initialize HMI event */
423 hmi_evt->severity = OpalHMI_SEV_FATAL;
424 hmi_evt->type = OpalHMI_ERROR_MALFUNC_ALERT;
425 hmi_evt->u.xstop_error.xstop_type = CHECKSTOP_TYPE_CORE;
426
427 /*
428 * Check CORE FIRs and find the reason for core checkstop.
429 * Send a separate HMI event for each core that has checkstopped.
430 */
431 for_each_cpu(cpu) {
432 /* GARDed CPUs are marked unavailable. Skip them. */
433 if (cpu->state == cpu_state_unavailable)
434 continue;
435
436 /* Only check on primaries (ie. core), not threads */
437 if (cpu->is_secondary)
438 continue;
439
440 /* Initialize xstop_error fields. */
441 hmi_evt->u.xstop_error.xstop_reason = 0;
442 hmi_evt->u.xstop_error.u.pir = cpu->pir;
443
444 if (decode_core_fir(cpu, hmi_evt))
445 queue_hmi_event(hmi_evt, 0, out_flags);
446 }
447 }
448
find_capp_checkstop_reason(int flat_chip_id,struct OpalHMIEvent * hmi_evt,uint64_t * out_flags)449 static void find_capp_checkstop_reason(int flat_chip_id,
450 struct OpalHMIEvent *hmi_evt,
451 uint64_t *out_flags)
452 {
453 struct capp_info info;
454 struct phb *phb;
455 uint64_t capp_fir;
456 uint64_t capp_fir_mask;
457 uint64_t capp_fir_action0;
458 uint64_t capp_fir_action1;
459 uint64_t reg;
460 int64_t rc;
461
462 /* Find the CAPP on the chip associated with the HMI. */
463 for_each_phb(phb) {
464 /* get the CAPP info */
465 rc = capp_get_info(flat_chip_id, phb, &info);
466 if (rc == OPAL_PARAMETER)
467 continue;
468
469 if (xscom_read(flat_chip_id, info.capp_fir_reg, &capp_fir) ||
470 xscom_read(flat_chip_id, info.capp_fir_mask_reg,
471 &capp_fir_mask) ||
472 xscom_read(flat_chip_id, info.capp_fir_action0_reg,
473 &capp_fir_action0) ||
474 xscom_read(flat_chip_id, info.capp_fir_action1_reg,
475 &capp_fir_action1)) {
476 prerror("CAPP: Couldn't read CAPP#%d (PHB:#%x) FIR registers by XSCOM!\n",
477 info.capp_index, info.phb_index);
478 continue;
479 }
480
481 if (!(capp_fir & ~capp_fir_mask))
482 continue;
483
484 prlog(PR_DEBUG, "CAPP#%d (PHB:#%x): FIR 0x%016llx mask 0x%016llx\n",
485 info.capp_index, info.phb_index, capp_fir,
486 capp_fir_mask);
487 prlog(PR_DEBUG, "CAPP#%d (PHB:#%x): ACTION0 0x%016llx, ACTION1 0x%016llx\n",
488 info.capp_index, info.phb_index, capp_fir_action0,
489 capp_fir_action1);
490
491 /*
492 * If this bit is set (=1) a Recoverable Error has been
493 * detected
494 */
495 xscom_read(flat_chip_id, info.capp_err_status_ctrl_reg, ®);
496 if ((reg & PPC_BIT(0)) != 0) {
497 phb_lock(phb);
498 phb->ops->set_capp_recovery(phb);
499 phb_unlock(phb);
500
501 hmi_evt->severity = OpalHMI_SEV_NO_ERROR;
502 hmi_evt->type = OpalHMI_ERROR_CAPP_RECOVERY;
503 queue_hmi_event(hmi_evt, 1, out_flags);
504
505 return;
506 }
507 }
508 }
509
find_nx_checkstop_reason(int flat_chip_id,struct OpalHMIEvent * hmi_evt,uint64_t * out_flags)510 static void find_nx_checkstop_reason(int flat_chip_id,
511 struct OpalHMIEvent *hmi_evt,
512 uint64_t *out_flags)
513 {
514 uint64_t nx_status;
515 uint64_t nx_dma_fir;
516 uint64_t nx_pbi_fir_val;
517 int i;
518
519 /* Get NX status register value. */
520 if (xscom_read(flat_chip_id, nx_status_reg, &nx_status) != 0) {
521 prerror("XSCOM error reading NX_STATUS_REG\n");
522 return;
523 }
524
525 /* Check if NX has driven an HMI interrupt. */
526 if (!(nx_status & NX_HMI_ACTIVE))
527 return;
528
529 /* Initialize HMI event */
530 hmi_evt->severity = OpalHMI_SEV_FATAL;
531 hmi_evt->type = OpalHMI_ERROR_MALFUNC_ALERT;
532 hmi_evt->u.xstop_error.xstop_type = CHECKSTOP_TYPE_NX;
533 hmi_evt->u.xstop_error.u.chip_id = flat_chip_id;
534
535 /* Get DMA & Engine FIR data register value. */
536 if (xscom_read(flat_chip_id, nx_dma_engine_fir, &nx_dma_fir) != 0) {
537 prerror("XSCOM error reading NX_DMA_ENGINE_FIR\n");
538 return;
539 }
540
541 /* Get PowerBus Interface FIR data register value. */
542 if (xscom_read(flat_chip_id, nx_pbi_fir, &nx_pbi_fir_val) != 0) {
543 prerror("XSCOM error reading NX_PBI_FIR\n");
544 return;
545 }
546
547 /* Find NX checkstop reason and populate HMI event with error info. */
548 for (i = 0; i < ARRAY_SIZE(nx_dma_xstop_bits); i++)
549 if (nx_dma_fir & PPC_BIT(nx_dma_xstop_bits[i].bit))
550 hmi_evt->u.xstop_error.xstop_reason
551 |= nx_dma_xstop_bits[i].reason;
552
553 for (i = 0; i < ARRAY_SIZE(nx_pbi_xstop_bits); i++)
554 if (nx_pbi_fir_val & PPC_BIT(nx_pbi_xstop_bits[i].bit))
555 hmi_evt->u.xstop_error.xstop_reason
556 |= nx_pbi_xstop_bits[i].reason;
557
558 /*
559 * Set NXDMAENGFIR[38] to signal PRD that service action is required.
560 * Without this inject, PRD will not be able to do NX unit checkstop
561 * error analysis. NXDMAENGFIR[38] is a spare bit and used to report
562 * a software initiated attention.
563 *
564 * The behavior of this bit and all FIR bits are documented in
565 * RAS spreadsheet.
566 */
567 xscom_write(flat_chip_id, nx_dma_engine_fir, PPC_BIT(38));
568
569 /* Send an HMI event. */
570 queue_hmi_event(hmi_evt, 0, out_flags);
571 }
572
phb_is_npu2(struct dt_node * dn)573 static bool phb_is_npu2(struct dt_node *dn)
574 {
575 return (dt_node_is_compatible(dn, "ibm,power9-npu-pciex") ||
576 dt_node_is_compatible(dn, "ibm,power9-npu-opencapi-pciex"));
577 }
578
add_npu2_xstop_reason(uint32_t * xstop_reason,uint8_t reason)579 static void add_npu2_xstop_reason(uint32_t *xstop_reason, uint8_t reason)
580 {
581 int i, reason_count;
582 uint8_t *ptr;
583
584 reason_count = sizeof(*xstop_reason) / sizeof(reason);
585 ptr = (uint8_t *) xstop_reason;
586 for (i = 0; i < reason_count; i++) {
587 if (*ptr == 0) {
588 *ptr = reason;
589 break;
590 }
591 ptr++;
592 }
593 }
594
encode_npu2_xstop_reason(uint32_t * xstop_reason,uint64_t fir,int fir_number)595 static void encode_npu2_xstop_reason(uint32_t *xstop_reason,
596 uint64_t fir, int fir_number)
597 {
598 int bit;
599 uint8_t reason;
600
601 /*
602 * There are three 64-bit FIRs but the xstop reason field of
603 * the hmi event is only 32-bit. Encode which FIR bit is set as:
604 * - 2 bits for the FIR number
605 * - 6 bits for the bit number (0 -> 63)
606 *
607 * So we could even encode up to 4 reasons for the HMI, if
608 * that can ever happen
609 */
610 while (fir) {
611 bit = ilog2(fir);
612 reason = fir_number << 6;
613 reason |= (63 - bit); // IBM numbering
614 add_npu2_xstop_reason(xstop_reason, reason);
615 fir ^= 1ULL << bit;
616 }
617 }
618
find_npu2_checkstop_reason(int flat_chip_id,struct OpalHMIEvent * hmi_evt,uint64_t * out_flags)619 static void find_npu2_checkstop_reason(int flat_chip_id,
620 struct OpalHMIEvent *hmi_evt,
621 uint64_t *out_flags)
622 {
623 struct phb *phb;
624 int i;
625 bool npu2_hmi_verbose = false, found = false;
626 uint64_t npu2_fir;
627 uint64_t npu2_fir_mask;
628 uint64_t npu2_fir_action0;
629 uint64_t npu2_fir_action1;
630 uint64_t npu2_fir_addr;
631 uint64_t npu2_fir_mask_addr;
632 uint64_t npu2_fir_action0_addr;
633 uint64_t npu2_fir_action1_addr;
634 uint64_t fatal_errors;
635 uint32_t xstop_reason = 0;
636 int total_errors = 0;
637 const char *loc;
638
639 /* Find the NPU on the chip associated with the HMI. */
640 for_each_phb(phb) {
641 /* NOTE: if a chip ever has >1 NPU this will need adjusting */
642 if (phb_is_npu2(phb->dt_node) &&
643 (dt_get_chip_id(phb->dt_node) == flat_chip_id)) {
644 found = true;
645 break;
646 }
647 }
648
649 /* If we didn't find a NPU on the chip, it's not our checkstop. */
650 if (!found)
651 return;
652
653 npu2_fir_addr = NPU2_FIR_REGISTER_0;
654 npu2_fir_mask_addr = NPU2_FIR_REGISTER_0 + NPU2_FIR_MASK_OFFSET;
655 npu2_fir_action0_addr = NPU2_FIR_REGISTER_0 + NPU2_FIR_ACTION0_OFFSET;
656 npu2_fir_action1_addr = NPU2_FIR_REGISTER_0 + NPU2_FIR_ACTION1_OFFSET;
657
658 for (i = 0; i < NPU2_TOTAL_FIR_REGISTERS; i++) {
659 /* Read all the registers necessary to find a checkstop condition. */
660 if (xscom_read(flat_chip_id, npu2_fir_addr, &npu2_fir) ||
661 xscom_read(flat_chip_id, npu2_fir_mask_addr, &npu2_fir_mask) ||
662 xscom_read(flat_chip_id, npu2_fir_action0_addr, &npu2_fir_action0) ||
663 xscom_read(flat_chip_id, npu2_fir_action1_addr, &npu2_fir_action1)) {
664 prerror("HMI: Couldn't read NPU FIR register%d with XSCOM\n", i);
665 continue;
666 }
667
668 fatal_errors = npu2_fir & ~npu2_fir_mask & npu2_fir_action0 & npu2_fir_action1;
669
670 if (fatal_errors) {
671 loc = chip_loc_code(flat_chip_id);
672 if (!loc)
673 loc = "Not Available";
674 prlog(PR_ERR, "NPU: [Loc: %s] P:%d FIR#%d FIR 0x%016llx mask 0x%016llx\n",
675 loc, flat_chip_id, i, npu2_fir, npu2_fir_mask);
676 prlog(PR_ERR, "NPU: [Loc: %s] P:%d ACTION0 0x%016llx, ACTION1 0x%016llx\n",
677 loc, flat_chip_id, npu2_fir_action0, npu2_fir_action1);
678 total_errors++;
679
680 encode_npu2_xstop_reason(&xstop_reason, fatal_errors, i);
681 }
682
683 /* Can't do a fence yet, we are just logging fir information for now */
684 npu2_fir_addr += NPU2_FIR_OFFSET;
685 npu2_fir_mask_addr += NPU2_FIR_OFFSET;
686 npu2_fir_action0_addr += NPU2_FIR_OFFSET;
687 npu2_fir_action1_addr += NPU2_FIR_OFFSET;
688
689 }
690
691 if (!total_errors)
692 return;
693
694 npu2_hmi_verbose = nvram_query_eq_safe("npu2-hmi-verbose", "true");
695 /* Force this for now until we sort out something better */
696 npu2_hmi_verbose = true;
697
698 if (npu2_hmi_verbose) {
699 npu2_dump_scoms(flat_chip_id);
700 prlog(PR_ERR, " _________________________ \n");
701 prlog(PR_ERR, "< It's Debug time! >\n");
702 prlog(PR_ERR, " ------------------------- \n");
703 prlog(PR_ERR, " \\ ,__, \n");
704 prlog(PR_ERR, " \\ (oo)____ \n");
705 prlog(PR_ERR, " (__) )\\ \n");
706 prlog(PR_ERR, " ||--|| * \n");
707 }
708
709 /* Set up the HMI event */
710 hmi_evt->severity = OpalHMI_SEV_WARNING;
711 hmi_evt->type = OpalHMI_ERROR_MALFUNC_ALERT;
712 hmi_evt->u.xstop_error.xstop_type = CHECKSTOP_TYPE_NPU;
713 hmi_evt->u.xstop_error.xstop_reason = xstop_reason;
714 hmi_evt->u.xstop_error.u.chip_id = flat_chip_id;
715
716 /* Marking the event as recoverable so that we don't crash */
717 queue_hmi_event(hmi_evt, 1, out_flags);
718 }
719
find_npu_checkstop_reason(int flat_chip_id,struct OpalHMIEvent * hmi_evt,uint64_t * out_flags)720 static void find_npu_checkstop_reason(int flat_chip_id,
721 struct OpalHMIEvent *hmi_evt,
722 uint64_t *out_flags)
723 {
724 struct phb *phb;
725 struct npu *p = NULL;
726
727 uint64_t npu_fir;
728 uint64_t npu_fir_mask;
729 uint64_t npu_fir_action0;
730 uint64_t npu_fir_action1;
731 uint64_t fatal_errors;
732
733 /* Only check for NPU errors if the chip has a NPU */
734 if (PVR_TYPE(mfspr(SPR_PVR)) != PVR_TYPE_P8NVL)
735 return find_npu2_checkstop_reason(flat_chip_id, hmi_evt, out_flags);
736
737 /* Find the NPU on the chip associated with the HMI. */
738 for_each_phb(phb) {
739 /* NOTE: if a chip ever has >1 NPU this will need adjusting */
740 if (dt_node_is_compatible(phb->dt_node, "ibm,power8-npu-pciex") &&
741 (dt_get_chip_id(phb->dt_node) == flat_chip_id)) {
742 p = phb_to_npu(phb);
743 break;
744 }
745 }
746
747 /* If we didn't find a NPU on the chip, it's not our checkstop. */
748 if (p == NULL)
749 return;
750
751 /* Read all the registers necessary to find a checkstop condition. */
752 if (xscom_read(flat_chip_id,
753 p->at_xscom + NX_FIR, &npu_fir) ||
754 xscom_read(flat_chip_id,
755 p->at_xscom + NX_FIR_MASK, &npu_fir_mask) ||
756 xscom_read(flat_chip_id,
757 p->at_xscom + NX_FIR_ACTION0, &npu_fir_action0) ||
758 xscom_read(flat_chip_id,
759 p->at_xscom + NX_FIR_ACTION1, &npu_fir_action1)) {
760 prerror("Couldn't read NPU registers with XSCOM\n");
761 return;
762 }
763
764 fatal_errors = npu_fir & ~npu_fir_mask & npu_fir_action0 & npu_fir_action1;
765
766 /* If there's no errors, we don't need to do anything. */
767 if (!fatal_errors)
768 return;
769
770 prlog(PR_DEBUG, "NPU: FIR 0x%016llx mask 0x%016llx\n",
771 npu_fir, npu_fir_mask);
772 prlog(PR_DEBUG, "NPU: ACTION0 0x%016llx, ACTION1 0x%016llx\n",
773 npu_fir_action0, npu_fir_action1);
774
775 /* Set the NPU to fenced since it can't recover. */
776 npu_set_fence_state(p, true);
777
778 /* Set up the HMI event */
779 hmi_evt->severity = OpalHMI_SEV_WARNING;
780 hmi_evt->type = OpalHMI_ERROR_MALFUNC_ALERT;
781 hmi_evt->u.xstop_error.xstop_type = CHECKSTOP_TYPE_NPU;
782 hmi_evt->u.xstop_error.u.chip_id = flat_chip_id;
783
784 /* The HMI is "recoverable" because it shouldn't crash the system */
785 queue_hmi_event(hmi_evt, 1, out_flags);
786 }
787
decode_malfunction(struct OpalHMIEvent * hmi_evt,uint64_t * out_flags)788 static void decode_malfunction(struct OpalHMIEvent *hmi_evt, uint64_t *out_flags)
789 {
790 int i;
791 uint64_t malf_alert, flags;
792
793 flags = 0;
794
795 if (!setup_scom_addresses()) {
796 prerror("Failed to setup scom addresses\n");
797 /* Send an unknown HMI event. */
798 hmi_evt->u.xstop_error.xstop_type = CHECKSTOP_TYPE_UNKNOWN;
799 hmi_evt->u.xstop_error.xstop_reason = 0;
800 queue_hmi_event(hmi_evt, false, out_flags);
801 return;
802 }
803
804 xscom_read(this_cpu()->chip_id, malf_alert_scom, &malf_alert);
805
806 if (!malf_alert)
807 return;
808
809 for (i = 0; i < 64; i++) {
810 if (malf_alert & PPC_BIT(i)) {
811 xscom_write(this_cpu()->chip_id, malf_alert_scom,
812 ~PPC_BIT(i));
813 find_capp_checkstop_reason(i, hmi_evt, &flags);
814 find_nx_checkstop_reason(i, hmi_evt, &flags);
815 find_npu_checkstop_reason(i, hmi_evt, &flags);
816 }
817 }
818
819 find_core_checkstop_reason(hmi_evt, &flags);
820
821 /*
822 * If we fail to find checkstop reason, send an unknown HMI event.
823 */
824 if (!(flags & OPAL_HMI_FLAGS_NEW_EVENT)) {
825 hmi_evt->u.xstop_error.xstop_type = CHECKSTOP_TYPE_UNKNOWN;
826 hmi_evt->u.xstop_error.xstop_reason = 0;
827 queue_hmi_event(hmi_evt, false, &flags);
828 }
829 *out_flags |= flags;
830 }
831
832 /*
833 * This will "rendez-vous" all threads on the core to the rendez-vous
834 * id "sig". You need to make sure that "sig" is different from the
835 * previous rendez vous. The sig value must be between 0 and 7 with
836 * boot time being set to 0.
837 *
838 * Note: in theory, we could just use a flip flop "sig" in the thread
839 * structure (binary rendez-vous with no argument). This is a bit more
840 * debuggable and better at handling timeouts (arguably).
841 *
842 * This should be called with the no lock held
843 */
hmi_rendez_vous(uint32_t sig)844 static void hmi_rendez_vous(uint32_t sig)
845 {
846 struct cpu_thread *t = this_cpu();
847 uint32_t my_id = cpu_get_thread_index(t);
848 uint32_t my_shift = my_id << 2;
849 uint32_t *sptr = t->core_hmi_state_ptr;
850 uint32_t val, prev, shift, i;
851 uint64_t timeout;
852
853 assert(sig <= 0x7);
854
855 /*
856 * Mark ourselves as having reached the rendez vous point with
857 * the exit bit cleared
858 */
859 do {
860 val = prev = *sptr;
861 val &= ~(0xfu << my_shift);
862 val |= sig << my_shift;
863 } while (cmpxchg32(sptr, prev, val) != prev);
864
865 /*
866 * Wait for everybody else to reach that point, ignore the
867 * exit bit as another thread could have already set it.
868 */
869 for (i = 0; i < cpu_thread_count; i++) {
870 shift = i << 2;
871
872 timeout = TIMEOUT_LOOPS;
873 while (((*sptr >> shift) & 0x7) != sig && --timeout)
874 cpu_relax();
875 if (!timeout)
876 prlog(PR_ERR, "Rendez-vous stage 1 timeout, CPU 0x%x"
877 " waiting for thread %d (sptr=%08x)\n",
878 t->pir, i, *sptr);
879 }
880
881 /* Set the exit bit */
882 do {
883 val = prev = *sptr;
884 val &= ~(0xfu << my_shift);
885 val |= (sig | 8) << my_shift;
886 } while (cmpxchg32(sptr, prev, val) != prev);
887
888 /* At this point, we need to wait for everybody else to have a value
889 * that is *not* sig. IE. they either have set the exit bit *or* they
890 * have changed the rendez-vous (meaning they have moved on to another
891 * rendez vous point).
892 */
893 for (i = 0; i < cpu_thread_count; i++) {
894 shift = i << 2;
895
896 timeout = TIMEOUT_LOOPS;
897 while (((*sptr >> shift) & 0xf) == sig && --timeout)
898 cpu_relax();
899 if (!timeout)
900 prlog(PR_ERR, "Rendez-vous stage 2 timeout, CPU 0x%x"
901 " waiting for thread %d (sptr=%08x)\n",
902 t->pir, i, *sptr);
903 }
904 }
905
hmi_print_debug(const uint8_t * msg,uint64_t hmer)906 static void hmi_print_debug(const uint8_t *msg, uint64_t hmer)
907 {
908 const char *loc;
909 uint32_t core_id, thread_index;
910
911 core_id = pir_to_core_id(this_cpu()->pir);
912 thread_index = cpu_get_thread_index(this_cpu());
913
914 loc = chip_loc_code(this_cpu()->chip_id);
915 if (!loc)
916 loc = "Not Available";
917
918 if (hmer & (SPR_HMER_TFAC_ERROR | SPR_HMER_TFMR_PARITY_ERROR)) {
919 prlog(PR_DEBUG, "[Loc: %s]: P:%d C:%d T:%d: TFMR(%016lx) %s\n",
920 loc, this_cpu()->chip_id, core_id, thread_index,
921 mfspr(SPR_TFMR), msg);
922 } else {
923 prlog(PR_DEBUG, "[Loc: %s]: P:%d C:%d T:%d: %s\n",
924 loc, this_cpu()->chip_id, core_id, thread_index,
925 msg);
926 }
927 }
928
handle_thread_tfac_error(uint64_t tfmr,uint64_t * out_flags)929 static int handle_thread_tfac_error(uint64_t tfmr, uint64_t *out_flags)
930 {
931 int recover = 1;
932
933 if (tfmr & SPR_TFMR_DEC_PARITY_ERR)
934 *out_flags |= OPAL_HMI_FLAGS_DEC_LOST;
935 if (!tfmr_recover_local_errors(tfmr))
936 recover = 0;
937 tfmr &= ~(SPR_TFMR_PURR_PARITY_ERR |
938 SPR_TFMR_SPURR_PARITY_ERR |
939 SPR_TFMR_DEC_PARITY_ERR);
940 return recover;
941 }
942
943 static int64_t opal_handle_hmi(void);
944
opal_handle_hmi_job(void * data __unused)945 static void opal_handle_hmi_job(void *data __unused)
946 {
947 opal_handle_hmi();
948 }
949
950 /*
951 * Queue hmi handling job If secondaries are still in OPAL
952 * This function is called by thread 0.
953 */
hmi_kick_secondaries(void)954 static struct cpu_job **hmi_kick_secondaries(void)
955 {
956 struct cpu_thread *ts = this_cpu();
957 struct cpu_job **hmi_jobs = NULL;
958 int job_sz = sizeof(struct cpu_job *) * cpu_thread_count;
959 int i;
960
961 for (i = 1; i < cpu_thread_count; i++) {
962 ts = next_cpu(ts);
963
964 /* Is this thread still in OPAL ? */
965 if (ts->state == cpu_state_active) {
966 if (!hmi_jobs) {
967 hmi_jobs = zalloc(job_sz);
968 assert(hmi_jobs);
969 }
970
971 prlog(PR_DEBUG, "Sending hmi job to thread %d\n", i);
972 hmi_jobs[i] = cpu_queue_job(ts, "handle_hmi_job",
973 opal_handle_hmi_job, NULL);
974 }
975 }
976 return hmi_jobs;
977 }
978
handle_all_core_tfac_error(uint64_t tfmr,uint64_t * out_flags)979 static int handle_all_core_tfac_error(uint64_t tfmr, uint64_t *out_flags)
980 {
981 struct cpu_thread *t, *t0;
982 int recover = -1;
983 struct cpu_job **hmi_jobs = NULL;
984
985 t = this_cpu();
986 t0 = find_cpu_by_pir(cpu_get_thread0(t));
987
988 if (t == t0 && t0->state == cpu_state_os)
989 hmi_jobs = hmi_kick_secondaries();
990
991 /* Rendez vous all threads */
992 hmi_rendez_vous(1);
993
994 /* We use a lock here as some of the TFMR bits are shared and I
995 * prefer avoiding doing the cleanup simultaneously.
996 */
997 lock(&hmi_lock);
998
999 /* First handle corrupt TFMR otherwise we can't trust anything.
1000 * We'll use a lock here so that the threads don't try to do it at
1001 * the same time
1002 */
1003 if (tfmr & SPR_TFMR_TFMR_CORRUPT) {
1004 /* Check if it's still in error state */
1005 if (mfspr(SPR_TFMR) & SPR_TFMR_TFMR_CORRUPT)
1006 if (!recover_corrupt_tfmr()) {
1007 unlock(&hmi_lock);
1008 recover = 0;
1009 goto error_out;
1010 }
1011
1012 tfmr = mfspr(SPR_TFMR);
1013
1014 /* We could have got new thread errors in the meantime */
1015 if (tfmr & SPR_TFMR_THREAD_ERRORS) {
1016 recover = handle_thread_tfac_error(tfmr, out_flags);
1017 tfmr &= ~SPR_TFMR_THREAD_ERRORS;
1018 }
1019 if (!recover) {
1020 unlock(&hmi_lock);
1021 goto error_out;
1022 }
1023 }
1024
1025 /* Tell the OS ... */
1026 if (tfmr & SPR_TFMR_HDEC_PARITY_ERROR)
1027 *out_flags |= OPAL_HMI_FLAGS_HDEC_LOST;
1028
1029 /* Cleanup bad HDEC or TB on all threads or subcures before we clear
1030 * the error conditions
1031 */
1032 tfmr_cleanup_core_errors(tfmr);
1033
1034 /* Unlock before next rendez-vous */
1035 unlock(&hmi_lock);
1036
1037 /* Second rendez vous, ensure the above cleanups are all done before
1038 * we proceed further
1039 */
1040 hmi_rendez_vous(2);
1041
1042 /* We can now clear the error conditions in the core. */
1043 recover = tfmr_clear_core_errors(tfmr);
1044 if (recover == 0)
1045 goto error_out;
1046
1047 /* Third rendez-vous. We could in theory do the timebase resync as
1048 * part of the previous one, but I prefer having all the error
1049 * conditions cleared before we start trying.
1050 */
1051 hmi_rendez_vous(3);
1052
1053 /* Now perform the actual TB recovery on thread 0 */
1054 if (t == t0)
1055 recover = chiptod_recover_tb_errors(&this_cpu()->tb_resynced);
1056
1057 error_out:
1058 /* Last rendez-vous */
1059 hmi_rendez_vous(4);
1060
1061 /* Now all threads have gone past rendez-vous 3 and not yet past another
1062 * rendez-vous 1, so the value of tb_resynced of thread 0 of the core
1063 * contains an accurate indication as to whether the timebase was lost.
1064 */
1065 if (t0->tb_resynced)
1066 *out_flags |= OPAL_HMI_FLAGS_TB_RESYNC;
1067
1068 if (t == t0 && hmi_jobs) {
1069 int i;
1070 for (i = 1; i < cpu_thread_count; i++)
1071 if (hmi_jobs[i])
1072 cpu_wait_job(hmi_jobs[i], true);
1073 free(hmi_jobs);
1074 }
1075
1076 return recover;
1077 }
1078
read_tfmr_t0(void)1079 static uint64_t read_tfmr_t0(void)
1080 {
1081 uint64_t tfmr_t0;
1082 uint32_t chip_id = this_cpu()->chip_id;
1083 uint32_t core_id = pir_to_core_id(this_cpu()->pir);
1084
1085 lock(&hmi_lock);
1086
1087 xscom_write(chip_id, XSCOM_ADDR_P9_EC(core_id, P9_SCOM_SPRC),
1088 SETFIELD(P9_SCOMC_SPR_SELECT, 0, P9_SCOMC_TFMR_T0));
1089 xscom_read(chip_id, XSCOM_ADDR_P9_EC(core_id, P9_SCOM_SPRD),
1090 &tfmr_t0);
1091 unlock(&hmi_lock);
1092 return tfmr_t0;
1093 }
1094
1095 /* P9 errata: In theory, an HDEC error is sent to all threads. However,
1096 * due to an errata on P9 where TFMR bit 26 (HDEC parity) cannot be
1097 * cleared on thread 1..3, I am not confident we can do a rendez-vous
1098 * in all cases.
1099 *
1100 * Our current approach is to ignore that error unless it is present
1101 * on thread 0 TFMR. Also, ignore TB residue error due to a similar
1102 * errata as above.
1103 */
validate_latched_errors(uint64_t * tfmr)1104 static void validate_latched_errors(uint64_t *tfmr)
1105 {
1106 if ((*tfmr & (SPR_TFMR_HDEC_PARITY_ERROR | SPR_TFMR_TB_RESIDUE_ERR))
1107 && this_cpu()->is_secondary) {
1108 uint64_t tfmr_t0 = read_tfmr_t0();
1109
1110 if (!(tfmr_t0 & SPR_TFMR_HDEC_PARITY_ERROR))
1111 *tfmr &= ~SPR_TFMR_HDEC_PARITY_ERROR;
1112
1113 if (!(tfmr_t0 & SPR_TFMR_TB_RESIDUE_ERR))
1114 *tfmr &= ~SPR_TFMR_TB_RESIDUE_ERR;
1115 }
1116 }
1117
handle_tfac_errors(struct OpalHMIEvent * hmi_evt,uint64_t * out_flags)1118 static int handle_tfac_errors(struct OpalHMIEvent *hmi_evt, uint64_t *out_flags)
1119 {
1120 int recover = -1;
1121 uint64_t tfmr = mfspr(SPR_TFMR);
1122
1123 /* Initialize the hmi event with old value of TFMR */
1124 hmi_evt->tfmr = tfmr;
1125
1126 /* A TFMR parity/corrupt error makes us ignore all the local stuff.*/
1127 if (tfmr & SPR_TFMR_TFMR_CORRUPT) {
1128 /* Mark TB as invalid for now as we don't trust TFMR, we'll fix
1129 * it up later
1130 */
1131 this_cpu()->tb_invalid = true;
1132 goto bad_tfmr;
1133 }
1134
1135 this_cpu()->tb_invalid = !(tfmr & SPR_TFMR_TB_VALID);
1136
1137 if (proc_gen == proc_gen_p9)
1138 validate_latched_errors(&tfmr);
1139
1140 /* First, handle thread local errors */
1141 if (tfmr & SPR_TFMR_THREAD_ERRORS) {
1142 recover = handle_thread_tfac_error(tfmr, out_flags);
1143 tfmr &= ~SPR_TFMR_THREAD_ERRORS;
1144 }
1145
1146 bad_tfmr:
1147
1148 /* Let's see if we still have a all-core error to deal with, if
1149 * not, we just bail out
1150 */
1151 if (tfmr & SPR_TFMR_CORE_ERRORS) {
1152 int recover2;
1153
1154 /* Only update "recover" if it's not already 0 (non-recovered)
1155 */
1156 recover2 = handle_all_core_tfac_error(tfmr, out_flags);
1157 if (recover != 0)
1158 recover = recover2;
1159 } else if (tfmr & SPR_TFMR_CHIP_TOD_INTERRUPT) {
1160 int recover2;
1161
1162 /*
1163 * There are some TOD errors which do not affect working of
1164 * TOD and TB. They stay in valid state. Hence we don't need
1165 * rendez vous.
1166 *
1167 * TOD errors that affects TOD/TB will report a global error
1168 * on TFMR alongwith bit 51, and they will go in rendez vous.
1169 */
1170 recover2 = chiptod_recover_tod_errors();
1171 if (recover != 0)
1172 recover = recover2;
1173 } else if (this_cpu()->tb_invalid) {
1174 /* This shouldn't happen, TB is invalid and no global error
1175 * was reported. We just return for now assuming one will
1176 * be. We can't do a rendez vous without a core-global HMI.
1177 */
1178 prlog(PR_ERR, "HMI: TB invalid without core error reported ! "
1179 "CPU=%x, TFMR=0x%016lx\n", this_cpu()->pir,
1180 mfspr(SPR_TFMR));
1181 }
1182
1183 if (recover != -1 && hmi_evt) {
1184 hmi_evt->severity = OpalHMI_SEV_ERROR_SYNC;
1185 hmi_evt->type = OpalHMI_ERROR_TFAC;
1186 queue_hmi_event(hmi_evt, recover, out_flags);
1187 }
1188
1189 /* Set the TB state looking at TFMR register before we head out. */
1190 this_cpu()->tb_invalid = !(mfspr(SPR_TFMR) & SPR_TFMR_TB_VALID);
1191
1192 if (this_cpu()->tb_invalid) {
1193 *out_flags |= OPAL_HMI_FLAGS_TOD_TB_FAIL;
1194 prlog(PR_WARNING, "Failed to get TB in running state! "
1195 "CPU=%x, TFMR=%016lx\n", this_cpu()->pir,
1196 mfspr(SPR_TFMR));
1197 }
1198
1199 return recover;
1200 }
1201
handle_hmi_exception(uint64_t hmer,struct OpalHMIEvent * hmi_evt,uint64_t * out_flags)1202 static int handle_hmi_exception(uint64_t hmer, struct OpalHMIEvent *hmi_evt,
1203 uint64_t *out_flags)
1204 {
1205 struct cpu_thread *cpu = this_cpu();
1206 int recover = 1;
1207 uint64_t handled = 0;
1208
1209 prlog(PR_DEBUG, "Received HMI interrupt: HMER = 0x%016llx\n", hmer);
1210 /* Initialize the hmi event with old value of HMER */
1211 if (hmi_evt)
1212 hmi_evt->hmer = hmer;
1213
1214 /* Handle Timer/TOD errors separately */
1215 if (hmer & (SPR_HMER_TFAC_ERROR | SPR_HMER_TFMR_PARITY_ERROR)) {
1216 hmi_print_debug("Timer Facility Error", hmer);
1217 handled = hmer & (SPR_HMER_TFAC_ERROR | SPR_HMER_TFMR_PARITY_ERROR);
1218 mtspr(SPR_HMER, ~handled);
1219 recover = handle_tfac_errors(hmi_evt, out_flags);
1220 handled = 0;
1221 }
1222
1223 lock(&hmi_lock);
1224 /*
1225 * Not all HMIs would move TB into invalid state. Set the TB state
1226 * looking at TFMR register. TFMR will tell us correct state of
1227 * TB register.
1228 */
1229 if (hmer & SPR_HMER_PROC_RECV_DONE) {
1230 uint32_t chip_id = pir_to_chip_id(cpu->pir);
1231 uint32_t core_id = pir_to_core_id(cpu->pir);
1232 uint64_t core_wof;
1233
1234 hmi_print_debug("Processor recovery occurred.", hmer);
1235 if (!read_core_wof(chip_id, core_id, &core_wof)) {
1236 int i;
1237
1238 prlog(PR_DEBUG, "Core WOF = 0x%016llx recovered error:\n", core_wof);
1239 for (i = 0; i < ARRAY_SIZE(recoverable_bits); i++) {
1240 if (core_wof & PPC_BIT(recoverable_bits[i].bit))
1241 prlog(PR_DEBUG, "%s\n",
1242 recoverable_bits[i].reason);
1243 }
1244 }
1245
1246 handled |= SPR_HMER_PROC_RECV_DONE;
1247 if (cpu_is_thread0(cpu) && hmi_evt) {
1248 hmi_evt->severity = OpalHMI_SEV_NO_ERROR;
1249 hmi_evt->type = OpalHMI_ERROR_PROC_RECOV_DONE;
1250 queue_hmi_event(hmi_evt, recover, out_flags);
1251 }
1252 }
1253 if (hmer & SPR_HMER_PROC_RECV_ERROR_MASKED) {
1254 handled |= SPR_HMER_PROC_RECV_ERROR_MASKED;
1255 if (cpu_is_thread0(cpu) && hmi_evt) {
1256 hmi_evt->severity = OpalHMI_SEV_NO_ERROR;
1257 hmi_evt->type = OpalHMI_ERROR_PROC_RECOV_MASKED;
1258 queue_hmi_event(hmi_evt, recover, out_flags);
1259 }
1260 hmi_print_debug("Processor recovery Done (masked).", hmer);
1261 }
1262 if (hmer & SPR_HMER_PROC_RECV_AGAIN) {
1263 handled |= SPR_HMER_PROC_RECV_AGAIN;
1264 if (cpu_is_thread0(cpu) && hmi_evt) {
1265 hmi_evt->severity = OpalHMI_SEV_NO_ERROR;
1266 hmi_evt->type = OpalHMI_ERROR_PROC_RECOV_DONE_AGAIN;
1267 queue_hmi_event(hmi_evt, recover, out_flags);
1268 }
1269 hmi_print_debug("Processor recovery occurred again before"
1270 "bit2 was cleared\n", hmer);
1271 }
1272 /* Assert if we see malfunction alert, we can not continue. */
1273 if (hmer & SPR_HMER_MALFUNCTION_ALERT) {
1274 handled |= SPR_HMER_MALFUNCTION_ALERT;
1275
1276 hmi_print_debug("Malfunction Alert", hmer);
1277 if (hmi_evt)
1278 decode_malfunction(hmi_evt, out_flags);
1279 }
1280
1281 /* Assert if we see Hypervisor resource error, we can not continue. */
1282 if (hmer & SPR_HMER_HYP_RESOURCE_ERR) {
1283 handled |= SPR_HMER_HYP_RESOURCE_ERR;
1284
1285 hmi_print_debug("Hypervisor resource error", hmer);
1286 recover = 0;
1287 if (hmi_evt) {
1288 hmi_evt->severity = OpalHMI_SEV_FATAL;
1289 hmi_evt->type = OpalHMI_ERROR_HYP_RESOURCE;
1290 queue_hmi_event(hmi_evt, recover, out_flags);
1291 }
1292 }
1293 if (hmer & SPR_HMER_TRIG_FIR_HMI) {
1294 handled |= SPR_HMER_TRIG_FIR_HMI;
1295 hmer &= ~SPR_HMER_TRIG_FIR_HMI;
1296
1297 hmi_print_debug("Clearing unknown debug trigger", hmer);
1298 if (hmi_evt) {
1299 hmi_evt->severity = OpalHMI_SEV_NO_ERROR;
1300 hmi_evt->type = OpalHMI_ERROR_DEBUG_TRIG_FIR,
1301 queue_hmi_event(hmi_evt, recover, out_flags);
1302 }
1303 }
1304
1305 if (recover == 0)
1306 disable_fast_reboot("Unrecoverable HMI");
1307 /*
1308 * HMER bits are sticky, once set to 1 they remain set to 1 until
1309 * they are set to 0. Reset the error source bit to 0, otherwise
1310 * we keep getting HMI interrupt again and again. Writing to HMER
1311 * acts as an AND, so we write mask of all 1's except for the bits
1312 * we want to clear.
1313 */
1314 mtspr(SPR_HMER, ~handled);
1315 unlock(&hmi_lock);
1316 return recover;
1317 }
1318
opal_handle_hmi(void)1319 static int64_t opal_handle_hmi(void)
1320 {
1321 uint64_t hmer, dummy_flags;
1322 struct OpalHMIEvent hmi_evt;
1323
1324 /*
1325 * Compiled time check to see size of OpalHMIEvent do not exceed
1326 * that of struct opal_msg.
1327 */
1328 BUILD_ASSERT(sizeof(struct opal_msg) >= sizeof(struct OpalHMIEvent));
1329
1330 memset(&hmi_evt, 0, sizeof(struct OpalHMIEvent));
1331 hmi_evt.version = OpalHMIEvt_V2;
1332
1333 hmer = mfspr(SPR_HMER); /* Get HMER register value */
1334 handle_hmi_exception(hmer, &hmi_evt, &dummy_flags);
1335
1336 return OPAL_SUCCESS;
1337 }
1338 opal_call(OPAL_HANDLE_HMI, opal_handle_hmi, 0);
1339
opal_handle_hmi2(__be64 * out_flags)1340 static int64_t opal_handle_hmi2(__be64 *out_flags)
1341 {
1342 uint64_t hmer, flags = 0;
1343 struct OpalHMIEvent hmi_evt;
1344
1345 /*
1346 * Compiled time check to see size of OpalHMIEvent do not exceed
1347 * that of struct opal_msg.
1348 */
1349 BUILD_ASSERT(sizeof(struct opal_msg) >= sizeof(struct OpalHMIEvent));
1350
1351 memset(&hmi_evt, 0, sizeof(struct OpalHMIEvent));
1352 hmi_evt.version = OpalHMIEvt_V2;
1353
1354 hmer = mfspr(SPR_HMER); /* Get HMER register value */
1355 handle_hmi_exception(hmer, &hmi_evt, &flags);
1356 *out_flags = cpu_to_be64(flags);
1357
1358 return OPAL_SUCCESS;
1359 }
1360 opal_call(OPAL_HANDLE_HMI2, opal_handle_hmi2, 1);
1361