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