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