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_ARCH_H 8 #define RAS_ARCH_H 9 10 /* 11 * Size of nodes implementing Standard Error Records - currently only 4k is 12 * supported. 13 */ 14 #define STD_ERR_NODE_SIZE_NUM_K 4U 15 16 /* 17 * Individual register offsets within an error record in Standard Error Record 18 * format when error records are accessed through memory-mapped registers. 19 */ 20 #define ERR_FR(n) (0x0ULL + (64ULL * (n))) 21 #define ERR_CTLR(n) (0x8ULL + (64ULL * (n))) 22 #define ERR_STATUS(n) (0x10ULL + (64ULL * (n))) 23 #define ERR_ADDR(n) (0x18ULL + (64ULL * (n))) 24 #define ERR_MISC0(n) (0x20ULL + (64ULL * (n))) 25 #define ERR_MISC1(n) (0x28ULL + (64ULL * (n))) 26 27 /* Group Status Register (ERR_STATUS) offset */ 28 #define ERR_GSR(base, size_num_k, n) \ 29 ((base) + (0x380ULL * (size_num_k)) + (8ULL * (n))) 30 31 /* Management register offsets */ 32 #define ERR_DEVID(base, size_num_k) \ 33 ((base) + ((0x400ULL * (size_num_k)) - 0x100ULL) + 0xc8ULL) 34 35 #define ERR_DEVID_MASK 0xffffUL 36 37 /* Standard Error Record status register fields */ 38 #define ERR_STATUS_AV_SHIFT 31 39 #define ERR_STATUS_AV_MASK U(0x1) 40 41 #define ERR_STATUS_V_SHIFT 30 42 #define ERR_STATUS_V_MASK U(0x1) 43 44 #define ERR_STATUS_UE_SHIFT 29 45 #define ERR_STATUS_UE_MASK U(0x1) 46 47 #define ERR_STATUS_ER_SHIFT 28 48 #define ERR_STATUS_ER_MASK U(0x1) 49 50 #define ERR_STATUS_OF_SHIFT 27 51 #define ERR_STATUS_OF_MASK U(0x1) 52 53 #define ERR_STATUS_MV_SHIFT 26 54 #define ERR_STATUS_MV_MASK U(0x1) 55 56 #define ERR_STATUS_CE_SHIFT 24 57 #define ERR_STATUS_CE_MASK U(0x3) 58 59 #define ERR_STATUS_DE_SHIFT 23 60 #define ERR_STATUS_DE_MASK U(0x1) 61 62 #define ERR_STATUS_PN_SHIFT 22 63 #define ERR_STATUS_PN_MASK U(0x1) 64 65 #define ERR_STATUS_UET_SHIFT 20 66 #define ERR_STATUS_UET_MASK U(0x3) 67 68 #define ERR_STATUS_IERR_SHIFT 8 69 #define ERR_STATUS_IERR_MASK U(0xff) 70 71 #define ERR_STATUS_SERR_SHIFT 0 72 #define ERR_STATUS_SERR_MASK U(0xff) 73 74 #define ERR_STATUS_GET_FIELD(_status, _field) \ 75 (((_status) >> ERR_STATUS_ ##_field ##_SHIFT) & ERR_STATUS_ ##_field ##_MASK) 76 77 #define ERR_STATUS_CLR_FIELD(_status, _field) \ 78 (_status) &= ~(ERR_STATUS_ ##_field ##_MASK << ERR_STATUS_ ##_field ##_SHIFT) 79 80 #define ERR_STATUS_SET_FIELD(_status, _field, _value) \ 81 (_status) |= (((_value) & ERR_STATUS_ ##_field ##_MASK) << ERR_STATUS_ ##_field ##_SHIFT) 82 83 #define ERR_STATUS_WRITE_FIELD(_status, _field, _value) do { \ 84 ERR_STATUS_CLR_FIELD(_status, _field, _value); \ 85 ERR_STATUS_SET_FIELD(_status, _field, _value); \ 86 } while (0) 87 88 89 /* Standard Error Record control register fields */ 90 #define ERR_CTLR_WDUI_SHIFT 11 91 #define ERR_CTLR_WDUI_MASK 0x1 92 93 #define ERR_CTLR_RDUI_SHIFT 10 94 #define ERR_CTLR_RDUI_MASK 0x1 95 #define ERR_CTLR_DUI_SHIFT ERR_CTLR_RDUI_SHIFT 96 #define ERR_CTLR_DUI_MASK ERR_CTLR_RDUI_MASK 97 98 #define ERR_CTLR_WCFI_SHIFT 9 99 #define ERR_CTLR_WCFI_MASK 0x1 100 101 #define ERR_CTLR_RCFI_SHIFT 8 102 #define ERR_CTLR_RCFI_MASK 0x1 103 #define ERR_CTLR_CFI_SHIFT ERR_CTLR_RCFI_SHIFT 104 #define ERR_CTLR_CFI_MASK ERR_CTLR_RCFI_MASK 105 106 #define ERR_CTLR_WUE_SHIFT 7 107 #define ERR_CTLR_WUE_MASK 0x1 108 109 #define ERR_CTLR_WFI_SHIFT 6 110 #define ERR_CTLR_WFI_MASK 0x1 111 112 #define ERR_CTLR_WUI_SHIFT 5 113 #define ERR_CTLR_WUI_MASK 0x1 114 115 #define ERR_CTLR_RUE_SHIFT 4 116 #define ERR_CTLR_RUE_MASK 0x1 117 #define ERR_CTLR_UE_SHIFT ERR_CTLR_RUE_SHIFT 118 #define ERR_CTLR_UE_MASK ERR_CTLR_RUE_MASK 119 120 #define ERR_CTLR_RFI_SHIFT 3 121 #define ERR_CTLR_RFI_MASK 0x1 122 #define ERR_CTLR_FI_SHIFT ERR_CTLR_RFI_SHIFT 123 #define ERR_CTLR_FI_MASK ERR_CTLR_RFI_MASK 124 125 #define ERR_CTLR_RUI_SHIFT 2 126 #define ERR_CTLR_RUI_MASK 0x1 127 #define ERR_CTLR_UI_SHIFT ERR_CTLR_RUI_SHIFT 128 #define ERR_CTLR_UI_MASK ERR_CTLR_RUI_MASK 129 130 #define ERR_CTLR_ED_SHIFT 0 131 #define ERR_CTLR_ED_MASK 0x1 132 133 #define ERR_CTLR_CLR_FIELD(_ctlr, _field) \ 134 (_ctlr) &= ~(ERR_CTLR_ ##_field _MASK << ERR_CTLR_ ##_field ##_SHIFT) 135 136 #define ERR_CTLR_SET_FIELD(_ctlr, _field, _value) \ 137 (_ctlr) |= (((_value) & ERR_CTLR_ ##_field ##_MASK) << ERR_CTLR_ ##_field ##_SHIFT) 138 139 #define ERR_CTLR_ENABLE_FIELD(_ctlr, _field) \ 140 ERR_CTLR_SET_FIELD(_ctlr, _field, ERR_CTLR_ ##_field ##_MASK) 141 142 /* Uncorrected error types for Asynchronous exceptions */ 143 #define ERROR_STATUS_UET_UC 0x0 /* Uncontainable */ 144 #define ERROR_STATUS_UET_UEU 0x1 /* Unrecoverable */ 145 #define ERROR_STATUS_UET_UEO 0x2 /* Restable */ 146 #define ERROR_STATUS_UET_UER 0x3 /* Recoverable */ 147 148 /* Error types for Synchronous exceptions */ 149 #define ERROR_STATUS_SET_UER 0x0 /* Recoverable */ 150 #define ERROR_STATUS_SET_UEO 0x1 /* Restable */ 151 #define ERROR_STATUS_SET_UC 0x2 /* Uncontainable */ 152 #define ERROR_STATUS_SET_CE 0x3 /* Corrected */ 153 154 /* Implementation Defined Syndrome bit in ESR */ 155 #define SERROR_IDS_BIT U(24) 156 157 /* 158 * Asynchronous Error Type in exception syndrome. The field has same values in 159 * both DISR_EL1 and ESR_EL3 for SError. 160 */ 161 #define EABORT_AET_SHIFT U(10) 162 #define EABORT_AET_WIDTH U(3) 163 #define EABORT_AET_MASK U(0x7) 164 165 /* DFSC field in Asynchronous exception syndrome */ 166 #define EABORT_DFSC_SHIFT U(0) 167 #define EABORT_DFSC_WIDTH U(6) 168 #define EABORT_DFSC_MASK U(0x3f) 169 170 /* Synchronous Error Type in exception syndrome. */ 171 #define EABORT_SET_SHIFT U(11) 172 #define EABORT_SET_WIDTH U(2) 173 #define EABORT_SET_MASK U(0x3) 174 175 /* DFSC code for SErrors */ 176 #define DFSC_SERROR 0x11 177 178 /* I/DFSC code for synchronous external abort */ 179 #define SYNC_EA_FSC 0x10 180 181 #ifndef __ASSEMBLY__ 182 183 #include <arch.h> 184 #include <arch_helpers.h> 185 #include <assert.h> 186 #include <context.h> 187 #include <lib/mmio.h> 188 #include <stdint.h> 189 190 /* 191 * Standard Error Record accessors for memory-mapped registers. 192 */ 193 194 static inline uint64_t ser_get_feature(uintptr_t base, unsigned int idx) 195 { 196 return mmio_read_64(base + ERR_FR(idx)); 197 } 198 199 static inline uint64_t ser_get_control(uintptr_t base, unsigned int idx) 200 { 201 return mmio_read_64(base + ERR_CTLR(idx)); 202 } 203 204 static inline uint64_t ser_get_status(uintptr_t base, unsigned int idx) 205 { 206 return mmio_read_64(base + ERR_STATUS(idx)); 207 } 208 209 /* 210 * Error handling agent would write to the status register to clear an 211 * identified/handled error. Most fields in the status register are 212 * conditional write-one-to-clear. 213 * 214 * Typically, to clear the status, it suffices to write back the same value 215 * previously read. However, if there were new, higher-priority errors recorded 216 * on the node since status was last read, writing read value won't clear the 217 * status. Therefore, an error handling agent must wait on and verify the status 218 * has indeed been cleared. 219 */ 220 static inline void ser_set_status(uintptr_t base, unsigned int idx, 221 uint64_t status) 222 { 223 mmio_write_64(base + ERR_STATUS(idx), status); 224 } 225 226 static inline uint64_t ser_get_addr(uintptr_t base, unsigned int idx) 227 { 228 return mmio_read_64(base + ERR_ADDR(idx)); 229 } 230 231 static inline uint64_t ser_get_misc0(uintptr_t base, unsigned int idx) 232 { 233 return mmio_read_64(base + ERR_MISC0(idx)); 234 } 235 236 static inline uint64_t ser_get_misc1(uintptr_t base, unsigned int idx) 237 { 238 return mmio_read_64(base + ERR_MISC1(idx)); 239 } 240 241 242 /* 243 * Standard Error Record helpers for System registers. 244 */ 245 static inline void ser_sys_select_record(unsigned int idx) 246 { 247 unsigned int max_idx __unused = 248 (unsigned int) read_erridr_el1() & ERRIDR_MASK; 249 250 assert(idx < max_idx); 251 252 write_errselr_el1(idx); 253 isb(); 254 } 255 256 /* Library functions to probe Standard Error Record */ 257 int ser_probe_memmap(uintptr_t base, unsigned int size_num_k, int *probe_data); 258 int ser_probe_sysreg(unsigned int idx_start, unsigned int num_idx, int *probe_data); 259 #endif /* __ASSEMBLY__ */ 260 261 #endif /* RAS_ARCH_H */ 262