123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- /*
- * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #ifndef RAS_H
- #define RAS_H
- #define ERR_HANDLER_VERSION 1U
- /* Error record access mechanism */
- #define ERR_ACCESS_SYSREG 0
- #define ERR_ACCESS_MEMMAP 1
- /*
- * Register all error records on the platform.
- *
- * This macro must be used in the same file as the array of error record info
- * are declared. Only then would ARRAY_SIZE() yield a meaningful value.
- */
- #define REGISTER_ERR_RECORD_INFO(_records) \
- const struct err_record_mapping err_record_mappings = { \
- .err_records = (_records), \
- .num_err_records = ARRAY_SIZE(_records), \
- }
- /* Error record info iterator */
- #define for_each_err_record_info(_i, _info) \
- for ((_i) = 0, (_info) = err_record_mappings.err_records; \
- (_i) < err_record_mappings.num_err_records; \
- (_i)++, (_info)++)
- #define ERR_RECORD_COMMON_(_probe, _handler, _aux) \
- .probe = _probe, \
- .handler = _handler, \
- .aux_data = _aux,
- #define ERR_RECORD_SYSREG_V1(_idx_start, _num_idx, _probe, _handler, _aux) \
- { \
- .version = 1, \
- .sysreg.idx_start = _idx_start, \
- .sysreg.num_idx = _num_idx, \
- .access = ERR_ACCESS_SYSREG, \
- ERR_RECORD_COMMON_(_probe, _handler, _aux) \
- }
- #define ERR_RECORD_MEMMAP_V1(_base_addr, _size_num_k, _probe, _handler, _aux) \
- { \
- .version = 1, \
- .memmap.base_addr = _base_addr, \
- .memmap.size_num_k = _size_num_k, \
- .access = ERR_ACCESS_MEMMAP, \
- ERR_RECORD_COMMON_(_probe, _handler, _aux) \
- }
- /*
- * Macro to be used to name and declare an array of RAS interrupts along with
- * their handlers.
- *
- * This macro must be used in the same file as the array of interrupts are
- * declared. Only then would ARRAY_SIZE() yield a meaningful value. Also, the
- * array is expected to be sorted in the increasing order of interrupt number.
- */
- #define REGISTER_RAS_INTERRUPTS(_array) \
- const struct ras_interrupt_mapping ras_interrupt_mappings = { \
- .intrs = (_array), \
- .num_intrs = ARRAY_SIZE(_array), \
- }
- #ifndef __ASSEMBLER__
- #include <assert.h>
- #include <lib/extensions/ras_arch.h>
- struct err_record_info;
- struct ras_interrupt {
- /* Interrupt number, and the associated error record info */
- unsigned int intr_number;
- struct err_record_info *err_record;
- void *cookie;
- };
- /* Function to probe a error record group for error */
- typedef int (*err_record_probe_t)(const struct err_record_info *info,
- int *probe_data);
- /* Data passed to error record group handler */
- struct err_handler_data {
- /* Info passed on from top-level exception handler */
- uint64_t flags;
- void *cookie;
- void *handle;
- /* Data structure version */
- unsigned int version;
- /* Reason for EA: one the ERROR_* constants */
- unsigned int ea_reason;
- /*
- * For EAs received at vector, the value read from ESR; for an EA
- * synchronized by ESB, the value of DISR.
- */
- uint32_t syndrome;
- /* For errors signalled via interrupt, the raw interrupt ID; otherwise, 0. */
- unsigned int interrupt;
- };
- /* Function to handle error from an error record group */
- typedef int (*err_record_handler_t)(const struct err_record_info *info,
- int probe_data, const struct err_handler_data *const data);
- /* Error record information */
- struct err_record_info {
- /* Function to probe error record group for errors */
- err_record_probe_t probe;
- /* Function to handle error record group errors */
- err_record_handler_t handler;
- /* Opaque group-specific data */
- void *aux_data;
- /* Additional information for Standard Error Records */
- union {
- struct {
- /*
- * For a group accessed via memory-mapped register,
- * base address of the page hosting error records, and
- * the size of the record group.
- */
- uintptr_t base_addr;
- /* Size of group in number of KBs */
- unsigned int size_num_k;
- } memmap;
- struct {
- /*
- * For error records accessed via system register, index of
- * the error record.
- */
- unsigned int idx_start;
- unsigned int num_idx;
- } sysreg;
- };
- /* Data structure version */
- unsigned int version;
- /* Error record access mechanism */
- unsigned int access:1;
- };
- struct err_record_mapping {
- struct err_record_info *err_records;
- size_t num_err_records;
- };
- struct ras_interrupt_mapping {
- struct ras_interrupt *intrs;
- size_t num_intrs;
- };
- extern const struct err_record_mapping err_record_mappings;
- extern const struct ras_interrupt_mapping ras_interrupt_mappings;
- /*
- * Helper functions to probe memory-mapped and system registers implemented in
- * Standard Error Record format
- */
- static inline int ras_err_ser_probe_memmap(const struct err_record_info *info,
- int *probe_data)
- {
- assert(info->version == ERR_HANDLER_VERSION);
- return ser_probe_memmap(info->memmap.base_addr, info->memmap.size_num_k,
- probe_data);
- }
- static inline int ras_err_ser_probe_sysreg(const struct err_record_info *info,
- int *probe_data)
- {
- assert(info->version == ERR_HANDLER_VERSION);
- return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx,
- probe_data);
- }
- const char *ras_serr_to_str(unsigned int serr);
- int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
- void *handle, uint64_t flags);
- void ras_init(void);
- #endif /* __ASSEMBLER__ */
- #endif /* RAS_H */
|