1 /*
2 * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
3 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include <stdbool.h>
9
10 #include <arch_helpers.h>
11 #include <bl31/ea_handle.h>
12 #include <bl31/ehf.h>
13 #include <common/debug.h>
14 #include <lib/extensions/ras.h>
15 #include <lib/extensions/ras_arch.h>
16 #include <plat/common/platform.h>
17
18 #ifndef PLAT_RAS_PRI
19 # error Platform must define RAS priority value
20 #endif
21
22 /*
23 * Function to convert architecturally-defined primary error code SERR,
24 * bits[7:0] from ERR<n>STATUS to its corresponding error string.
25 */
ras_serr_to_str(unsigned int serr)26 const char *ras_serr_to_str(unsigned int serr)
27 {
28 const char *str[ERROR_STATUS_NUM_SERR] = {
29 "No error",
30 "IMPLEMENTATION DEFINED error",
31 "Data value from (non-associative) internal memory",
32 "IMPLEMENTATION DEFINED pin",
33 "Assertion failure",
34 "Error detected on internal data path",
35 "Data value from associative memory",
36 "Address/control value from associative memory",
37 "Data value from a TLB",
38 "Address/control value from a TLB",
39 "Data value from producer",
40 "Address/control value from producer",
41 "Data value from (non-associative) external memory",
42 "Illegal address (software fault)",
43 "Illegal access (software fault)",
44 "Illegal state (software fault)",
45 "Internal data register",
46 "Internal control register",
47 "Error response from slave",
48 "External timeout",
49 "Internal timeout",
50 "Deferred error from slave not supported at master"
51 };
52
53 /*
54 * All other values are reserved. Reserved values might be defined
55 * in a future version of the architecture
56 */
57 if (serr >= ERROR_STATUS_NUM_SERR)
58 return "unknown SERR";
59
60 return str[serr];
61 }
62
63 /* Handler that receives External Aborts on RAS-capable systems */
ras_ea_handler(unsigned int ea_reason,uint64_t syndrome,void * cookie,void * handle,uint64_t flags)64 int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
65 void *handle, uint64_t flags)
66 {
67 unsigned int i, n_handled = 0;
68 int probe_data, ret;
69 struct err_record_info *info;
70
71 const struct err_handler_data err_data = {
72 .version = ERR_HANDLER_VERSION,
73 .ea_reason = ea_reason,
74 .interrupt = 0,
75 .syndrome = (uint32_t) syndrome,
76 .flags = flags,
77 .cookie = cookie,
78 .handle = handle
79 };
80
81 for_each_err_record_info(i, info) {
82 assert(info->probe != NULL);
83 assert(info->handler != NULL);
84
85 /* Continue probing until the record group signals no error */
86 while (true) {
87 if (info->probe(info, &probe_data) == 0)
88 break;
89
90 /* Handle error */
91 ret = info->handler(info, probe_data, &err_data);
92 if (ret != 0)
93 return ret;
94
95 n_handled++;
96 }
97 }
98
99 return (n_handled != 0U) ? 1 : 0;
100 }
101
102 #if ENABLE_ASSERTIONS
assert_interrupts_sorted(void)103 static void assert_interrupts_sorted(void)
104 {
105 unsigned int i, last;
106 struct ras_interrupt *start = ras_interrupt_mappings.intrs;
107
108 if (ras_interrupt_mappings.num_intrs == 0UL)
109 return;
110
111 last = start[0].intr_number;
112 for (i = 1; i < ras_interrupt_mappings.num_intrs; i++) {
113 assert(start[i].intr_number > last);
114 last = start[i].intr_number;
115 }
116 }
117 #endif
118
119 /*
120 * Given an RAS interrupt number, locate the registered handler and call it. If
121 * no handler was found for the interrupt number, this function panics.
122 */
ras_interrupt_handler(uint32_t intr_raw,uint32_t flags,void * handle,void * cookie)123 static int ras_interrupt_handler(uint32_t intr_raw, uint32_t flags,
124 void *handle, void *cookie)
125 {
126 struct ras_interrupt *ras_inrs = ras_interrupt_mappings.intrs;
127 struct ras_interrupt *selected = NULL;
128 int probe_data = 0;
129 int start, end, mid, ret __unused;
130
131 const struct err_handler_data err_data = {
132 .version = ERR_HANDLER_VERSION,
133 .interrupt = intr_raw,
134 .flags = flags,
135 .cookie = cookie,
136 .handle = handle
137 };
138
139 assert(ras_interrupt_mappings.num_intrs > 0UL);
140
141 start = 0;
142 end = (int) ras_interrupt_mappings.num_intrs;
143 while (start <= end) {
144 mid = ((end + start) / 2);
145 if (intr_raw == ras_inrs[mid].intr_number) {
146 selected = &ras_inrs[mid];
147 break;
148 } else if (intr_raw < ras_inrs[mid].intr_number) {
149 /* Move left */
150 end = mid - 1;
151 } else {
152 /* Move right */
153 start = mid + 1;
154 }
155 }
156
157 if (selected == NULL) {
158 ERROR("RAS interrupt %u has no handler!\n", intr_raw);
159 panic();
160 }
161
162 if (selected->err_record->probe != NULL) {
163 ret = selected->err_record->probe(selected->err_record, &probe_data);
164 assert(ret != 0);
165 }
166
167 /* Call error handler for the record group */
168 assert(selected->err_record->handler != NULL);
169 (void) selected->err_record->handler(selected->err_record, probe_data,
170 &err_data);
171
172 return 0;
173 }
174
ras_init(void)175 void __init ras_init(void)
176 {
177 #if ENABLE_ASSERTIONS
178 /* Check RAS interrupts are sorted */
179 assert_interrupts_sorted();
180 #endif
181
182 /* Register RAS priority handler */
183 ehf_register_priority_handler(PLAT_RAS_PRI, ras_interrupt_handler);
184 }
185