ras.h 5.2 KB

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