blob: f57fc3afd1c4190d4c7f577cb9f3c690cbe727a4 [file] [log] [blame]
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +00001/*
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 1
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_mapping = { \
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_mapping.err_records; \
31 _i < err_record_mapping.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
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +000057/*
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_mapping = { \
67 .intrs = _array, \
68 .num_intrs = ARRAY_SIZE(_array), \
69 }
70
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000071#ifndef __ASSEMBLY__
72
73#include <assert.h>
74#include <ras_arch.h>
75
76struct err_record_info;
77
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +000078struct 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
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000085/* Function to probe a error record group for error */
86typedef int (*err_record_probe_t)(const struct err_record_info *info,
87 int *probe_data);
88
89/* Data passed to error record group handler */
90struct 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;
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000107
108 /* For errors signalled via. interrupt, the raw interrupt ID; otherwise, 0. */
109 unsigned int interrupt;
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000110};
111
112/* Function to handle error from an error record group */
113typedef 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 */
117struct 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
158struct err_record_mapping {
159 struct err_record_info *err_records;
160 size_t num_err_records;
161};
162
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000163struct ras_interrupt_mapping {
164 struct ras_interrupt *intrs;
165 size_t num_intrs;
166};
167
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000168extern const struct err_record_mapping err_record_mapping;
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000169extern const struct ras_interrupt_mapping ras_interrupt_mapping;
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000170
171
172/*
173 * Helper functions to probe memory-mapped and system registers implemented in
174 * Standard Error Record format
175 */
176static 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
185static 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
194int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
195 void *handle, uint64_t flags);
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000196void ras_init(void);
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000197
198#endif /* __ASSEMBLY__ */
199#endif /* __RAS_COMMON__ */