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