1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
4*54fd6939SJiyong Park *
5*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause
6*54fd6939SJiyong Park */
7*54fd6939SJiyong Park
8*54fd6939SJiyong Park #ifndef RAS_ARCH_H
9*54fd6939SJiyong Park #define RAS_ARCH_H
10*54fd6939SJiyong Park
11*54fd6939SJiyong Park /*
12*54fd6939SJiyong Park * Size of nodes implementing Standard Error Records - currently only 4k is
13*54fd6939SJiyong Park * supported.
14*54fd6939SJiyong Park */
15*54fd6939SJiyong Park #define STD_ERR_NODE_SIZE_NUM_K 4U
16*54fd6939SJiyong Park
17*54fd6939SJiyong Park /*
18*54fd6939SJiyong Park * Individual register offsets within an error record in Standard Error Record
19*54fd6939SJiyong Park * format when error records are accessed through memory-mapped registers.
20*54fd6939SJiyong Park */
21*54fd6939SJiyong Park #define ERR_FR(n) (0x0ULL + (64ULL * (n)))
22*54fd6939SJiyong Park #define ERR_CTLR(n) (0x8ULL + (64ULL * (n)))
23*54fd6939SJiyong Park #define ERR_STATUS(n) (0x10ULL + (64ULL * (n)))
24*54fd6939SJiyong Park #define ERR_ADDR(n) (0x18ULL + (64ULL * (n)))
25*54fd6939SJiyong Park #define ERR_MISC0(n) (0x20ULL + (64ULL * (n)))
26*54fd6939SJiyong Park #define ERR_MISC1(n) (0x28ULL + (64ULL * (n)))
27*54fd6939SJiyong Park
28*54fd6939SJiyong Park /* Group Status Register (ERR_STATUS) offset */
29*54fd6939SJiyong Park #define ERR_GSR(base, size_num_k, n) \
30*54fd6939SJiyong Park ((base) + (0x380ULL * (size_num_k)) + (8ULL * (n)))
31*54fd6939SJiyong Park
32*54fd6939SJiyong Park /* Management register offsets */
33*54fd6939SJiyong Park #define ERR_DEVID(base, size_num_k) \
34*54fd6939SJiyong Park ((base) + ((0x400ULL * (size_num_k)) - 0x100ULL) + 0xc8ULL)
35*54fd6939SJiyong Park
36*54fd6939SJiyong Park #define ERR_DEVID_MASK 0xffffUL
37*54fd6939SJiyong Park
38*54fd6939SJiyong Park /* Standard Error Record status register fields */
39*54fd6939SJiyong Park #define ERR_STATUS_AV_SHIFT 31
40*54fd6939SJiyong Park #define ERR_STATUS_AV_MASK U(0x1)
41*54fd6939SJiyong Park
42*54fd6939SJiyong Park #define ERR_STATUS_V_SHIFT 30
43*54fd6939SJiyong Park #define ERR_STATUS_V_MASK U(0x1)
44*54fd6939SJiyong Park
45*54fd6939SJiyong Park #define ERR_STATUS_UE_SHIFT 29
46*54fd6939SJiyong Park #define ERR_STATUS_UE_MASK U(0x1)
47*54fd6939SJiyong Park
48*54fd6939SJiyong Park #define ERR_STATUS_ER_SHIFT 28
49*54fd6939SJiyong Park #define ERR_STATUS_ER_MASK U(0x1)
50*54fd6939SJiyong Park
51*54fd6939SJiyong Park #define ERR_STATUS_OF_SHIFT 27
52*54fd6939SJiyong Park #define ERR_STATUS_OF_MASK U(0x1)
53*54fd6939SJiyong Park
54*54fd6939SJiyong Park #define ERR_STATUS_MV_SHIFT 26
55*54fd6939SJiyong Park #define ERR_STATUS_MV_MASK U(0x1)
56*54fd6939SJiyong Park
57*54fd6939SJiyong Park #define ERR_STATUS_CE_SHIFT 24
58*54fd6939SJiyong Park #define ERR_STATUS_CE_MASK U(0x3)
59*54fd6939SJiyong Park
60*54fd6939SJiyong Park #define ERR_STATUS_DE_SHIFT 23
61*54fd6939SJiyong Park #define ERR_STATUS_DE_MASK U(0x1)
62*54fd6939SJiyong Park
63*54fd6939SJiyong Park #define ERR_STATUS_PN_SHIFT 22
64*54fd6939SJiyong Park #define ERR_STATUS_PN_MASK U(0x1)
65*54fd6939SJiyong Park
66*54fd6939SJiyong Park #define ERR_STATUS_UET_SHIFT 20
67*54fd6939SJiyong Park #define ERR_STATUS_UET_MASK U(0x3)
68*54fd6939SJiyong Park
69*54fd6939SJiyong Park #define ERR_STATUS_IERR_SHIFT 8
70*54fd6939SJiyong Park #define ERR_STATUS_IERR_MASK U(0xff)
71*54fd6939SJiyong Park
72*54fd6939SJiyong Park #define ERR_STATUS_SERR_SHIFT 0
73*54fd6939SJiyong Park #define ERR_STATUS_SERR_MASK U(0xff)
74*54fd6939SJiyong Park
75*54fd6939SJiyong Park #define ERR_STATUS_GET_FIELD(_status, _field) \
76*54fd6939SJiyong Park (((_status) >> ERR_STATUS_ ##_field ##_SHIFT) & ERR_STATUS_ ##_field ##_MASK)
77*54fd6939SJiyong Park
78*54fd6939SJiyong Park #define ERR_STATUS_CLR_FIELD(_status, _field) \
79*54fd6939SJiyong Park (_status) &= ~(ERR_STATUS_ ##_field ##_MASK << ERR_STATUS_ ##_field ##_SHIFT)
80*54fd6939SJiyong Park
81*54fd6939SJiyong Park #define ERR_STATUS_SET_FIELD(_status, _field, _value) \
82*54fd6939SJiyong Park (_status) |= (((_value) & ERR_STATUS_ ##_field ##_MASK) << ERR_STATUS_ ##_field ##_SHIFT)
83*54fd6939SJiyong Park
84*54fd6939SJiyong Park #define ERR_STATUS_WRITE_FIELD(_status, _field, _value) do { \
85*54fd6939SJiyong Park ERR_STATUS_CLR_FIELD(_status, _field, _value); \
86*54fd6939SJiyong Park ERR_STATUS_SET_FIELD(_status, _field, _value); \
87*54fd6939SJiyong Park } while (0)
88*54fd6939SJiyong Park
89*54fd6939SJiyong Park
90*54fd6939SJiyong Park /* Standard Error Record control register fields */
91*54fd6939SJiyong Park #define ERR_CTLR_WDUI_SHIFT 11
92*54fd6939SJiyong Park #define ERR_CTLR_WDUI_MASK 0x1
93*54fd6939SJiyong Park
94*54fd6939SJiyong Park #define ERR_CTLR_RDUI_SHIFT 10
95*54fd6939SJiyong Park #define ERR_CTLR_RDUI_MASK 0x1
96*54fd6939SJiyong Park #define ERR_CTLR_DUI_SHIFT ERR_CTLR_RDUI_SHIFT
97*54fd6939SJiyong Park #define ERR_CTLR_DUI_MASK ERR_CTLR_RDUI_MASK
98*54fd6939SJiyong Park
99*54fd6939SJiyong Park #define ERR_CTLR_WCFI_SHIFT 9
100*54fd6939SJiyong Park #define ERR_CTLR_WCFI_MASK 0x1
101*54fd6939SJiyong Park
102*54fd6939SJiyong Park #define ERR_CTLR_RCFI_SHIFT 8
103*54fd6939SJiyong Park #define ERR_CTLR_RCFI_MASK 0x1
104*54fd6939SJiyong Park #define ERR_CTLR_CFI_SHIFT ERR_CTLR_RCFI_SHIFT
105*54fd6939SJiyong Park #define ERR_CTLR_CFI_MASK ERR_CTLR_RCFI_MASK
106*54fd6939SJiyong Park
107*54fd6939SJiyong Park #define ERR_CTLR_WUE_SHIFT 7
108*54fd6939SJiyong Park #define ERR_CTLR_WUE_MASK 0x1
109*54fd6939SJiyong Park
110*54fd6939SJiyong Park #define ERR_CTLR_WFI_SHIFT 6
111*54fd6939SJiyong Park #define ERR_CTLR_WFI_MASK 0x1
112*54fd6939SJiyong Park
113*54fd6939SJiyong Park #define ERR_CTLR_WUI_SHIFT 5
114*54fd6939SJiyong Park #define ERR_CTLR_WUI_MASK 0x1
115*54fd6939SJiyong Park
116*54fd6939SJiyong Park #define ERR_CTLR_RUE_SHIFT 4
117*54fd6939SJiyong Park #define ERR_CTLR_RUE_MASK 0x1
118*54fd6939SJiyong Park #define ERR_CTLR_UE_SHIFT ERR_CTLR_RUE_SHIFT
119*54fd6939SJiyong Park #define ERR_CTLR_UE_MASK ERR_CTLR_RUE_MASK
120*54fd6939SJiyong Park
121*54fd6939SJiyong Park #define ERR_CTLR_RFI_SHIFT 3
122*54fd6939SJiyong Park #define ERR_CTLR_RFI_MASK 0x1
123*54fd6939SJiyong Park #define ERR_CTLR_FI_SHIFT ERR_CTLR_RFI_SHIFT
124*54fd6939SJiyong Park #define ERR_CTLR_FI_MASK ERR_CTLR_RFI_MASK
125*54fd6939SJiyong Park
126*54fd6939SJiyong Park #define ERR_CTLR_RUI_SHIFT 2
127*54fd6939SJiyong Park #define ERR_CTLR_RUI_MASK 0x1
128*54fd6939SJiyong Park #define ERR_CTLR_UI_SHIFT ERR_CTLR_RUI_SHIFT
129*54fd6939SJiyong Park #define ERR_CTLR_UI_MASK ERR_CTLR_RUI_MASK
130*54fd6939SJiyong Park
131*54fd6939SJiyong Park #define ERR_CTLR_ED_SHIFT 0
132*54fd6939SJiyong Park #define ERR_CTLR_ED_MASK 0x1
133*54fd6939SJiyong Park
134*54fd6939SJiyong Park #define ERR_CTLR_CLR_FIELD(_ctlr, _field) \
135*54fd6939SJiyong Park (_ctlr) &= ~(ERR_CTLR_ ##_field _MASK << ERR_CTLR_ ##_field ##_SHIFT)
136*54fd6939SJiyong Park
137*54fd6939SJiyong Park #define ERR_CTLR_SET_FIELD(_ctlr, _field, _value) \
138*54fd6939SJiyong Park (_ctlr) |= (((_value) & ERR_CTLR_ ##_field ##_MASK) << ERR_CTLR_ ##_field ##_SHIFT)
139*54fd6939SJiyong Park
140*54fd6939SJiyong Park #define ERR_CTLR_ENABLE_FIELD(_ctlr, _field) \
141*54fd6939SJiyong Park ERR_CTLR_SET_FIELD(_ctlr, _field, ERR_CTLR_ ##_field ##_MASK)
142*54fd6939SJiyong Park
143*54fd6939SJiyong Park /* Uncorrected error types for Asynchronous exceptions */
144*54fd6939SJiyong Park #define ERROR_STATUS_UET_UC 0x0 /* Uncontainable */
145*54fd6939SJiyong Park #define ERROR_STATUS_UET_UEU 0x1 /* Unrecoverable */
146*54fd6939SJiyong Park #define ERROR_STATUS_UET_UEO 0x2 /* Restable */
147*54fd6939SJiyong Park #define ERROR_STATUS_UET_UER 0x3 /* Recoverable */
148*54fd6939SJiyong Park
149*54fd6939SJiyong Park /* Error types for Synchronous exceptions */
150*54fd6939SJiyong Park #define ERROR_STATUS_SET_UER 0x0 /* Recoverable */
151*54fd6939SJiyong Park #define ERROR_STATUS_SET_UEO 0x1 /* Restable */
152*54fd6939SJiyong Park #define ERROR_STATUS_SET_UC 0x2 /* Uncontainable */
153*54fd6939SJiyong Park #define ERROR_STATUS_SET_CE 0x3 /* Corrected */
154*54fd6939SJiyong Park
155*54fd6939SJiyong Park /* Number of architecturally-defined primary error codes */
156*54fd6939SJiyong Park #define ERROR_STATUS_NUM_SERR U(22)
157*54fd6939SJiyong Park
158*54fd6939SJiyong Park /* Implementation Defined Syndrome bit in ESR */
159*54fd6939SJiyong Park #define SERROR_IDS_BIT U(24)
160*54fd6939SJiyong Park
161*54fd6939SJiyong Park /*
162*54fd6939SJiyong Park * Asynchronous Error Type in exception syndrome. The field has same values in
163*54fd6939SJiyong Park * both DISR_EL1 and ESR_EL3 for SError.
164*54fd6939SJiyong Park */
165*54fd6939SJiyong Park #define EABORT_AET_SHIFT U(10)
166*54fd6939SJiyong Park #define EABORT_AET_WIDTH U(3)
167*54fd6939SJiyong Park #define EABORT_AET_MASK U(0x7)
168*54fd6939SJiyong Park
169*54fd6939SJiyong Park /* DFSC field in Asynchronous exception syndrome */
170*54fd6939SJiyong Park #define EABORT_DFSC_SHIFT U(0)
171*54fd6939SJiyong Park #define EABORT_DFSC_WIDTH U(6)
172*54fd6939SJiyong Park #define EABORT_DFSC_MASK U(0x3f)
173*54fd6939SJiyong Park
174*54fd6939SJiyong Park /* Synchronous Error Type in exception syndrome. */
175*54fd6939SJiyong Park #define EABORT_SET_SHIFT U(11)
176*54fd6939SJiyong Park #define EABORT_SET_WIDTH U(2)
177*54fd6939SJiyong Park #define EABORT_SET_MASK U(0x3)
178*54fd6939SJiyong Park
179*54fd6939SJiyong Park /* DFSC code for SErrors */
180*54fd6939SJiyong Park #define DFSC_SERROR 0x11
181*54fd6939SJiyong Park
182*54fd6939SJiyong Park /* I/DFSC code for synchronous external abort */
183*54fd6939SJiyong Park #define SYNC_EA_FSC 0x10
184*54fd6939SJiyong Park
185*54fd6939SJiyong Park #ifndef __ASSEMBLER__
186*54fd6939SJiyong Park
187*54fd6939SJiyong Park #include <arch.h>
188*54fd6939SJiyong Park #include <arch_helpers.h>
189*54fd6939SJiyong Park #include <assert.h>
190*54fd6939SJiyong Park #include <context.h>
191*54fd6939SJiyong Park #include <lib/mmio.h>
192*54fd6939SJiyong Park #include <stdint.h>
193*54fd6939SJiyong Park
194*54fd6939SJiyong Park /*
195*54fd6939SJiyong Park * Standard Error Record accessors for memory-mapped registers.
196*54fd6939SJiyong Park */
197*54fd6939SJiyong Park
ser_get_feature(uintptr_t base,unsigned int idx)198*54fd6939SJiyong Park static inline uint64_t ser_get_feature(uintptr_t base, unsigned int idx)
199*54fd6939SJiyong Park {
200*54fd6939SJiyong Park return mmio_read_64(base + ERR_FR(idx));
201*54fd6939SJiyong Park }
202*54fd6939SJiyong Park
ser_get_control(uintptr_t base,unsigned int idx)203*54fd6939SJiyong Park static inline uint64_t ser_get_control(uintptr_t base, unsigned int idx)
204*54fd6939SJiyong Park {
205*54fd6939SJiyong Park return mmio_read_64(base + ERR_CTLR(idx));
206*54fd6939SJiyong Park }
207*54fd6939SJiyong Park
ser_get_status(uintptr_t base,unsigned int idx)208*54fd6939SJiyong Park static inline uint64_t ser_get_status(uintptr_t base, unsigned int idx)
209*54fd6939SJiyong Park {
210*54fd6939SJiyong Park return mmio_read_64(base + ERR_STATUS(idx));
211*54fd6939SJiyong Park }
212*54fd6939SJiyong Park
213*54fd6939SJiyong Park /*
214*54fd6939SJiyong Park * Error handling agent would write to the status register to clear an
215*54fd6939SJiyong Park * identified/handled error. Most fields in the status register are
216*54fd6939SJiyong Park * conditional write-one-to-clear.
217*54fd6939SJiyong Park *
218*54fd6939SJiyong Park * Typically, to clear the status, it suffices to write back the same value
219*54fd6939SJiyong Park * previously read. However, if there were new, higher-priority errors recorded
220*54fd6939SJiyong Park * on the node since status was last read, writing read value won't clear the
221*54fd6939SJiyong Park * status. Therefore, an error handling agent must wait on and verify the status
222*54fd6939SJiyong Park * has indeed been cleared.
223*54fd6939SJiyong Park */
ser_set_status(uintptr_t base,unsigned int idx,uint64_t status)224*54fd6939SJiyong Park static inline void ser_set_status(uintptr_t base, unsigned int idx,
225*54fd6939SJiyong Park uint64_t status)
226*54fd6939SJiyong Park {
227*54fd6939SJiyong Park mmio_write_64(base + ERR_STATUS(idx), status);
228*54fd6939SJiyong Park }
229*54fd6939SJiyong Park
ser_get_addr(uintptr_t base,unsigned int idx)230*54fd6939SJiyong Park static inline uint64_t ser_get_addr(uintptr_t base, unsigned int idx)
231*54fd6939SJiyong Park {
232*54fd6939SJiyong Park return mmio_read_64(base + ERR_ADDR(idx));
233*54fd6939SJiyong Park }
234*54fd6939SJiyong Park
ser_get_misc0(uintptr_t base,unsigned int idx)235*54fd6939SJiyong Park static inline uint64_t ser_get_misc0(uintptr_t base, unsigned int idx)
236*54fd6939SJiyong Park {
237*54fd6939SJiyong Park return mmio_read_64(base + ERR_MISC0(idx));
238*54fd6939SJiyong Park }
239*54fd6939SJiyong Park
ser_get_misc1(uintptr_t base,unsigned int idx)240*54fd6939SJiyong Park static inline uint64_t ser_get_misc1(uintptr_t base, unsigned int idx)
241*54fd6939SJiyong Park {
242*54fd6939SJiyong Park return mmio_read_64(base + ERR_MISC1(idx));
243*54fd6939SJiyong Park }
244*54fd6939SJiyong Park
245*54fd6939SJiyong Park
246*54fd6939SJiyong Park /*
247*54fd6939SJiyong Park * Standard Error Record helpers for System registers.
248*54fd6939SJiyong Park */
ser_sys_select_record(unsigned int idx)249*54fd6939SJiyong Park static inline void ser_sys_select_record(unsigned int idx)
250*54fd6939SJiyong Park {
251*54fd6939SJiyong Park unsigned int max_idx __unused =
252*54fd6939SJiyong Park (unsigned int) read_erridr_el1() & ERRIDR_MASK;
253*54fd6939SJiyong Park
254*54fd6939SJiyong Park assert(idx < max_idx);
255*54fd6939SJiyong Park
256*54fd6939SJiyong Park write_errselr_el1(idx);
257*54fd6939SJiyong Park isb();
258*54fd6939SJiyong Park }
259*54fd6939SJiyong Park
260*54fd6939SJiyong Park /* Library functions to probe Standard Error Record */
261*54fd6939SJiyong Park int ser_probe_memmap(uintptr_t base, unsigned int size_num_k, int *probe_data);
262*54fd6939SJiyong Park int ser_probe_sysreg(unsigned int idx_start, unsigned int num_idx, int *probe_data);
263*54fd6939SJiyong Park #endif /* __ASSEMBLER__ */
264*54fd6939SJiyong Park
265*54fd6939SJiyong Park #endif /* RAS_ARCH_H */
266