• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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