xref: /rk3399_ARM-atf/include/lib/extensions/ras.h (revision 362599eca43a0e97b1bd38bfc96d277d86faa3d4)
1*362599ecSJeenu Viswambharan /*
2*362599ecSJeenu Viswambharan  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3*362599ecSJeenu Viswambharan  *
4*362599ecSJeenu Viswambharan  * SPDX-License-Identifier: BSD-3-Clause
5*362599ecSJeenu Viswambharan  */
6*362599ecSJeenu Viswambharan 
7*362599ecSJeenu Viswambharan #ifndef __RAS_COMMON__
8*362599ecSJeenu Viswambharan #define __RAS_COMMON__
9*362599ecSJeenu Viswambharan 
10*362599ecSJeenu Viswambharan #define ERR_HANDLER_VERSION	1
11*362599ecSJeenu Viswambharan 
12*362599ecSJeenu Viswambharan /* Error record access mechanism */
13*362599ecSJeenu Viswambharan #define ERR_ACCESS_SYSREG	0
14*362599ecSJeenu Viswambharan #define ERR_ACCESS_MEMMAP	1
15*362599ecSJeenu Viswambharan 
16*362599ecSJeenu Viswambharan /*
17*362599ecSJeenu Viswambharan  * Register all error records on the platform.
18*362599ecSJeenu Viswambharan  *
19*362599ecSJeenu Viswambharan  * This macro must be used in the same file as the array of error record info
20*362599ecSJeenu Viswambharan  * are declared. Only then would ARRAY_SIZE() yield a meaningful value.
21*362599ecSJeenu Viswambharan  */
22*362599ecSJeenu Viswambharan #define REGISTER_ERR_RECORD_INFO(_records) \
23*362599ecSJeenu Viswambharan 	const struct err_record_mapping err_record_mapping = { \
24*362599ecSJeenu Viswambharan 		.err_records = _records, \
25*362599ecSJeenu Viswambharan 		.num_err_records = ARRAY_SIZE(_records), \
26*362599ecSJeenu Viswambharan 	}
27*362599ecSJeenu Viswambharan 
28*362599ecSJeenu Viswambharan /* Error record info iterator */
29*362599ecSJeenu Viswambharan #define for_each_err_record_info(_i, _info) \
30*362599ecSJeenu Viswambharan 	for (_i = 0, _info = err_record_mapping.err_records; \
31*362599ecSJeenu Viswambharan 		_i < err_record_mapping.num_err_records; \
32*362599ecSJeenu Viswambharan 		_i++, _info++)
33*362599ecSJeenu Viswambharan 
34*362599ecSJeenu Viswambharan #define _ERR_RECORD_COMMON(_probe, _handler, _aux) \
35*362599ecSJeenu Viswambharan 	.probe = _probe, \
36*362599ecSJeenu Viswambharan 	.handler = _handler, \
37*362599ecSJeenu Viswambharan 	.aux_data = _aux,
38*362599ecSJeenu Viswambharan 
39*362599ecSJeenu Viswambharan #define ERR_RECORD_SYSREG_V1(_idx_start, _num_idx, _probe, _handler, _aux) \
40*362599ecSJeenu Viswambharan 	{ \
41*362599ecSJeenu Viswambharan 		.version = 1, \
42*362599ecSJeenu Viswambharan 		.sysreg.idx_start = _idx_start, \
43*362599ecSJeenu Viswambharan 		.sysreg.num_idx = _num_idx, \
44*362599ecSJeenu Viswambharan 		.access = ERR_ACCESS_SYSREG, \
45*362599ecSJeenu Viswambharan 		_ERR_RECORD_COMMON(_probe, _handler, _aux) \
46*362599ecSJeenu Viswambharan 	}
47*362599ecSJeenu Viswambharan 
48*362599ecSJeenu Viswambharan #define ERR_RECORD_MEMMAP_V1(_base_addr, _size_num_k, _probe, _handler, _aux) \
49*362599ecSJeenu Viswambharan 	{ \
50*362599ecSJeenu Viswambharan 		.version = 1, \
51*362599ecSJeenu Viswambharan 		.memmap.base_addr = _base_addr, \
52*362599ecSJeenu Viswambharan 		.memmap.size_num_k = _size_num_k, \
53*362599ecSJeenu Viswambharan 		.access = ERR_ACCESS_MEMMAP, \
54*362599ecSJeenu Viswambharan 		_ERR_RECORD_COMMON(_probe, _handler, _aux) \
55*362599ecSJeenu Viswambharan 	}
56*362599ecSJeenu Viswambharan 
57*362599ecSJeenu Viswambharan #ifndef __ASSEMBLY__
58*362599ecSJeenu Viswambharan 
59*362599ecSJeenu Viswambharan #include <assert.h>
60*362599ecSJeenu Viswambharan #include <ras_arch.h>
61*362599ecSJeenu Viswambharan 
62*362599ecSJeenu Viswambharan struct err_record_info;
63*362599ecSJeenu Viswambharan 
64*362599ecSJeenu Viswambharan /* Function to probe a error record group for error */
65*362599ecSJeenu Viswambharan typedef int (*err_record_probe_t)(const struct err_record_info *info,
66*362599ecSJeenu Viswambharan 		int *probe_data);
67*362599ecSJeenu Viswambharan 
68*362599ecSJeenu Viswambharan /* Data passed to error record group handler */
69*362599ecSJeenu Viswambharan struct err_handler_data {
70*362599ecSJeenu Viswambharan 	/* Info passed on from top-level exception handler */
71*362599ecSJeenu Viswambharan 	uint64_t flags;
72*362599ecSJeenu Viswambharan 	void *cookie;
73*362599ecSJeenu Viswambharan 	void *handle;
74*362599ecSJeenu Viswambharan 
75*362599ecSJeenu Viswambharan 	/* Data structure version */
76*362599ecSJeenu Viswambharan 	unsigned int version;
77*362599ecSJeenu Viswambharan 
78*362599ecSJeenu Viswambharan 	/* Reason for EA: one the ERROR_* constants */
79*362599ecSJeenu Viswambharan 	unsigned int ea_reason;
80*362599ecSJeenu Viswambharan 
81*362599ecSJeenu Viswambharan 	/*
82*362599ecSJeenu Viswambharan 	 * For EAs received at vector, the value read from ESR; for an EA
83*362599ecSJeenu Viswambharan 	 * synchronized by ESB, the value of DISR.
84*362599ecSJeenu Viswambharan 	 */
85*362599ecSJeenu Viswambharan 	uint32_t syndrome;
86*362599ecSJeenu Viswambharan };
87*362599ecSJeenu Viswambharan 
88*362599ecSJeenu Viswambharan /* Function to handle error from an error record group */
89*362599ecSJeenu Viswambharan typedef int (*err_record_handler_t)(const struct err_record_info *info,
90*362599ecSJeenu Viswambharan 		int probe_data, const struct err_handler_data *const data);
91*362599ecSJeenu Viswambharan 
92*362599ecSJeenu Viswambharan /* Error record information */
93*362599ecSJeenu Viswambharan struct err_record_info {
94*362599ecSJeenu Viswambharan 	/* Function to probe error record group for errors */
95*362599ecSJeenu Viswambharan 	err_record_probe_t probe;
96*362599ecSJeenu Viswambharan 
97*362599ecSJeenu Viswambharan 	/* Function to handle error record group errors */
98*362599ecSJeenu Viswambharan 	err_record_handler_t handler;
99*362599ecSJeenu Viswambharan 
100*362599ecSJeenu Viswambharan 	/* Opaque group-specific data */
101*362599ecSJeenu Viswambharan 	void *aux_data;
102*362599ecSJeenu Viswambharan 
103*362599ecSJeenu Viswambharan 	/* Additional information for Standard Error Records */
104*362599ecSJeenu Viswambharan 	union {
105*362599ecSJeenu Viswambharan 		struct {
106*362599ecSJeenu Viswambharan 			/*
107*362599ecSJeenu Viswambharan 			 * For a group accessed via. memory-mapped register,
108*362599ecSJeenu Viswambharan 			 * base address of the page hosting error records, and
109*362599ecSJeenu Viswambharan 			 * the size of the record group.
110*362599ecSJeenu Viswambharan 			 */
111*362599ecSJeenu Viswambharan 			uintptr_t base_addr;
112*362599ecSJeenu Viswambharan 
113*362599ecSJeenu Viswambharan 			/* Size of group in number of KBs */
114*362599ecSJeenu Viswambharan 			unsigned int size_num_k;
115*362599ecSJeenu Viswambharan 		} memmap;
116*362599ecSJeenu Viswambharan 
117*362599ecSJeenu Viswambharan 		struct {
118*362599ecSJeenu Viswambharan 			/*
119*362599ecSJeenu Viswambharan 			 * For error records accessed via. system register, index of
120*362599ecSJeenu Viswambharan 			 * the error record.
121*362599ecSJeenu Viswambharan 			 */
122*362599ecSJeenu Viswambharan 			unsigned int idx_start;
123*362599ecSJeenu Viswambharan 			unsigned int num_idx;
124*362599ecSJeenu Viswambharan 		} sysreg;
125*362599ecSJeenu Viswambharan 	};
126*362599ecSJeenu Viswambharan 
127*362599ecSJeenu Viswambharan 	/* Data structure version */
128*362599ecSJeenu Viswambharan 	unsigned int version;
129*362599ecSJeenu Viswambharan 
130*362599ecSJeenu Viswambharan 	/* Error record access mechanism */
131*362599ecSJeenu Viswambharan 	unsigned int access:1;
132*362599ecSJeenu Viswambharan };
133*362599ecSJeenu Viswambharan 
134*362599ecSJeenu Viswambharan struct err_record_mapping {
135*362599ecSJeenu Viswambharan 	struct err_record_info *err_records;
136*362599ecSJeenu Viswambharan 	size_t num_err_records;
137*362599ecSJeenu Viswambharan };
138*362599ecSJeenu Viswambharan 
139*362599ecSJeenu Viswambharan extern const struct err_record_mapping err_record_mapping;
140*362599ecSJeenu Viswambharan 
141*362599ecSJeenu Viswambharan 
142*362599ecSJeenu Viswambharan /*
143*362599ecSJeenu Viswambharan  * Helper functions to probe memory-mapped and system registers implemented in
144*362599ecSJeenu Viswambharan  * Standard Error Record format
145*362599ecSJeenu Viswambharan  */
146*362599ecSJeenu Viswambharan static inline int ras_err_ser_probe_memmap(const struct err_record_info *info,
147*362599ecSJeenu Viswambharan 		int *probe_data)
148*362599ecSJeenu Viswambharan {
149*362599ecSJeenu Viswambharan 	assert(info->version == ERR_HANDLER_VERSION);
150*362599ecSJeenu Viswambharan 
151*362599ecSJeenu Viswambharan 	return ser_probe_memmap(info->memmap.base_addr, info->memmap.size_num_k,
152*362599ecSJeenu Viswambharan 		probe_data);
153*362599ecSJeenu Viswambharan }
154*362599ecSJeenu Viswambharan 
155*362599ecSJeenu Viswambharan static inline int ras_err_ser_probe_sysreg(const struct err_record_info *info,
156*362599ecSJeenu Viswambharan 		int *probe_data)
157*362599ecSJeenu Viswambharan {
158*362599ecSJeenu Viswambharan 	assert(info->version == ERR_HANDLER_VERSION);
159*362599ecSJeenu Viswambharan 
160*362599ecSJeenu Viswambharan 	return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx,
161*362599ecSJeenu Viswambharan 			probe_data);
162*362599ecSJeenu Viswambharan }
163*362599ecSJeenu Viswambharan 
164*362599ecSJeenu Viswambharan int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
165*362599ecSJeenu Viswambharan 		void *handle, uint64_t flags);
166*362599ecSJeenu Viswambharan 
167*362599ecSJeenu Viswambharan #endif /* __ASSEMBLY__ */
168*362599ecSJeenu Viswambharan #endif /* __RAS_COMMON__ */
169