blob: 793ab9fac693c3aefe44b06f173a1a608addb56c [file] [log] [blame]
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +00001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
David Pu70f65972019-03-18 15:14:49 -07003 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +00004 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +00008#ifndef RAS_H
9#define RAS_H
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000010
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010011#define ERR_HANDLER_VERSION 1U
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000012
13/* Error record access mechanism */
14#define ERR_ACCESS_SYSREG 0
15#define ERR_ACCESS_MEMMAP 1
16
17/*
18 * Register all error records on the platform.
19 *
20 * This macro must be used in the same file as the array of error record info
21 * are declared. Only then would ARRAY_SIZE() yield a meaningful value.
22 */
23#define REGISTER_ERR_RECORD_INFO(_records) \
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010024 const struct err_record_mapping err_record_mappings = { \
25 .err_records = (_records), \
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000026 .num_err_records = ARRAY_SIZE(_records), \
27 }
28
29/* Error record info iterator */
30#define for_each_err_record_info(_i, _info) \
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010031 for ((_i) = 0, (_info) = err_record_mappings.err_records; \
32 (_i) < err_record_mappings.num_err_records; \
33 (_i)++, (_info)++)
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000034
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010035#define ERR_RECORD_COMMON_(_probe, _handler, _aux) \
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000036 .probe = _probe, \
37 .handler = _handler, \
38 .aux_data = _aux,
39
40#define ERR_RECORD_SYSREG_V1(_idx_start, _num_idx, _probe, _handler, _aux) \
41 { \
42 .version = 1, \
43 .sysreg.idx_start = _idx_start, \
44 .sysreg.num_idx = _num_idx, \
45 .access = ERR_ACCESS_SYSREG, \
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010046 ERR_RECORD_COMMON_(_probe, _handler, _aux) \
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000047 }
48
49#define ERR_RECORD_MEMMAP_V1(_base_addr, _size_num_k, _probe, _handler, _aux) \
50 { \
51 .version = 1, \
52 .memmap.base_addr = _base_addr, \
53 .memmap.size_num_k = _size_num_k, \
54 .access = ERR_ACCESS_MEMMAP, \
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010055 ERR_RECORD_COMMON_(_probe, _handler, _aux) \
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000056 }
57
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +000058/*
59 * Macro to be used to name and declare an array of RAS interrupts along with
60 * their handlers.
61 *
62 * This macro must be used in the same file as the array of interrupts are
63 * declared. Only then would ARRAY_SIZE() yield a meaningful value. Also, the
64 * array is expected to be sorted in the increasing order of interrupt number.
65 */
66#define REGISTER_RAS_INTERRUPTS(_array) \
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010067 const struct ras_interrupt_mapping ras_interrupt_mappings = { \
68 .intrs = (_array), \
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +000069 .num_intrs = ARRAY_SIZE(_array), \
70 }
71
Julius Werner53456fc2019-07-09 13:49:11 -070072#ifndef __ASSEMBLER__
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000073
74#include <assert.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000075
76#include <lib/extensions/ras_arch.h>
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000077
78struct err_record_info;
79
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +000080struct ras_interrupt {
81 /* Interrupt number, and the associated error record info */
82 unsigned int intr_number;
83 struct err_record_info *err_record;
84 void *cookie;
85};
86
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000087/* Function to probe a error record group for error */
88typedef int (*err_record_probe_t)(const struct err_record_info *info,
89 int *probe_data);
90
91/* Data passed to error record group handler */
92struct err_handler_data {
93 /* Info passed on from top-level exception handler */
94 uint64_t flags;
95 void *cookie;
96 void *handle;
97
98 /* Data structure version */
99 unsigned int version;
100
101 /* Reason for EA: one the ERROR_* constants */
102 unsigned int ea_reason;
103
104 /*
105 * For EAs received at vector, the value read from ESR; for an EA
106 * synchronized by ESB, the value of DISR.
107 */
108 uint32_t syndrome;
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000109
Antonio Nino Diaz56b68ad2019-02-28 13:35:21 +0000110 /* For errors signalled via interrupt, the raw interrupt ID; otherwise, 0. */
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000111 unsigned int interrupt;
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000112};
113
114/* Function to handle error from an error record group */
115typedef int (*err_record_handler_t)(const struct err_record_info *info,
116 int probe_data, const struct err_handler_data *const data);
117
118/* Error record information */
119struct err_record_info {
120 /* Function to probe error record group for errors */
121 err_record_probe_t probe;
122
123 /* Function to handle error record group errors */
124 err_record_handler_t handler;
125
126 /* Opaque group-specific data */
127 void *aux_data;
128
129 /* Additional information for Standard Error Records */
130 union {
131 struct {
132 /*
Antonio Nino Diaz56b68ad2019-02-28 13:35:21 +0000133 * For a group accessed via memory-mapped register,
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000134 * base address of the page hosting error records, and
135 * the size of the record group.
136 */
137 uintptr_t base_addr;
138
139 /* Size of group in number of KBs */
140 unsigned int size_num_k;
141 } memmap;
142
143 struct {
144 /*
Antonio Nino Diaz56b68ad2019-02-28 13:35:21 +0000145 * For error records accessed via system register, index of
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000146 * the error record.
147 */
148 unsigned int idx_start;
149 unsigned int num_idx;
150 } sysreg;
151 };
152
153 /* Data structure version */
154 unsigned int version;
155
156 /* Error record access mechanism */
157 unsigned int access:1;
158};
159
160struct err_record_mapping {
161 struct err_record_info *err_records;
162 size_t num_err_records;
163};
164
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000165struct ras_interrupt_mapping {
166 struct ras_interrupt *intrs;
167 size_t num_intrs;
168};
169
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +0100170extern const struct err_record_mapping err_record_mappings;
171extern const struct ras_interrupt_mapping ras_interrupt_mappings;
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000172
173
174/*
175 * Helper functions to probe memory-mapped and system registers implemented in
176 * Standard Error Record format
177 */
178static inline int ras_err_ser_probe_memmap(const struct err_record_info *info,
179 int *probe_data)
180{
181 assert(info->version == ERR_HANDLER_VERSION);
182
183 return ser_probe_memmap(info->memmap.base_addr, info->memmap.size_num_k,
184 probe_data);
185}
186
187static inline int ras_err_ser_probe_sysreg(const struct err_record_info *info,
188 int *probe_data)
189{
190 assert(info->version == ERR_HANDLER_VERSION);
191
192 return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx,
193 probe_data);
194}
195
David Pu70f65972019-03-18 15:14:49 -0700196const char *ras_serr_to_str(unsigned int serr);
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000197int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
198 void *handle, uint64_t flags);
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000199void ras_init(void);
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000200
Julius Werner53456fc2019-07-09 13:49:11 -0700201#endif /* __ASSEMBLER__ */
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +0000202
203#endif /* RAS_H */