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