1 /* 2 * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. 3 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef RAS_H 9 #define RAS_H 10 11 #define ERR_HANDLER_VERSION 1U 12 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) \ 24 const struct err_record_mapping err_record_mappings = { \ 25 .err_records = (_records), \ 26 .num_err_records = ARRAY_SIZE(_records), \ 27 } 28 29 /* Error record info iterator */ 30 #define for_each_err_record_info(_i, _info) \ 31 for ((_i) = 0, (_info) = err_record_mappings.err_records; \ 32 (_i) < err_record_mappings.num_err_records; \ 33 (_i)++, (_info)++) 34 35 #define ERR_RECORD_COMMON_(_probe, _handler, _aux) \ 36 .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, \ 46 ERR_RECORD_COMMON_(_probe, _handler, _aux) \ 47 } 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, \ 55 ERR_RECORD_COMMON_(_probe, _handler, _aux) \ 56 } 57 58 /* 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) \ 67 const struct ras_interrupt_mapping ras_interrupt_mappings = { \ 68 .intrs = (_array), \ 69 .num_intrs = ARRAY_SIZE(_array), \ 70 } 71 72 #ifndef __ASSEMBLER__ 73 74 #include <assert.h> 75 76 #include <lib/extensions/ras_arch.h> 77 78 struct err_record_info; 79 80 struct 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 87 /* Function to probe a error record group for error */ 88 typedef int (*err_record_probe_t)(const struct err_record_info *info, 89 int *probe_data); 90 91 /* Data passed to error record group handler */ 92 struct 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; 109 110 /* For errors signalled via interrupt, the raw interrupt ID; otherwise, 0. */ 111 unsigned int interrupt; 112 }; 113 114 /* Function to handle error from an error record group */ 115 typedef 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 */ 119 struct 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 /* 133 * For a group accessed via memory-mapped register, 134 * 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 /* 145 * For error records accessed via system register, index of 146 * 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 160 struct err_record_mapping { 161 struct err_record_info *err_records; 162 size_t num_err_records; 163 }; 164 165 struct ras_interrupt_mapping { 166 struct ras_interrupt *intrs; 167 size_t num_intrs; 168 }; 169 170 extern const struct err_record_mapping err_record_mappings; 171 extern const struct ras_interrupt_mapping ras_interrupt_mappings; 172 173 174 /* 175 * Helper functions to probe memory-mapped and system registers implemented in 176 * Standard Error Record format 177 */ 178 static 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 187 static 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 196 const char *ras_serr_to_str(unsigned int serr); 197 int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, 198 void *handle, uint64_t flags); 199 void ras_init(void); 200 201 #endif /* __ASSEMBLER__ */ 202 203 #endif /* RAS_H */ 204