1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 #include "adf_dev_err.h"
5
6 struct reg_info {
7 size_t offs;
8 char *name;
9 };
10
11 static struct reg_info adf_err_regs[] = {
12 { ADF_ERRSOU0, "ERRSOU0" },
13 { ADF_ERRSOU1, "ERRSOU1" },
14 { ADF_ERRSOU3, "ERRSOU3" },
15 { ADF_ERRSOU4, "ERRSOU4" },
16 { ADF_ERRSOU5, "ERRSOU5" },
17 { ADF_RICPPINTSTS, "RICPPINTSTS" },
18 { ADF_RIERRPUSHID, "RIERRPUSHID" },
19 { ADF_RIERRPULLID, "RIERRPULLID" },
20 { ADF_CPP_CFC_ERR_STATUS, "CPP_CFC_ERR_STATUS" },
21 { ADF_CPP_CFC_ERR_PPID, "CPP_CFC_ERR_PPID" },
22 { ADF_TICPPINTSTS, "TICPPINTSTS" },
23 { ADF_TIERRPUSHID, "TIERRPUSHID" },
24 { ADF_TIERRPULLID, "TIERRPULLID" },
25 { ADF_SECRAMUERR, "SECRAMUERR" },
26 { ADF_SECRAMUERRAD, "SECRAMUERRAD" },
27 { ADF_CPPMEMTGTERR, "CPPMEMTGTERR" },
28 { ADF_ERRPPID, "ERRPPID" },
29 };
30
31 static u32
32 adf_get_intstatsssm(struct resource *pmisc_bar_addr, size_t dev)
33 {
34 return ADF_CSR_RD(pmisc_bar_addr, ADF_INTSTATSSM(dev));
35 }
36
37 static u32
38 adf_get_pperr(struct resource *pmisc_bar_addr, size_t dev)
39 {
40 return ADF_CSR_RD(pmisc_bar_addr, ADF_PPERR(dev));
41 }
42
43 static u32
44 adf_get_pperrid(struct resource *pmisc_bar_addr, size_t dev)
45 {
46 return ADF_CSR_RD(pmisc_bar_addr, ADF_PPERRID(dev));
47 }
48
49 static u32
50 adf_get_uerrssmsh(struct resource *pmisc_bar_addr, size_t dev)
51 {
52 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMSH(dev));
53 }
54
55 static u32
56 adf_get_uerrssmshad(struct resource *pmisc_bar_addr, size_t dev)
57 {
58 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMSHAD(dev));
59 }
60
61 static u32
62 adf_get_uerrssmmmp0(struct resource *pmisc_bar_addr, size_t dev)
63 {
64 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMMMP(dev, 0));
65 }
66
67 static u32
68 adf_get_uerrssmmmp1(struct resource *pmisc_bar_addr, size_t dev)
69 {
70 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMMMP(dev, 1));
71 }
72
73 static u32
74 adf_get_uerrssmmmp2(struct resource *pmisc_bar_addr, size_t dev)
75 {
76 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMMMP(dev, 2));
77 }
78
79 static u32
80 adf_get_uerrssmmmp3(struct resource *pmisc_bar_addr, size_t dev)
81 {
82 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMMMP(dev, 3));
83 }
84
85 static u32
86 adf_get_uerrssmmmp4(struct resource *pmisc_bar_addr, size_t dev)
87 {
88 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMMMP(dev, 4));
89 }
90
91 static u32
92 adf_get_uerrssmmmpad0(struct resource *pmisc_bar_addr, size_t dev)
93 {
94 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMMMPAD(dev, 0));
95 }
96
97 static u32
98 adf_get_uerrssmmmpad1(struct resource *pmisc_bar_addr, size_t dev)
99 {
100 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMMMPAD(dev, 1));
101 }
102
103 static u32
104 adf_get_uerrssmmmpad2(struct resource *pmisc_bar_addr, size_t dev)
105 {
106 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMMMPAD(dev, 2));
107 }
108
109 static u32
110 adf_get_uerrssmmmpad3(struct resource *pmisc_bar_addr, size_t dev)
111 {
112 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMMMPAD(dev, 3));
113 }
114
115 static u32
116 adf_get_uerrssmmmpad4(struct resource *pmisc_bar_addr, size_t dev)
117 {
118 return ADF_CSR_RD(pmisc_bar_addr, ADF_UERRSSMMMPAD(dev, 4));
119 }
120
121 struct reg_array_info {
122 u32 (*read)(struct resource *pmisc_bar_addr, size_t dev);
123 char *name;
124 };
125
126 static struct reg_array_info adf_accel_err_regs[] = {
127 { adf_get_intstatsssm, "INTSTATSSM" },
128 { adf_get_pperr, "PPERR" },
129 { adf_get_pperrid, "PPERRID" },
130 { adf_get_uerrssmsh, "UERRSSMSH" },
131 { adf_get_uerrssmshad, "UERRSSMSHAD" },
132 { adf_get_uerrssmmmp0, "UERRSSMMMP0" },
133 { adf_get_uerrssmmmp1, "UERRSSMMMP1" },
134 { adf_get_uerrssmmmp2, "UERRSSMMMP2" },
135 { adf_get_uerrssmmmp3, "UERRSSMMMP3" },
136 { adf_get_uerrssmmmp4, "UERRSSMMMP4" },
137 { adf_get_uerrssmmmpad0, "UERRSSMMMPAD0" },
138 { adf_get_uerrssmmmpad1, "UERRSSMMMPAD1" },
139 { adf_get_uerrssmmmpad2, "UERRSSMMMPAD2" },
140 { adf_get_uerrssmmmpad3, "UERRSSMMMPAD3" },
141 { adf_get_uerrssmmmpad4, "UERRSSMMMPAD4" },
142 };
143
144 static char adf_printf_buf[128] = { 0 };
145 static size_t adf_printf_len;
146
147 static void
148 adf_print_flush(struct adf_accel_dev *accel_dev)
149 {
150 if (adf_printf_len > 0) {
151 device_printf(GET_DEV(accel_dev), "%.128s\n", adf_printf_buf);
152 adf_printf_len = 0;
153 }
154 }
155
156 static void
157 adf_print_reg(struct adf_accel_dev *accel_dev,
158 const char *name,
159 size_t idx,
160 u32 val)
161 {
162 adf_printf_len += snprintf(&adf_printf_buf[adf_printf_len],
163 sizeof(adf_printf_buf) - adf_printf_len,
164 "%s[%zu],%.8x,",
165 name,
166 idx,
167 val);
168
169 if (adf_printf_len >= 80)
170 adf_print_flush(accel_dev);
171 }
172
173 void
174 adf_print_err_registers(struct adf_accel_dev *accel_dev)
175 {
176 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
177 struct adf_bar *misc_bar =
178 &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
179 struct resource *csr = misc_bar->virt_addr;
180 size_t i;
181 unsigned int mask;
182 u32 val;
183
184 for (i = 0; i < ARRAY_SIZE(adf_err_regs); ++i) {
185 val = ADF_CSR_RD(csr, adf_err_regs[i].offs);
186
187 adf_print_reg(accel_dev, adf_err_regs[i].name, 0, val);
188 }
189
190 for (i = 0; i < ARRAY_SIZE(adf_accel_err_regs); ++i) {
191 size_t accel;
192
193 for (accel = 0, mask = hw_data->accel_mask; mask;
194 accel++, mask >>= 1) {
195 if (!(mask & 1))
196 continue;
197 val = adf_accel_err_regs[i].read(csr, accel);
198
199 adf_print_reg(accel_dev,
200 adf_accel_err_regs[i].name,
201 accel,
202 val);
203 }
204 }
205
206 adf_print_flush(accel_dev);
207 }
208
209 static void
210 adf_log_slice_hang(struct adf_accel_dev *accel_dev,
211 u8 accel_num,
212 char *unit_name,
213 u8 unit_number)
214 {
215 device_printf(GET_DEV(accel_dev),
216 "CPM #%x Slice Hang Detected unit: %s%d.\n",
217 accel_num,
218 unit_name,
219 unit_number);
220 }
221
222 bool
223 adf_handle_slice_hang(struct adf_accel_dev *accel_dev,
224 u8 accel_num,
225 struct resource *csr,
226 u32 slice_hang_offset)
227 {
228 u32 slice_hang = ADF_CSR_RD(csr, slice_hang_offset);
229
230 if (!slice_hang)
231 return false;
232
233 if (slice_hang & ADF_SLICE_HANG_AUTH0_MASK)
234 adf_log_slice_hang(accel_dev, accel_num, "Auth", 0);
235 if (slice_hang & ADF_SLICE_HANG_AUTH1_MASK)
236 adf_log_slice_hang(accel_dev, accel_num, "Auth", 1);
237 if (slice_hang & ADF_SLICE_HANG_AUTH2_MASK)
238 adf_log_slice_hang(accel_dev, accel_num, "Auth", 2);
239 if (slice_hang & ADF_SLICE_HANG_CPHR0_MASK)
240 adf_log_slice_hang(accel_dev, accel_num, "Cipher", 0);
241 if (slice_hang & ADF_SLICE_HANG_CPHR1_MASK)
242 adf_log_slice_hang(accel_dev, accel_num, "Cipher", 1);
243 if (slice_hang & ADF_SLICE_HANG_CPHR2_MASK)
244 adf_log_slice_hang(accel_dev, accel_num, "Cipher", 2);
245 if (slice_hang & ADF_SLICE_HANG_CMP0_MASK)
246 adf_log_slice_hang(accel_dev, accel_num, "Comp", 0);
247 if (slice_hang & ADF_SLICE_HANG_CMP1_MASK)
248 adf_log_slice_hang(accel_dev, accel_num, "Comp", 1);
249 if (slice_hang & ADF_SLICE_HANG_XLT0_MASK)
250 adf_log_slice_hang(accel_dev, accel_num, "Xlator", 0);
251 if (slice_hang & ADF_SLICE_HANG_XLT1_MASK)
252 adf_log_slice_hang(accel_dev, accel_num, "Xlator", 1);
253 if (slice_hang & ADF_SLICE_HANG_MMP0_MASK)
254 adf_log_slice_hang(accel_dev, accel_num, "MMP", 0);
255 if (slice_hang & ADF_SLICE_HANG_MMP1_MASK)
256 adf_log_slice_hang(accel_dev, accel_num, "MMP", 1);
257 if (slice_hang & ADF_SLICE_HANG_MMP2_MASK)
258 adf_log_slice_hang(accel_dev, accel_num, "MMP", 2);
259 if (slice_hang & ADF_SLICE_HANG_MMP3_MASK)
260 adf_log_slice_hang(accel_dev, accel_num, "MMP", 3);
261 if (slice_hang & ADF_SLICE_HANG_MMP4_MASK)
262 adf_log_slice_hang(accel_dev, accel_num, "MMP", 4);
263
264 /* Clear the associated interrupt */
265 ADF_CSR_WR(csr, slice_hang_offset, slice_hang);
266
267 return true;
268 }
269
270 /**
271 * adf_check_slice_hang() - Check slice hang status
272 *
273 * Return: true if a slice hange interrupt is serviced..
274 */
275 bool
276 adf_check_slice_hang(struct adf_accel_dev *accel_dev)
277 {
278 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
279 struct adf_bar *misc_bar =
280 &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
281 struct resource *csr = misc_bar->virt_addr;
282 u32 errsou3 = ADF_CSR_RD(csr, ADF_ERRSOU3);
283 u32 errsou5 = ADF_CSR_RD(csr, ADF_ERRSOU5);
284 u32 offset;
285 u32 accel_num;
286 bool handled = false;
287 u32 errsou[] = { errsou3, errsou3, errsou5, errsou5, errsou5 };
288 u32 mask[] = { ADF_EMSK3_CPM0_MASK,
289 ADF_EMSK3_CPM1_MASK,
290 ADF_EMSK5_CPM2_MASK,
291 ADF_EMSK5_CPM3_MASK,
292 ADF_EMSK5_CPM4_MASK };
293 unsigned int accel_mask;
294
295 for (accel_num = 0, accel_mask = hw_data->accel_mask; accel_mask;
296 accel_num++, accel_mask >>= 1) {
297 if (!(accel_mask & 1))
298 continue;
299 if (accel_num >= ARRAY_SIZE(errsou)) {
300 device_printf(GET_DEV(accel_dev),
301 "Invalid accel_num %d.\n",
302 accel_num);
303 break;
304 }
305
306 if (errsou[accel_num] & mask[accel_num]) {
307 if (ADF_CSR_RD(csr, ADF_INTSTATSSM(accel_num)) &
308 ADF_INTSTATSSM_SHANGERR) {
309 offset = ADF_SLICEHANGSTATUS(accel_num);
310 handled |= adf_handle_slice_hang(accel_dev,
311 accel_num,
312 csr,
313 offset);
314 }
315 }
316 }
317
318 return handled;
319 }
Cache object: 6f56b213f8e59803c4e62d8c594f6e5c
|