xref: /arm-trusted-firmware/plat/ax/laguna/lua_ras.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /* SPDX-License-Identifier: BSD-3-Clause */
2*91f16700Schasinglulu /*
3*91f16700Schasinglulu  * Copyright (C) 2024, Charleye <wangkart@aliyun.com>
4*91f16700Schasinglulu  * All rights reserved.
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu #include <lib/extensions/ras.h>
7*91f16700Schasinglulu #include <services/sdei.h>
8*91f16700Schasinglulu #include <plat/common/platform.h>
9*91f16700Schasinglulu #include <lib/libc/aarch64/inttypes_.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu static int injected_fault_handler(const struct err_record_info *info,
12*91f16700Schasinglulu 		int probe_data, const struct err_handler_data *const data)
13*91f16700Schasinglulu {
14*91f16700Schasinglulu 	uint64_t status;
15*91f16700Schasinglulu 	uint64_t misc0;
16*91f16700Schasinglulu 	uint32_t intr;
17*91f16700Schasinglulu 	// int ret;
18*91f16700Schasinglulu 
19*91f16700Schasinglulu 	intr = data->interrupt;
20*91f16700Schasinglulu 
21*91f16700Schasinglulu 	NOTICE("ERXMISC0_EL1 = 0x%lx\n", read_erxmisc0_el1());
22*91f16700Schasinglulu 	NOTICE("ERXSTATUS_EL1 = 0x%lx\n", read_erxstatus_el1());
23*91f16700Schasinglulu 	NOTICE("Raw Interrupt: %d\n", intr);
24*91f16700Schasinglulu 	/*
25*91f16700Schasinglulu 	 * The faulting error record is already selected by the SER probe
26*91f16700Schasinglulu 	 * function.
27*91f16700Schasinglulu 	 */
28*91f16700Schasinglulu 	status = read_erxstatus_el1();
29*91f16700Schasinglulu 	/* Clear error */
30*91f16700Schasinglulu 	write_erxstatus_el1(status);
31*91f16700Schasinglulu 	isb();
32*91f16700Schasinglulu 	dsb();
33*91f16700Schasinglulu 	NOTICE("[Cleared] ERXMISC0_EL1 = 0x%lx\n", read_erxmisc0_el1());
34*91f16700Schasinglulu 	NOTICE("[Cleared] ERXSTATUS_EL1 = 0x%lx\n", read_erxstatus_el1());
35*91f16700Schasinglulu 
36*91f16700Schasinglulu 	ERROR("Fault reported by system error record %d on 0x%lx: status=0x%" PRIx64 "\n",
37*91f16700Schasinglulu 			probe_data, read_mpidr_el1(), status);
38*91f16700Schasinglulu 	ERROR(" exception reason=%u syndrome=0x%" PRIx64 "\n", data->ea_reason,
39*91f16700Schasinglulu 			data->flags);
40*91f16700Schasinglulu 
41*91f16700Schasinglulu 	misc0 = read_erxmisc0_el1();
42*91f16700Schasinglulu 
43*91f16700Schasinglulu 	/* Clear Other Error Count Overflow */
44*91f16700Schasinglulu 	if (misc0 & BIT(47)) {
45*91f16700Schasinglulu 		misc0 &= ~BIT(47);
46*91f16700Schasinglulu 		misc0 &= ~GENMASK_64(46, 40);
47*91f16700Schasinglulu 		write_erxmisc0_el1(misc0);
48*91f16700Schasinglulu 	}
49*91f16700Schasinglulu 
50*91f16700Schasinglulu 	/* Clear Repeat Error Count Overflow */
51*91f16700Schasinglulu 	if (misc0 & BIT(39)) {
52*91f16700Schasinglulu 		misc0 &= ~BIT(39);
53*91f16700Schasinglulu 		misc0 &= ~GENMASK_64(38, 32);
54*91f16700Schasinglulu 		write_erxmisc0_el1(misc0);
55*91f16700Schasinglulu 	}
56*91f16700Schasinglulu 
57*91f16700Schasinglulu 	/* Clear errors again
58*91f16700Schasinglulu 	 * It might clear more than one error(CE and UC)
59*91f16700Schasinglulu 	 * at the same time.
60*91f16700Schasinglulu 	 */
61*91f16700Schasinglulu 	status = read_erxstatus_el1();
62*91f16700Schasinglulu 	write_erxstatus_el1(status);
63*91f16700Schasinglulu 	plat_ic_end_of_interrupt(intr);
64*91f16700Schasinglulu 
65*91f16700Schasinglulu 	// ret = sdei_dispatch_event(5001);
66*91f16700Schasinglulu 	// if (ret < 0) {
67*91f16700Schasinglulu 	// 	ERROR("Can't dispatch event to SDEI\n");
68*91f16700Schasinglulu 	// 	panic();
69*91f16700Schasinglulu 	// } else {
70*91f16700Schasinglulu 	// 	INFO("SDEI event dispatched\n");
71*91f16700Schasinglulu 	// }
72*91f16700Schasinglulu 
73*91f16700Schasinglulu 	return 0;
74*91f16700Schasinglulu }
75*91f16700Schasinglulu 
76*91f16700Schasinglulu void plat_handle_uncontainable_ea(void)
77*91f16700Schasinglulu {
78*91f16700Schasinglulu 	/* Do not change the string, CI expects it. Wait forever */
79*91f16700Schasinglulu 	INFO("Injected Uncontainable Error\n");
80*91f16700Schasinglulu 	while (true) {
81*91f16700Schasinglulu 		wfe();
82*91f16700Schasinglulu 	}
83*91f16700Schasinglulu }
84*91f16700Schasinglulu 
85*91f16700Schasinglulu struct err_record_info lua_err_records[] = {
86*91f16700Schasinglulu 	/* Record for injected fault */
87*91f16700Schasinglulu 	ERR_RECORD_SYSREG_V1(0, 2, ras_err_ser_probe_sysreg,
88*91f16700Schasinglulu 			injected_fault_handler, NULL),
89*91f16700Schasinglulu };
90*91f16700Schasinglulu REGISTER_ERR_RECORD_INFO(lua_err_records);
91*91f16700Schasinglulu 
92*91f16700Schasinglulu struct ras_interrupt lua_ras_interrupts[] = {
93*91f16700Schasinglulu 	{
94*91f16700Schasinglulu 		.intr_number = PLAT_LUA_DSU_ERRIRQ,
95*91f16700Schasinglulu 		.err_record = &lua_err_records[0],
96*91f16700Schasinglulu 	},
97*91f16700Schasinglulu 	{
98*91f16700Schasinglulu 		.intr_number = PLAT_LUA_DSU_FAULTIRQ,
99*91f16700Schasinglulu 		.err_record = &lua_err_records[0],
100*91f16700Schasinglulu 	},
101*91f16700Schasinglulu 	{
102*91f16700Schasinglulu 		.intr_number = PLAT_LUA_CPU0_ERRIRQ,
103*91f16700Schasinglulu 		.err_record = &lua_err_records[0],
104*91f16700Schasinglulu 	},
105*91f16700Schasinglulu 	{
106*91f16700Schasinglulu 		.intr_number = PLAT_LUA_CPU1_ERRIRQ,
107*91f16700Schasinglulu 		.err_record = &lua_err_records[0],
108*91f16700Schasinglulu 	},
109*91f16700Schasinglulu 	{
110*91f16700Schasinglulu 		.intr_number = PLAT_LUA_CPU2_ERRIRQ,
111*91f16700Schasinglulu 		.err_record = &lua_err_records[0],
112*91f16700Schasinglulu 	},
113*91f16700Schasinglulu 	{
114*91f16700Schasinglulu 		.intr_number = PLAT_LUA_CPU3_ERRIRQ,
115*91f16700Schasinglulu 		.err_record = &lua_err_records[0],
116*91f16700Schasinglulu 	},
117*91f16700Schasinglulu 	{
118*91f16700Schasinglulu 		.intr_number = PLAT_LUA_CPU0_FAULTIRQ,
119*91f16700Schasinglulu 		.err_record = &lua_err_records[0],
120*91f16700Schasinglulu 	},
121*91f16700Schasinglulu 	{
122*91f16700Schasinglulu 		.intr_number = PLAT_LUA_CPU1_FAULTIRQ,
123*91f16700Schasinglulu 		.err_record = &lua_err_records[0],
124*91f16700Schasinglulu 	},
125*91f16700Schasinglulu 	{
126*91f16700Schasinglulu 		.intr_number = PLAT_LUA_CPU2_FAULTIRQ,
127*91f16700Schasinglulu 		.err_record = &lua_err_records[0],
128*91f16700Schasinglulu 	},
129*91f16700Schasinglulu 	{
130*91f16700Schasinglulu 		.intr_number = PLAT_LUA_CPU3_FAULTIRQ,
131*91f16700Schasinglulu 		.err_record = &lua_err_records[0],
132*91f16700Schasinglulu 	},
133*91f16700Schasinglulu };
134*91f16700Schasinglulu REGISTER_RAS_INTERRUPTS(lua_ras_interrupts);
135