1*362599ecSJeenu Viswambharan /* 2*362599ecSJeenu Viswambharan * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 3*362599ecSJeenu Viswambharan * 4*362599ecSJeenu Viswambharan * SPDX-License-Identifier: BSD-3-Clause 5*362599ecSJeenu Viswambharan */ 6*362599ecSJeenu Viswambharan 7*362599ecSJeenu Viswambharan #ifndef __RAS_COMMON__ 8*362599ecSJeenu Viswambharan #define __RAS_COMMON__ 9*362599ecSJeenu Viswambharan 10*362599ecSJeenu Viswambharan #define ERR_HANDLER_VERSION 1 11*362599ecSJeenu Viswambharan 12*362599ecSJeenu Viswambharan /* Error record access mechanism */ 13*362599ecSJeenu Viswambharan #define ERR_ACCESS_SYSREG 0 14*362599ecSJeenu Viswambharan #define ERR_ACCESS_MEMMAP 1 15*362599ecSJeenu Viswambharan 16*362599ecSJeenu Viswambharan /* 17*362599ecSJeenu Viswambharan * Register all error records on the platform. 18*362599ecSJeenu Viswambharan * 19*362599ecSJeenu Viswambharan * This macro must be used in the same file as the array of error record info 20*362599ecSJeenu Viswambharan * are declared. Only then would ARRAY_SIZE() yield a meaningful value. 21*362599ecSJeenu Viswambharan */ 22*362599ecSJeenu Viswambharan #define REGISTER_ERR_RECORD_INFO(_records) \ 23*362599ecSJeenu Viswambharan const struct err_record_mapping err_record_mapping = { \ 24*362599ecSJeenu Viswambharan .err_records = _records, \ 25*362599ecSJeenu Viswambharan .num_err_records = ARRAY_SIZE(_records), \ 26*362599ecSJeenu Viswambharan } 27*362599ecSJeenu Viswambharan 28*362599ecSJeenu Viswambharan /* Error record info iterator */ 29*362599ecSJeenu Viswambharan #define for_each_err_record_info(_i, _info) \ 30*362599ecSJeenu Viswambharan for (_i = 0, _info = err_record_mapping.err_records; \ 31*362599ecSJeenu Viswambharan _i < err_record_mapping.num_err_records; \ 32*362599ecSJeenu Viswambharan _i++, _info++) 33*362599ecSJeenu Viswambharan 34*362599ecSJeenu Viswambharan #define _ERR_RECORD_COMMON(_probe, _handler, _aux) \ 35*362599ecSJeenu Viswambharan .probe = _probe, \ 36*362599ecSJeenu Viswambharan .handler = _handler, \ 37*362599ecSJeenu Viswambharan .aux_data = _aux, 38*362599ecSJeenu Viswambharan 39*362599ecSJeenu Viswambharan #define ERR_RECORD_SYSREG_V1(_idx_start, _num_idx, _probe, _handler, _aux) \ 40*362599ecSJeenu Viswambharan { \ 41*362599ecSJeenu Viswambharan .version = 1, \ 42*362599ecSJeenu Viswambharan .sysreg.idx_start = _idx_start, \ 43*362599ecSJeenu Viswambharan .sysreg.num_idx = _num_idx, \ 44*362599ecSJeenu Viswambharan .access = ERR_ACCESS_SYSREG, \ 45*362599ecSJeenu Viswambharan _ERR_RECORD_COMMON(_probe, _handler, _aux) \ 46*362599ecSJeenu Viswambharan } 47*362599ecSJeenu Viswambharan 48*362599ecSJeenu Viswambharan #define ERR_RECORD_MEMMAP_V1(_base_addr, _size_num_k, _probe, _handler, _aux) \ 49*362599ecSJeenu Viswambharan { \ 50*362599ecSJeenu Viswambharan .version = 1, \ 51*362599ecSJeenu Viswambharan .memmap.base_addr = _base_addr, \ 52*362599ecSJeenu Viswambharan .memmap.size_num_k = _size_num_k, \ 53*362599ecSJeenu Viswambharan .access = ERR_ACCESS_MEMMAP, \ 54*362599ecSJeenu Viswambharan _ERR_RECORD_COMMON(_probe, _handler, _aux) \ 55*362599ecSJeenu Viswambharan } 56*362599ecSJeenu Viswambharan 57*362599ecSJeenu Viswambharan #ifndef __ASSEMBLY__ 58*362599ecSJeenu Viswambharan 59*362599ecSJeenu Viswambharan #include <assert.h> 60*362599ecSJeenu Viswambharan #include <ras_arch.h> 61*362599ecSJeenu Viswambharan 62*362599ecSJeenu Viswambharan struct err_record_info; 63*362599ecSJeenu Viswambharan 64*362599ecSJeenu Viswambharan /* Function to probe a error record group for error */ 65*362599ecSJeenu Viswambharan typedef int (*err_record_probe_t)(const struct err_record_info *info, 66*362599ecSJeenu Viswambharan int *probe_data); 67*362599ecSJeenu Viswambharan 68*362599ecSJeenu Viswambharan /* Data passed to error record group handler */ 69*362599ecSJeenu Viswambharan struct err_handler_data { 70*362599ecSJeenu Viswambharan /* Info passed on from top-level exception handler */ 71*362599ecSJeenu Viswambharan uint64_t flags; 72*362599ecSJeenu Viswambharan void *cookie; 73*362599ecSJeenu Viswambharan void *handle; 74*362599ecSJeenu Viswambharan 75*362599ecSJeenu Viswambharan /* Data structure version */ 76*362599ecSJeenu Viswambharan unsigned int version; 77*362599ecSJeenu Viswambharan 78*362599ecSJeenu Viswambharan /* Reason for EA: one the ERROR_* constants */ 79*362599ecSJeenu Viswambharan unsigned int ea_reason; 80*362599ecSJeenu Viswambharan 81*362599ecSJeenu Viswambharan /* 82*362599ecSJeenu Viswambharan * For EAs received at vector, the value read from ESR; for an EA 83*362599ecSJeenu Viswambharan * synchronized by ESB, the value of DISR. 84*362599ecSJeenu Viswambharan */ 85*362599ecSJeenu Viswambharan uint32_t syndrome; 86*362599ecSJeenu Viswambharan }; 87*362599ecSJeenu Viswambharan 88*362599ecSJeenu Viswambharan /* Function to handle error from an error record group */ 89*362599ecSJeenu Viswambharan typedef int (*err_record_handler_t)(const struct err_record_info *info, 90*362599ecSJeenu Viswambharan int probe_data, const struct err_handler_data *const data); 91*362599ecSJeenu Viswambharan 92*362599ecSJeenu Viswambharan /* Error record information */ 93*362599ecSJeenu Viswambharan struct err_record_info { 94*362599ecSJeenu Viswambharan /* Function to probe error record group for errors */ 95*362599ecSJeenu Viswambharan err_record_probe_t probe; 96*362599ecSJeenu Viswambharan 97*362599ecSJeenu Viswambharan /* Function to handle error record group errors */ 98*362599ecSJeenu Viswambharan err_record_handler_t handler; 99*362599ecSJeenu Viswambharan 100*362599ecSJeenu Viswambharan /* Opaque group-specific data */ 101*362599ecSJeenu Viswambharan void *aux_data; 102*362599ecSJeenu Viswambharan 103*362599ecSJeenu Viswambharan /* Additional information for Standard Error Records */ 104*362599ecSJeenu Viswambharan union { 105*362599ecSJeenu Viswambharan struct { 106*362599ecSJeenu Viswambharan /* 107*362599ecSJeenu Viswambharan * For a group accessed via. memory-mapped register, 108*362599ecSJeenu Viswambharan * base address of the page hosting error records, and 109*362599ecSJeenu Viswambharan * the size of the record group. 110*362599ecSJeenu Viswambharan */ 111*362599ecSJeenu Viswambharan uintptr_t base_addr; 112*362599ecSJeenu Viswambharan 113*362599ecSJeenu Viswambharan /* Size of group in number of KBs */ 114*362599ecSJeenu Viswambharan unsigned int size_num_k; 115*362599ecSJeenu Viswambharan } memmap; 116*362599ecSJeenu Viswambharan 117*362599ecSJeenu Viswambharan struct { 118*362599ecSJeenu Viswambharan /* 119*362599ecSJeenu Viswambharan * For error records accessed via. system register, index of 120*362599ecSJeenu Viswambharan * the error record. 121*362599ecSJeenu Viswambharan */ 122*362599ecSJeenu Viswambharan unsigned int idx_start; 123*362599ecSJeenu Viswambharan unsigned int num_idx; 124*362599ecSJeenu Viswambharan } sysreg; 125*362599ecSJeenu Viswambharan }; 126*362599ecSJeenu Viswambharan 127*362599ecSJeenu Viswambharan /* Data structure version */ 128*362599ecSJeenu Viswambharan unsigned int version; 129*362599ecSJeenu Viswambharan 130*362599ecSJeenu Viswambharan /* Error record access mechanism */ 131*362599ecSJeenu Viswambharan unsigned int access:1; 132*362599ecSJeenu Viswambharan }; 133*362599ecSJeenu Viswambharan 134*362599ecSJeenu Viswambharan struct err_record_mapping { 135*362599ecSJeenu Viswambharan struct err_record_info *err_records; 136*362599ecSJeenu Viswambharan size_t num_err_records; 137*362599ecSJeenu Viswambharan }; 138*362599ecSJeenu Viswambharan 139*362599ecSJeenu Viswambharan extern const struct err_record_mapping err_record_mapping; 140*362599ecSJeenu Viswambharan 141*362599ecSJeenu Viswambharan 142*362599ecSJeenu Viswambharan /* 143*362599ecSJeenu Viswambharan * Helper functions to probe memory-mapped and system registers implemented in 144*362599ecSJeenu Viswambharan * Standard Error Record format 145*362599ecSJeenu Viswambharan */ 146*362599ecSJeenu Viswambharan static inline int ras_err_ser_probe_memmap(const struct err_record_info *info, 147*362599ecSJeenu Viswambharan int *probe_data) 148*362599ecSJeenu Viswambharan { 149*362599ecSJeenu Viswambharan assert(info->version == ERR_HANDLER_VERSION); 150*362599ecSJeenu Viswambharan 151*362599ecSJeenu Viswambharan return ser_probe_memmap(info->memmap.base_addr, info->memmap.size_num_k, 152*362599ecSJeenu Viswambharan probe_data); 153*362599ecSJeenu Viswambharan } 154*362599ecSJeenu Viswambharan 155*362599ecSJeenu Viswambharan static inline int ras_err_ser_probe_sysreg(const struct err_record_info *info, 156*362599ecSJeenu Viswambharan int *probe_data) 157*362599ecSJeenu Viswambharan { 158*362599ecSJeenu Viswambharan assert(info->version == ERR_HANDLER_VERSION); 159*362599ecSJeenu Viswambharan 160*362599ecSJeenu Viswambharan return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx, 161*362599ecSJeenu Viswambharan probe_data); 162*362599ecSJeenu Viswambharan } 163*362599ecSJeenu Viswambharan 164*362599ecSJeenu Viswambharan int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, 165*362599ecSJeenu Viswambharan void *handle, uint64_t flags); 166*362599ecSJeenu Viswambharan 167*362599ecSJeenu Viswambharan #endif /* __ASSEMBLY__ */ 168*362599ecSJeenu Viswambharan #endif /* __RAS_COMMON__ */ 169