hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/arch/powerpc/platforms/powernv/opal-hmi.c
....@@ -1,18 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * OPAL hypervisor Maintenance interrupt handling support in PowerNV.
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License as published by
6
- * the Free Software Foundation; either version 2 of the License, or
7
- * (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; If not, see <http://www.gnu.org/licenses/>.
164 *
175 * Copyright 2014 IBM Corporation
186 * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
....@@ -149,6 +137,43 @@
149137 xstop_reason[i].description);
150138 }
151139
140
+static void print_npu_checkstop_reason(const char *level,
141
+ struct OpalHMIEvent *hmi_evt)
142
+{
143
+ uint8_t reason, reason_count, i;
144
+
145
+ /*
146
+ * We may not have a checkstop reason on some combination of
147
+ * hardware and/or skiboot version
148
+ */
149
+ if (!hmi_evt->u.xstop_error.xstop_reason) {
150
+ printk("%s NPU checkstop on chip %x\n", level,
151
+ be32_to_cpu(hmi_evt->u.xstop_error.u.chip_id));
152
+ return;
153
+ }
154
+
155
+ /*
156
+ * NPU2 has 3 FIRs. Reason encoded on a byte as:
157
+ * 2 bits for the FIR number
158
+ * 6 bits for the bit number
159
+ * It may be possible to find several reasons.
160
+ *
161
+ * We don't display a specific message per FIR bit as there
162
+ * are too many and most are meaningless without the workbook
163
+ * and/or hw team help anyway.
164
+ */
165
+ reason_count = sizeof(hmi_evt->u.xstop_error.xstop_reason) /
166
+ sizeof(reason);
167
+ for (i = 0; i < reason_count; i++) {
168
+ reason = (hmi_evt->u.xstop_error.xstop_reason >> (8 * i)) & 0xFF;
169
+ if (reason)
170
+ printk("%s NPU checkstop on chip %x: FIR%d bit %d is set\n",
171
+ level,
172
+ be32_to_cpu(hmi_evt->u.xstop_error.u.chip_id),
173
+ reason >> 6, reason & 0x3F);
174
+ }
175
+}
176
+
152177 static void print_checkstop_reason(const char *level,
153178 struct OpalHMIEvent *hmi_evt)
154179 {
....@@ -160,6 +185,9 @@
160185 case CHECKSTOP_TYPE_NX:
161186 print_nx_checkstop_reason(level, hmi_evt);
162187 break;
188
+ case CHECKSTOP_TYPE_NPU:
189
+ print_npu_checkstop_reason(level, hmi_evt);
190
+ break;
163191 default:
164192 printk("%s Unknown Malfunction Alert of type %d\n",
165193 level, type);