blob: 4fc8f04b11d87e4cdd3db24101e69ce6a7e7805a [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
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +00007#ifndef RAS_H
8#define RAS_H
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +00009
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010010#define ERR_HANDLER_VERSION 1U
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000011
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) \
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010023 const struct err_record_mapping err_record_mappings = { \
24 .err_records = (_records), \
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000025 .num_err_records = ARRAY_SIZE(_records), \
26 }
27
28/* Error record info iterator */
29#define for_each_err_record_info(_i, _info) \
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010030 for ((_i) = 0, (_info) = err_record_mappings.err_records; \
31 (_i) < err_record_mappings.num_err_records; \
32 (_i)++, (_info)++)
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000033
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010034#define ERR_RECORD_COMMON_(_probe, _handler, _aux) \
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000035 .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, \
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010045 ERR_RECORD_COMMON_(_probe, _handler, _aux) \
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000046 }
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, \
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010054 ERR_RECORD_COMMON_(_probe, _handler, _aux) \
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000055 }
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) \
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +010066 const struct ras_interrupt_mapping ras_interrupt_mappings = { \
67 .intrs = (_array), \
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +000068 .num_intrs = ARRAY_SIZE(_array), \
69 }
70
Julius Werner53456fc2019-07-09 13:49:11 -070071#ifndef __ASSEMBLER__
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000072
73#include <assert.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000074
75#include <lib/extensions/ras_arch.h>
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000076
77struct err_record_info;
78
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +000079struct ras_interrupt {
80 /* Interrupt number, and the associated error record info */
81 unsigned int intr_number;
82 struct err_record_info *err_record;
83 void *cookie;
84};
85
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +000086/* Function to probe a error record group for error */
87typedef int (*err_record_probe_t)(const struct err_record_info *info,
88 int *probe_data);
89
90/* Data passed to error record group handler */
91struct err_handler_data {
92 /* Info passed on from top-level exception handler */
93 uint64_t flags;
94 void *cookie;
95 void *handle;
96
97 /* Data structure version */
98 unsigned int version;
99
100 /* Reason for EA: one the ERROR_* constants */
101 unsigned int ea_reason;
102
103 /*
104 * For EAs received at vector, the value read from ESR; for an EA
105 * synchronized by ESB, the value of DISR.
106 */
107 uint32_t syndrome;
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000108
Antonio Nino Diaz56b68ad2019-02-28 13:35:21 +0000109 /* For errors signalled via interrupt, the raw interrupt ID; otherwise, 0. */
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000110 unsigned int interrupt;
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000111};
112
113/* Function to handle error from an error record group */
114typedef int (*err_record_handler_t)(const struct err_record_info *info,
115 int probe_data, const struct err_handler_data *const data);
116
117/* Error record information */
118struct err_record_info {
119 /* Function to probe error record group for errors */
120 err_record_probe_t probe;
121
122 /* Function to handle error record group errors */
123 err_record_handler_t handler;
124
125 /* Opaque group-specific data */
126 void *aux_data;
127
128 /* Additional information for Standard Error Records */
129 union {
130 struct {
131 /*
Antonio Nino Diaz56b68ad2019-02-28 13:35:21 +0000132 * For a group accessed via memory-mapped register,
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000133 * base address of the page hosting error records, and
134 * the size of the record group.
135 */
136 uintptr_t base_addr;
137
138 /* Size of group in number of KBs */
139 unsigned int size_num_k;
140 } memmap;
141
142 struct {
143 /*
Antonio Nino Diaz56b68ad2019-02-28 13:35:21 +0000144 * For error records accessed via system register, index of
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000145 * the error record.
146 */
147 unsigned int idx_start;
148 unsigned int num_idx;
149 } sysreg;
150 };
151
152 /* Data structure version */
153 unsigned int version;
154
155 /* Error record access mechanism */
156 unsigned int access:1;
157};
158
159struct err_record_mapping {
160 struct err_record_info *err_records;
161 size_t num_err_records;
162};
163
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000164struct ras_interrupt_mapping {
165 struct ras_interrupt *intrs;
166 size_t num_intrs;
167};
168
Jeenu Viswambharan31ac01e2018-08-02 10:14:12 +0100169extern const struct err_record_mapping err_record_mappings;
170extern const struct ras_interrupt_mapping ras_interrupt_mappings;
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000171
172
173/*
174 * Helper functions to probe memory-mapped and system registers implemented in
175 * Standard Error Record format
176 */
177static inline int ras_err_ser_probe_memmap(const struct err_record_info *info,
178 int *probe_data)
179{
180 assert(info->version == ERR_HANDLER_VERSION);
181
182 return ser_probe_memmap(info->memmap.base_addr, info->memmap.size_num_k,
183 probe_data);
184}
185
186static inline int ras_err_ser_probe_sysreg(const struct err_record_info *info,
187 int *probe_data)
188{
189 assert(info->version == ERR_HANDLER_VERSION);
190
191 return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx,
192 probe_data);
193}
194
195int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
196 void *handle, uint64_t flags);
Jeenu Viswambharand86cc5b2017-12-12 10:34:58 +0000197void ras_init(void);
Jeenu Viswambharan2e2e8812017-12-08 15:38:21 +0000198
Julius Werner53456fc2019-07-09 13:49:11 -0700199#endif /* __ASSEMBLER__ */
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +0000200
201#endif /* RAS_H */