130d81c36SJeenu Viswambharan /*
24c700c15SGovindraj Raja * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
38ca61538SDavid Pu * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
430d81c36SJeenu Viswambharan *
530d81c36SJeenu Viswambharan * SPDX-License-Identifier: BSD-3-Clause
630d81c36SJeenu Viswambharan */
730d81c36SJeenu Viswambharan
8b56dc2a9SJeenu Viswambharan #ifndef RAS_ARCH_H
9b56dc2a9SJeenu Viswambharan #define RAS_ARCH_H
1030d81c36SJeenu Viswambharan
1130d81c36SJeenu Viswambharan /*
1230d81c36SJeenu Viswambharan * Size of nodes implementing Standard Error Records - currently only 4k is
1330d81c36SJeenu Viswambharan * supported.
1430d81c36SJeenu Viswambharan */
1530a8d96eSJeenu Viswambharan #define STD_ERR_NODE_SIZE_NUM_K 4U
1630d81c36SJeenu Viswambharan
1730d81c36SJeenu Viswambharan /*
1830d81c36SJeenu Viswambharan * Individual register offsets within an error record in Standard Error Record
1930d81c36SJeenu Viswambharan * format when error records are accessed through memory-mapped registers.
2030d81c36SJeenu Viswambharan */
2130a8d96eSJeenu Viswambharan #define ERR_FR(n) (0x0ULL + (64ULL * (n)))
2230a8d96eSJeenu Viswambharan #define ERR_CTLR(n) (0x8ULL + (64ULL * (n)))
2330a8d96eSJeenu Viswambharan #define ERR_STATUS(n) (0x10ULL + (64ULL * (n)))
2430a8d96eSJeenu Viswambharan #define ERR_ADDR(n) (0x18ULL + (64ULL * (n)))
2530a8d96eSJeenu Viswambharan #define ERR_MISC0(n) (0x20ULL + (64ULL * (n)))
2630a8d96eSJeenu Viswambharan #define ERR_MISC1(n) (0x28ULL + (64ULL * (n)))
2730d81c36SJeenu Viswambharan
2830d81c36SJeenu Viswambharan /* Group Status Register (ERR_STATUS) offset */
2930d81c36SJeenu Viswambharan #define ERR_GSR(base, size_num_k, n) \
3030a8d96eSJeenu Viswambharan ((base) + (0x380ULL * (size_num_k)) + (8ULL * (n)))
3130d81c36SJeenu Viswambharan
3230d81c36SJeenu Viswambharan /* Management register offsets */
3330d81c36SJeenu Viswambharan #define ERR_DEVID(base, size_num_k) \
3430a8d96eSJeenu Viswambharan ((base) + ((0x400ULL * (size_num_k)) - 0x100ULL) + 0xc8ULL)
3530d81c36SJeenu Viswambharan
3630a8d96eSJeenu Viswambharan #define ERR_DEVID_MASK 0xffffUL
3730d81c36SJeenu Viswambharan
3830d81c36SJeenu Viswambharan /* Standard Error Record status register fields */
3930d81c36SJeenu Viswambharan #define ERR_STATUS_AV_SHIFT 31
4030d81c36SJeenu Viswambharan #define ERR_STATUS_AV_MASK U(0x1)
4130d81c36SJeenu Viswambharan
4230d81c36SJeenu Viswambharan #define ERR_STATUS_V_SHIFT 30
4330d81c36SJeenu Viswambharan #define ERR_STATUS_V_MASK U(0x1)
4430d81c36SJeenu Viswambharan
4530d81c36SJeenu Viswambharan #define ERR_STATUS_UE_SHIFT 29
4630d81c36SJeenu Viswambharan #define ERR_STATUS_UE_MASK U(0x1)
4730d81c36SJeenu Viswambharan
4830d81c36SJeenu Viswambharan #define ERR_STATUS_ER_SHIFT 28
4930d81c36SJeenu Viswambharan #define ERR_STATUS_ER_MASK U(0x1)
5030d81c36SJeenu Viswambharan
5130d81c36SJeenu Viswambharan #define ERR_STATUS_OF_SHIFT 27
5230d81c36SJeenu Viswambharan #define ERR_STATUS_OF_MASK U(0x1)
5330d81c36SJeenu Viswambharan
5430d81c36SJeenu Viswambharan #define ERR_STATUS_MV_SHIFT 26
5530d81c36SJeenu Viswambharan #define ERR_STATUS_MV_MASK U(0x1)
5630d81c36SJeenu Viswambharan
5730d81c36SJeenu Viswambharan #define ERR_STATUS_CE_SHIFT 24
5830d81c36SJeenu Viswambharan #define ERR_STATUS_CE_MASK U(0x3)
5930d81c36SJeenu Viswambharan
6030d81c36SJeenu Viswambharan #define ERR_STATUS_DE_SHIFT 23
6130d81c36SJeenu Viswambharan #define ERR_STATUS_DE_MASK U(0x1)
6230d81c36SJeenu Viswambharan
6330d81c36SJeenu Viswambharan #define ERR_STATUS_PN_SHIFT 22
6430d81c36SJeenu Viswambharan #define ERR_STATUS_PN_MASK U(0x1)
6530d81c36SJeenu Viswambharan
6630d81c36SJeenu Viswambharan #define ERR_STATUS_UET_SHIFT 20
6730d81c36SJeenu Viswambharan #define ERR_STATUS_UET_MASK U(0x3)
6830d81c36SJeenu Viswambharan
6930d81c36SJeenu Viswambharan #define ERR_STATUS_IERR_SHIFT 8
7030d81c36SJeenu Viswambharan #define ERR_STATUS_IERR_MASK U(0xff)
7130d81c36SJeenu Viswambharan
7230d81c36SJeenu Viswambharan #define ERR_STATUS_SERR_SHIFT 0
7330d81c36SJeenu Viswambharan #define ERR_STATUS_SERR_MASK U(0xff)
7430d81c36SJeenu Viswambharan
7530d81c36SJeenu Viswambharan #define ERR_STATUS_GET_FIELD(_status, _field) \
7630d81c36SJeenu Viswambharan (((_status) >> ERR_STATUS_ ##_field ##_SHIFT) & ERR_STATUS_ ##_field ##_MASK)
7730d81c36SJeenu Viswambharan
7830d81c36SJeenu Viswambharan #define ERR_STATUS_CLR_FIELD(_status, _field) \
7930d81c36SJeenu Viswambharan (_status) &= ~(ERR_STATUS_ ##_field ##_MASK << ERR_STATUS_ ##_field ##_SHIFT)
8030d81c36SJeenu Viswambharan
8130d81c36SJeenu Viswambharan #define ERR_STATUS_SET_FIELD(_status, _field, _value) \
8230d81c36SJeenu Viswambharan (_status) |= (((_value) & ERR_STATUS_ ##_field ##_MASK) << ERR_STATUS_ ##_field ##_SHIFT)
8330d81c36SJeenu Viswambharan
8430d81c36SJeenu Viswambharan #define ERR_STATUS_WRITE_FIELD(_status, _field, _value) do { \
8530d81c36SJeenu Viswambharan ERR_STATUS_CLR_FIELD(_status, _field, _value); \
8630d81c36SJeenu Viswambharan ERR_STATUS_SET_FIELD(_status, _field, _value); \
8730d81c36SJeenu Viswambharan } while (0)
8830d81c36SJeenu Viswambharan
8930d81c36SJeenu Viswambharan
9030d81c36SJeenu Viswambharan /* Standard Error Record control register fields */
9130d81c36SJeenu Viswambharan #define ERR_CTLR_WDUI_SHIFT 11
9230d81c36SJeenu Viswambharan #define ERR_CTLR_WDUI_MASK 0x1
9330d81c36SJeenu Viswambharan
9430d81c36SJeenu Viswambharan #define ERR_CTLR_RDUI_SHIFT 10
9530d81c36SJeenu Viswambharan #define ERR_CTLR_RDUI_MASK 0x1
9630d81c36SJeenu Viswambharan #define ERR_CTLR_DUI_SHIFT ERR_CTLR_RDUI_SHIFT
9730d81c36SJeenu Viswambharan #define ERR_CTLR_DUI_MASK ERR_CTLR_RDUI_MASK
9830d81c36SJeenu Viswambharan
9930d81c36SJeenu Viswambharan #define ERR_CTLR_WCFI_SHIFT 9
10030d81c36SJeenu Viswambharan #define ERR_CTLR_WCFI_MASK 0x1
10130d81c36SJeenu Viswambharan
10230d81c36SJeenu Viswambharan #define ERR_CTLR_RCFI_SHIFT 8
10330d81c36SJeenu Viswambharan #define ERR_CTLR_RCFI_MASK 0x1
10430d81c36SJeenu Viswambharan #define ERR_CTLR_CFI_SHIFT ERR_CTLR_RCFI_SHIFT
10530d81c36SJeenu Viswambharan #define ERR_CTLR_CFI_MASK ERR_CTLR_RCFI_MASK
10630d81c36SJeenu Viswambharan
10730d81c36SJeenu Viswambharan #define ERR_CTLR_WUE_SHIFT 7
10830d81c36SJeenu Viswambharan #define ERR_CTLR_WUE_MASK 0x1
10930d81c36SJeenu Viswambharan
11030d81c36SJeenu Viswambharan #define ERR_CTLR_WFI_SHIFT 6
11130d81c36SJeenu Viswambharan #define ERR_CTLR_WFI_MASK 0x1
11230d81c36SJeenu Viswambharan
11330d81c36SJeenu Viswambharan #define ERR_CTLR_WUI_SHIFT 5
11430d81c36SJeenu Viswambharan #define ERR_CTLR_WUI_MASK 0x1
11530d81c36SJeenu Viswambharan
11630d81c36SJeenu Viswambharan #define ERR_CTLR_RUE_SHIFT 4
11730d81c36SJeenu Viswambharan #define ERR_CTLR_RUE_MASK 0x1
11830d81c36SJeenu Viswambharan #define ERR_CTLR_UE_SHIFT ERR_CTLR_RUE_SHIFT
11930d81c36SJeenu Viswambharan #define ERR_CTLR_UE_MASK ERR_CTLR_RUE_MASK
12030d81c36SJeenu Viswambharan
12130d81c36SJeenu Viswambharan #define ERR_CTLR_RFI_SHIFT 3
12230d81c36SJeenu Viswambharan #define ERR_CTLR_RFI_MASK 0x1
12330d81c36SJeenu Viswambharan #define ERR_CTLR_FI_SHIFT ERR_CTLR_RFI_SHIFT
12430d81c36SJeenu Viswambharan #define ERR_CTLR_FI_MASK ERR_CTLR_RFI_MASK
12530d81c36SJeenu Viswambharan
12630d81c36SJeenu Viswambharan #define ERR_CTLR_RUI_SHIFT 2
12730d81c36SJeenu Viswambharan #define ERR_CTLR_RUI_MASK 0x1
12830d81c36SJeenu Viswambharan #define ERR_CTLR_UI_SHIFT ERR_CTLR_RUI_SHIFT
12930d81c36SJeenu Viswambharan #define ERR_CTLR_UI_MASK ERR_CTLR_RUI_MASK
13030d81c36SJeenu Viswambharan
13130d81c36SJeenu Viswambharan #define ERR_CTLR_ED_SHIFT 0
13230d81c36SJeenu Viswambharan #define ERR_CTLR_ED_MASK 0x1
13330d81c36SJeenu Viswambharan
13430d81c36SJeenu Viswambharan #define ERR_CTLR_CLR_FIELD(_ctlr, _field) \
13530d81c36SJeenu Viswambharan (_ctlr) &= ~(ERR_CTLR_ ##_field _MASK << ERR_CTLR_ ##_field ##_SHIFT)
13630d81c36SJeenu Viswambharan
13730d81c36SJeenu Viswambharan #define ERR_CTLR_SET_FIELD(_ctlr, _field, _value) \
13830d81c36SJeenu Viswambharan (_ctlr) |= (((_value) & ERR_CTLR_ ##_field ##_MASK) << ERR_CTLR_ ##_field ##_SHIFT)
13930d81c36SJeenu Viswambharan
14030d81c36SJeenu Viswambharan #define ERR_CTLR_ENABLE_FIELD(_ctlr, _field) \
14130d81c36SJeenu Viswambharan ERR_CTLR_SET_FIELD(_ctlr, _field, ERR_CTLR_ ##_field ##_MASK)
14230d81c36SJeenu Viswambharan
143b56dc2a9SJeenu Viswambharan /* Uncorrected error types for Asynchronous exceptions */
14430d81c36SJeenu Viswambharan #define ERROR_STATUS_UET_UC 0x0 /* Uncontainable */
14530d81c36SJeenu Viswambharan #define ERROR_STATUS_UET_UEU 0x1 /* Unrecoverable */
146e5cd3e81SVinoj Soundararajan #define ERROR_STATUS_UET_UEO 0x2 /* Restartable */
14730d81c36SJeenu Viswambharan #define ERROR_STATUS_UET_UER 0x3 /* Recoverable */
14830d81c36SJeenu Viswambharan
149daeae495SVinoj Soundararajan /* Corrected error types for Asynchronous exceptions */
150daeae495SVinoj Soundararajan #define ERROR_STATUS_CET_CE 0x6 /* Corrected (CE) */
151daeae495SVinoj Soundararajan
152b56dc2a9SJeenu Viswambharan /* Error types for Synchronous exceptions */
153b56dc2a9SJeenu Viswambharan #define ERROR_STATUS_SET_UER 0x0 /* Recoverable */
154b56dc2a9SJeenu Viswambharan #define ERROR_STATUS_SET_UC 0x2 /* Uncontainable */
1559c17687aSVinoj Soundararajan #define ERROR_STATUS_SET_UEO 0x3 /* Restartable */
156b56dc2a9SJeenu Viswambharan
1578ca61538SDavid Pu /* Number of architecturally-defined primary error codes */
1588ca61538SDavid Pu #define ERROR_STATUS_NUM_SERR U(22)
1598ca61538SDavid Pu
160b56dc2a9SJeenu Viswambharan /* Implementation Defined Syndrome bit in ESR */
161b56dc2a9SJeenu Viswambharan #define SERROR_IDS_BIT U(24)
162b56dc2a9SJeenu Viswambharan
163b56dc2a9SJeenu Viswambharan /*
164b56dc2a9SJeenu Viswambharan * Asynchronous Error Type in exception syndrome. The field has same values in
165b56dc2a9SJeenu Viswambharan * both DISR_EL1 and ESR_EL3 for SError.
166b56dc2a9SJeenu Viswambharan */
167b56dc2a9SJeenu Viswambharan #define EABORT_AET_SHIFT U(10)
168b56dc2a9SJeenu Viswambharan #define EABORT_AET_WIDTH U(3)
169b56dc2a9SJeenu Viswambharan #define EABORT_AET_MASK U(0x7)
170b56dc2a9SJeenu Viswambharan
171b56dc2a9SJeenu Viswambharan /* DFSC field in Asynchronous exception syndrome */
172b56dc2a9SJeenu Viswambharan #define EABORT_DFSC_SHIFT U(0)
173b56dc2a9SJeenu Viswambharan #define EABORT_DFSC_WIDTH U(6)
174b56dc2a9SJeenu Viswambharan #define EABORT_DFSC_MASK U(0x3f)
175b56dc2a9SJeenu Viswambharan
176b56dc2a9SJeenu Viswambharan /* Synchronous Error Type in exception syndrome. */
177b56dc2a9SJeenu Viswambharan #define EABORT_SET_SHIFT U(11)
178b56dc2a9SJeenu Viswambharan #define EABORT_SET_WIDTH U(2)
179b56dc2a9SJeenu Viswambharan #define EABORT_SET_MASK U(0x3)
180b56dc2a9SJeenu Viswambharan
181*ec6f49c2SVinoj Soundararajan #define EABORT_GET_FIELD(_esr_el3, _field) \
182*ec6f49c2SVinoj Soundararajan (((_esr_el3) >> EABORT_ ##_field ##_SHIFT) & EABORT_ ##_field ##_MASK)
183*ec6f49c2SVinoj Soundararajan
184b56dc2a9SJeenu Viswambharan /* DFSC code for SErrors */
185b56dc2a9SJeenu Viswambharan #define DFSC_SERROR 0x11
186b56dc2a9SJeenu Viswambharan
187b56dc2a9SJeenu Viswambharan /* I/DFSC code for synchronous external abort */
188b56dc2a9SJeenu Viswambharan #define SYNC_EA_FSC 0x10
189b56dc2a9SJeenu Viswambharan
190d5dfdeb6SJulius Werner #ifndef __ASSEMBLER__
191b56dc2a9SJeenu Viswambharan
192b56dc2a9SJeenu Viswambharan #include <arch.h>
193b56dc2a9SJeenu Viswambharan #include <arch_helpers.h>
194b56dc2a9SJeenu Viswambharan #include <assert.h>
195b56dc2a9SJeenu Viswambharan #include <context.h>
19609d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
197b56dc2a9SJeenu Viswambharan #include <stdint.h>
19830d81c36SJeenu Viswambharan
19930d81c36SJeenu Viswambharan /*
20030d81c36SJeenu Viswambharan * Standard Error Record accessors for memory-mapped registers.
20130d81c36SJeenu Viswambharan */
20230d81c36SJeenu Viswambharan
ser_get_feature(uintptr_t base,unsigned int idx)20330d81c36SJeenu Viswambharan static inline uint64_t ser_get_feature(uintptr_t base, unsigned int idx)
20430d81c36SJeenu Viswambharan {
20530d81c36SJeenu Viswambharan return mmio_read_64(base + ERR_FR(idx));
20630d81c36SJeenu Viswambharan }
20730d81c36SJeenu Viswambharan
ser_get_control(uintptr_t base,unsigned int idx)20830d81c36SJeenu Viswambharan static inline uint64_t ser_get_control(uintptr_t base, unsigned int idx)
20930d81c36SJeenu Viswambharan {
21030d81c36SJeenu Viswambharan return mmio_read_64(base + ERR_CTLR(idx));
21130d81c36SJeenu Viswambharan }
21230d81c36SJeenu Viswambharan
ser_get_status(uintptr_t base,unsigned int idx)21330d81c36SJeenu Viswambharan static inline uint64_t ser_get_status(uintptr_t base, unsigned int idx)
21430d81c36SJeenu Viswambharan {
21530d81c36SJeenu Viswambharan return mmio_read_64(base + ERR_STATUS(idx));
21630d81c36SJeenu Viswambharan }
21730d81c36SJeenu Viswambharan
21830d81c36SJeenu Viswambharan /*
21930d81c36SJeenu Viswambharan * Error handling agent would write to the status register to clear an
22030d81c36SJeenu Viswambharan * identified/handled error. Most fields in the status register are
22130d81c36SJeenu Viswambharan * conditional write-one-to-clear.
22230d81c36SJeenu Viswambharan *
22330d81c36SJeenu Viswambharan * Typically, to clear the status, it suffices to write back the same value
22430d81c36SJeenu Viswambharan * previously read. However, if there were new, higher-priority errors recorded
22530d81c36SJeenu Viswambharan * on the node since status was last read, writing read value won't clear the
22630d81c36SJeenu Viswambharan * status. Therefore, an error handling agent must wait on and verify the status
22730d81c36SJeenu Viswambharan * has indeed been cleared.
22830d81c36SJeenu Viswambharan */
ser_set_status(uintptr_t base,unsigned int idx,uint64_t status)22930d81c36SJeenu Viswambharan static inline void ser_set_status(uintptr_t base, unsigned int idx,
23030d81c36SJeenu Viswambharan uint64_t status)
23130d81c36SJeenu Viswambharan {
23230d81c36SJeenu Viswambharan mmio_write_64(base + ERR_STATUS(idx), status);
23330d81c36SJeenu Viswambharan }
23430d81c36SJeenu Viswambharan
ser_get_addr(uintptr_t base,unsigned int idx)23530d81c36SJeenu Viswambharan static inline uint64_t ser_get_addr(uintptr_t base, unsigned int idx)
23630d81c36SJeenu Viswambharan {
23730d81c36SJeenu Viswambharan return mmio_read_64(base + ERR_ADDR(idx));
23830d81c36SJeenu Viswambharan }
23930d81c36SJeenu Viswambharan
ser_get_misc0(uintptr_t base,unsigned int idx)24030d81c36SJeenu Viswambharan static inline uint64_t ser_get_misc0(uintptr_t base, unsigned int idx)
24130d81c36SJeenu Viswambharan {
24230d81c36SJeenu Viswambharan return mmio_read_64(base + ERR_MISC0(idx));
24330d81c36SJeenu Viswambharan }
24430d81c36SJeenu Viswambharan
ser_get_misc1(uintptr_t base,unsigned int idx)24530d81c36SJeenu Viswambharan static inline uint64_t ser_get_misc1(uintptr_t base, unsigned int idx)
24630d81c36SJeenu Viswambharan {
24730d81c36SJeenu Viswambharan return mmio_read_64(base + ERR_MISC1(idx));
24830d81c36SJeenu Viswambharan }
24930d81c36SJeenu Viswambharan
25030d81c36SJeenu Viswambharan
25130d81c36SJeenu Viswambharan /*
25230d81c36SJeenu Viswambharan * Standard Error Record helpers for System registers.
25330d81c36SJeenu Viswambharan */
ser_sys_select_record(unsigned int idx)25430d81c36SJeenu Viswambharan static inline void ser_sys_select_record(unsigned int idx)
25530d81c36SJeenu Viswambharan {
25630a8d96eSJeenu Viswambharan unsigned int max_idx __unused =
25730a8d96eSJeenu Viswambharan (unsigned int) read_erridr_el1() & ERRIDR_MASK;
25830d81c36SJeenu Viswambharan
25930d81c36SJeenu Viswambharan assert(idx < max_idx);
26030d81c36SJeenu Viswambharan
26130d81c36SJeenu Viswambharan write_errselr_el1(idx);
26230d81c36SJeenu Viswambharan isb();
26330d81c36SJeenu Viswambharan }
26430d81c36SJeenu Viswambharan
26530d81c36SJeenu Viswambharan /* Library functions to probe Standard Error Record */
26630d81c36SJeenu Viswambharan int ser_probe_memmap(uintptr_t base, unsigned int size_num_k, int *probe_data);
26730d81c36SJeenu Viswambharan int ser_probe_sysreg(unsigned int idx_start, unsigned int num_idx, int *probe_data);
268d5dfdeb6SJulius Werner #endif /* __ASSEMBLER__ */
26930d81c36SJeenu Viswambharan
270b56dc2a9SJeenu Viswambharan #endif /* RAS_ARCH_H */
271