1 /* 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 1U 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_mappings = { \ 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_mappings.err_records; \ 31 (_i) < err_record_mappings.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 57 /* 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_mappings = { \ 67 .intrs = (_array), \ 68 .num_intrs = ARRAY_SIZE(_array), \ 69 } 70 71 #ifndef __ASSEMBLY__ 72 73 #include <assert.h> 74 #include <ras_arch.h> 75 76 struct err_record_info; 77 78 struct 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 85 /* Function to probe a error record group for error */ 86 typedef int (*err_record_probe_t)(const struct err_record_info *info, 87 int *probe_data); 88 89 /* Data passed to error record group handler */ 90 struct 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; 107 108 /* For errors signalled via. interrupt, the raw interrupt ID; otherwise, 0. */ 109 unsigned int interrupt; 110 }; 111 112 /* Function to handle error from an error record group */ 113 typedef 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 */ 117 struct 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 158 struct err_record_mapping { 159 struct err_record_info *err_records; 160 size_t num_err_records; 161 }; 162 163 struct ras_interrupt_mapping { 164 struct ras_interrupt *intrs; 165 size_t num_intrs; 166 }; 167 168 extern const struct err_record_mapping err_record_mappings; 169 extern const struct ras_interrupt_mapping ras_interrupt_mappings; 170 171 172 /* 173 * Helper functions to probe memory-mapped and system registers implemented in 174 * Standard Error Record format 175 */ 176 static 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 185 static 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 194 int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, 195 void *handle, uint64_t flags); 196 void ras_init(void); 197 198 #endif /* __ASSEMBLY__ */ 199 #endif /* RAS_COMMON */ 200