ras.h 5.18 KB
Newer Older
1
2
/*
 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3
 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
4
5
6
7
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

8
9
#ifndef RAS_H
#define RAS_H
10

Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
11
#define ERR_HANDLER_VERSION	1U
12
13
14
15
16
17
18
19
20
21
22
23

/* Error record access mechanism */
#define ERR_ACCESS_SYSREG	0
#define ERR_ACCESS_MEMMAP	1

/*
 * Register all error records on the platform.
 *
 * This macro must be used in the same file as the array of error record info
 * are declared. Only then would ARRAY_SIZE() yield a meaningful value.
 */
#define REGISTER_ERR_RECORD_INFO(_records) \
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
24
25
	const struct err_record_mapping err_record_mappings = { \
		.err_records = (_records), \
26
27
28
29
30
		.num_err_records = ARRAY_SIZE(_records), \
	}

/* Error record info iterator */
#define for_each_err_record_info(_i, _info) \
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
31
32
33
	for ((_i) = 0, (_info) = err_record_mappings.err_records; \
		(_i) < err_record_mappings.num_err_records; \
		(_i)++, (_info)++)
34

Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
35
#define ERR_RECORD_COMMON_(_probe, _handler, _aux) \
36
37
38
39
40
41
42
43
44
45
	.probe = _probe, \
	.handler = _handler, \
	.aux_data = _aux,

#define ERR_RECORD_SYSREG_V1(_idx_start, _num_idx, _probe, _handler, _aux) \
	{ \
		.version = 1, \
		.sysreg.idx_start = _idx_start, \
		.sysreg.num_idx = _num_idx, \
		.access = ERR_ACCESS_SYSREG, \
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
46
		ERR_RECORD_COMMON_(_probe, _handler, _aux) \
47
48
49
50
51
52
53
54
	}

#define ERR_RECORD_MEMMAP_V1(_base_addr, _size_num_k, _probe, _handler, _aux) \
	{ \
		.version = 1, \
		.memmap.base_addr = _base_addr, \
		.memmap.size_num_k = _size_num_k, \
		.access = ERR_ACCESS_MEMMAP, \
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
55
		ERR_RECORD_COMMON_(_probe, _handler, _aux) \
56
57
	}

58
59
60
61
62
63
64
65
66
/*
 * Macro to be used to name and declare an array of RAS interrupts along with
 * their handlers.
 *
 * This macro must be used in the same file as the array of interrupts are
 * declared. Only then would ARRAY_SIZE() yield a meaningful value. Also, the
 * array is expected to be sorted in the increasing order of interrupt number.
 */
#define REGISTER_RAS_INTERRUPTS(_array) \
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
67
68
	const struct ras_interrupt_mapping ras_interrupt_mappings = { \
		.intrs = (_array), \
69
70
71
		.num_intrs = ARRAY_SIZE(_array), \
	}

72
#ifndef __ASSEMBLER__
73
74

#include <assert.h>
75
76

#include <lib/extensions/ras_arch.h>
77
78
79

struct err_record_info;

80
81
82
83
84
85
86
struct ras_interrupt {
	/* Interrupt number, and the associated error record info */
	unsigned int intr_number;
	struct err_record_info *err_record;
	void *cookie;
};

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* Function to probe a error record group for error */
typedef int (*err_record_probe_t)(const struct err_record_info *info,
		int *probe_data);

/* Data passed to error record group handler */
struct err_handler_data {
	/* Info passed on from top-level exception handler */
	uint64_t flags;
	void *cookie;
	void *handle;

	/* Data structure version */
	unsigned int version;

	/* Reason for EA: one the ERROR_* constants */
	unsigned int ea_reason;

	/*
	 * For EAs received at vector, the value read from ESR; for an EA
	 * synchronized by ESB, the value of DISR.
	 */
	uint32_t syndrome;
109

110
	/* For errors signalled via interrupt, the raw interrupt ID; otherwise, 0. */
111
	unsigned int interrupt;
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
};

/* Function to handle error from an error record group */
typedef int (*err_record_handler_t)(const struct err_record_info *info,
		int probe_data, const struct err_handler_data *const data);

/* Error record information */
struct err_record_info {
	/* Function to probe error record group for errors */
	err_record_probe_t probe;

	/* Function to handle error record group errors */
	err_record_handler_t handler;

	/* Opaque group-specific data */
	void *aux_data;

	/* Additional information for Standard Error Records */
	union {
		struct {
			/*
133
			 * For a group accessed via memory-mapped register,
134
135
136
137
138
139
140
141
142
143
144
			 * base address of the page hosting error records, and
			 * the size of the record group.
			 */
			uintptr_t base_addr;

			/* Size of group in number of KBs */
			unsigned int size_num_k;
		} memmap;

		struct {
			/*
145
			 * For error records accessed via system register, index of
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
			 * the error record.
			 */
			unsigned int idx_start;
			unsigned int num_idx;
		} sysreg;
	};

	/* Data structure version */
	unsigned int version;

	/* Error record access mechanism */
	unsigned int access:1;
};

struct err_record_mapping {
	struct err_record_info *err_records;
	size_t num_err_records;
};

165
166
167
168
169
struct ras_interrupt_mapping {
	struct ras_interrupt *intrs;
	size_t num_intrs;
};

Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
170
171
extern const struct err_record_mapping err_record_mappings;
extern const struct ras_interrupt_mapping ras_interrupt_mappings;
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195


/*
 * Helper functions to probe memory-mapped and system registers implemented in
 * Standard Error Record format
 */
static inline int ras_err_ser_probe_memmap(const struct err_record_info *info,
		int *probe_data)
{
	assert(info->version == ERR_HANDLER_VERSION);

	return ser_probe_memmap(info->memmap.base_addr, info->memmap.size_num_k,
		probe_data);
}

static inline int ras_err_ser_probe_sysreg(const struct err_record_info *info,
		int *probe_data)
{
	assert(info->version == ERR_HANDLER_VERSION);

	return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx,
			probe_data);
}

196
const char *ras_serr_to_str(unsigned int serr);
197
198
int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
		void *handle, uint64_t flags);
199
void ras_init(void);
200

201
#endif /* __ASSEMBLER__ */
202
203

#endif /* RAS_H */