xref: /rk3399_ARM-atf/include/lib/extensions/ras.h (revision 30a8d96e4689be30b2caeb23fd071fadd1ec87cd)
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_COMMON
8 #define RAS_COMMON
9 
10 #define ERR_HANDLER_VERSION	1U
11 
12 /* Error record access mechanism */
13 #define ERR_ACCESS_SYSREG	0
14 #define ERR_ACCESS_MEMMAP	1
15 
16 /*
17  * Register all error records on the platform.
18  *
19  * This macro must be used in the same file as the array of error record info
20  * are declared. Only then would ARRAY_SIZE() yield a meaningful value.
21  */
22 #define REGISTER_ERR_RECORD_INFO(_records) \
23 	const struct err_record_mapping err_record_mappings = { \
24 		.err_records = (_records), \
25 		.num_err_records = ARRAY_SIZE(_records), \
26 	}
27 
28 /* Error record info iterator */
29 #define for_each_err_record_info(_i, _info) \
30 	for ((_i) = 0, (_info) = err_record_mappings.err_records; \
31 		(_i) < err_record_mappings.num_err_records; \
32 		(_i)++, (_info)++)
33 
34 #define ERR_RECORD_COMMON_(_probe, _handler, _aux) \
35 	.probe = _probe, \
36 	.handler = _handler, \
37 	.aux_data = _aux,
38 
39 #define ERR_RECORD_SYSREG_V1(_idx_start, _num_idx, _probe, _handler, _aux) \
40 	{ \
41 		.version = 1, \
42 		.sysreg.idx_start = _idx_start, \
43 		.sysreg.num_idx = _num_idx, \
44 		.access = ERR_ACCESS_SYSREG, \
45 		ERR_RECORD_COMMON_(_probe, _handler, _aux) \
46 	}
47 
48 #define ERR_RECORD_MEMMAP_V1(_base_addr, _size_num_k, _probe, _handler, _aux) \
49 	{ \
50 		.version = 1, \
51 		.memmap.base_addr = _base_addr, \
52 		.memmap.size_num_k = _size_num_k, \
53 		.access = ERR_ACCESS_MEMMAP, \
54 		ERR_RECORD_COMMON_(_probe, _handler, _aux) \
55 	}
56 
57 /*
58  * Macro to be used to name and declare an array of RAS interrupts along with
59  * their handlers.
60  *
61  * This macro must be used in the same file as the array of interrupts are
62  * declared. Only then would ARRAY_SIZE() yield a meaningful value. Also, the
63  * array is expected to be sorted in the increasing order of interrupt number.
64  */
65 #define REGISTER_RAS_INTERRUPTS(_array) \
66 	const struct ras_interrupt_mapping ras_interrupt_mappings = { \
67 		.intrs = (_array), \
68 		.num_intrs = ARRAY_SIZE(_array), \
69 	}
70 
71 #ifndef __ASSEMBLY__
72 
73 #include <assert.h>
74 #include <ras_arch.h>
75 
76 struct err_record_info;
77 
78 struct ras_interrupt {
79 	/* Interrupt number, and the associated error record info */
80 	unsigned int intr_number;
81 	struct err_record_info *err_record;
82 	void *cookie;
83 };
84 
85 /* Function to probe a error record group for error */
86 typedef int (*err_record_probe_t)(const struct err_record_info *info,
87 		int *probe_data);
88 
89 /* Data passed to error record group handler */
90 struct err_handler_data {
91 	/* Info passed on from top-level exception handler */
92 	uint64_t flags;
93 	void *cookie;
94 	void *handle;
95 
96 	/* Data structure version */
97 	unsigned int version;
98 
99 	/* Reason for EA: one the ERROR_* constants */
100 	unsigned int ea_reason;
101 
102 	/*
103 	 * For EAs received at vector, the value read from ESR; for an EA
104 	 * synchronized by ESB, the value of DISR.
105 	 */
106 	uint32_t syndrome;
107 
108 	/* For errors signalled via. interrupt, the raw interrupt ID; otherwise, 0. */
109 	unsigned int interrupt;
110 };
111 
112 /* Function to handle error from an error record group */
113 typedef int (*err_record_handler_t)(const struct err_record_info *info,
114 		int probe_data, const struct err_handler_data *const data);
115 
116 /* Error record information */
117 struct err_record_info {
118 	/* Function to probe error record group for errors */
119 	err_record_probe_t probe;
120 
121 	/* Function to handle error record group errors */
122 	err_record_handler_t handler;
123 
124 	/* Opaque group-specific data */
125 	void *aux_data;
126 
127 	/* Additional information for Standard Error Records */
128 	union {
129 		struct {
130 			/*
131 			 * For a group accessed via. memory-mapped register,
132 			 * base address of the page hosting error records, and
133 			 * the size of the record group.
134 			 */
135 			uintptr_t base_addr;
136 
137 			/* Size of group in number of KBs */
138 			unsigned int size_num_k;
139 		} memmap;
140 
141 		struct {
142 			/*
143 			 * For error records accessed via. system register, index of
144 			 * the error record.
145 			 */
146 			unsigned int idx_start;
147 			unsigned int num_idx;
148 		} sysreg;
149 	};
150 
151 	/* Data structure version */
152 	unsigned int version;
153 
154 	/* Error record access mechanism */
155 	unsigned int access:1;
156 };
157 
158 struct err_record_mapping {
159 	struct err_record_info *err_records;
160 	size_t num_err_records;
161 };
162 
163 struct ras_interrupt_mapping {
164 	struct ras_interrupt *intrs;
165 	size_t num_intrs;
166 };
167 
168 extern const struct err_record_mapping err_record_mappings;
169 extern const struct ras_interrupt_mapping ras_interrupt_mappings;
170 
171 
172 /*
173  * Helper functions to probe memory-mapped and system registers implemented in
174  * Standard Error Record format
175  */
176 static inline int ras_err_ser_probe_memmap(const struct err_record_info *info,
177 		int *probe_data)
178 {
179 	assert(info->version == ERR_HANDLER_VERSION);
180 
181 	return ser_probe_memmap(info->memmap.base_addr, info->memmap.size_num_k,
182 		probe_data);
183 }
184 
185 static inline int ras_err_ser_probe_sysreg(const struct err_record_info *info,
186 		int *probe_data)
187 {
188 	assert(info->version == ERR_HANDLER_VERSION);
189 
190 	return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx,
191 			probe_data);
192 }
193 
194 int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
195 		void *handle, uint64_t flags);
196 void ras_init(void);
197 
198 #endif /* __ASSEMBLY__ */
199 #endif /* RAS_COMMON */
200