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