blob: 7d210531bdee66831c8feac6e4f1852654358ca5 [file] [log] [blame]
Jeenu Viswambharan19f6cf22017-12-07 08:43:05 +00001/*
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
160static inline uint64_t ser_get_feature(uintptr_t base, unsigned int idx)
161{
162 return mmio_read_64(base + ERR_FR(idx));
163}
164
165static inline uint64_t ser_get_control(uintptr_t base, unsigned int idx)
166{
167 return mmio_read_64(base + ERR_CTLR(idx));
168}
169
170static 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 */
186static 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
192static inline uint64_t ser_get_addr(uintptr_t base, unsigned int idx)
193{
194 return mmio_read_64(base + ERR_ADDR(idx));
195}
196
197static inline uint64_t ser_get_misc0(uintptr_t base, unsigned int idx)
198{
199 return mmio_read_64(base + ERR_MISC0(idx));
200}
201
202static 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 */
211static 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 */
222int ser_probe_memmap(uintptr_t base, unsigned int size_num_k, int *probe_data);
223int ser_probe_sysreg(unsigned int idx_start, unsigned int num_idx, int *probe_data);
224
225#endif /* __RAS_H__ */