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 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 57 #ifndef __ASSEMBLY__ 58 59 #include <assert.h> 60 #include <ras_arch.h> 61 62 struct err_record_info; 63 64 /* Function to probe a error record group for error */ 65 typedef int (*err_record_probe_t)(const struct err_record_info *info, 66 int *probe_data); 67 68 /* Data passed to error record group handler */ 69 struct err_handler_data { 70 /* Info passed on from top-level exception handler */ 71 uint64_t flags; 72 void *cookie; 73 void *handle; 74 75 /* Data structure version */ 76 unsigned int version; 77 78 /* Reason for EA: one the ERROR_* constants */ 79 unsigned int ea_reason; 80 81 /* 82 * For EAs received at vector, the value read from ESR; for an EA 83 * synchronized by ESB, the value of DISR. 84 */ 85 uint32_t syndrome; 86 }; 87 88 /* Function to handle error from an error record group */ 89 typedef int (*err_record_handler_t)(const struct err_record_info *info, 90 int probe_data, const struct err_handler_data *const data); 91 92 /* Error record information */ 93 struct err_record_info { 94 /* Function to probe error record group for errors */ 95 err_record_probe_t probe; 96 97 /* Function to handle error record group errors */ 98 err_record_handler_t handler; 99 100 /* Opaque group-specific data */ 101 void *aux_data; 102 103 /* Additional information for Standard Error Records */ 104 union { 105 struct { 106 /* 107 * For a group accessed via. memory-mapped register, 108 * base address of the page hosting error records, and 109 * the size of the record group. 110 */ 111 uintptr_t base_addr; 112 113 /* Size of group in number of KBs */ 114 unsigned int size_num_k; 115 } memmap; 116 117 struct { 118 /* 119 * For error records accessed via. system register, index of 120 * the error record. 121 */ 122 unsigned int idx_start; 123 unsigned int num_idx; 124 } sysreg; 125 }; 126 127 /* Data structure version */ 128 unsigned int version; 129 130 /* Error record access mechanism */ 131 unsigned int access:1; 132 }; 133 134 struct err_record_mapping { 135 struct err_record_info *err_records; 136 size_t num_err_records; 137 }; 138 139 extern const struct err_record_mapping err_record_mapping; 140 141 142 /* 143 * Helper functions to probe memory-mapped and system registers implemented in 144 * Standard Error Record format 145 */ 146 static inline int ras_err_ser_probe_memmap(const struct err_record_info *info, 147 int *probe_data) 148 { 149 assert(info->version == ERR_HANDLER_VERSION); 150 151 return ser_probe_memmap(info->memmap.base_addr, info->memmap.size_num_k, 152 probe_data); 153 } 154 155 static inline int ras_err_ser_probe_sysreg(const struct err_record_info *info, 156 int *probe_data) 157 { 158 assert(info->version == ERR_HANDLER_VERSION); 159 160 return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx, 161 probe_data); 162 } 163 164 int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, 165 void *handle, uint64_t flags); 166 167 #endif /* __ASSEMBLY__ */ 168 #endif /* __RAS_COMMON__ */ 169