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