xref: /arm-trusted-firmware/plat/arm/board/fvp/aarch64/fvp_ea.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2023, Arm Limited. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <inttypes.h>
8*91f16700Schasinglulu #include <stdint.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <arch_helpers.h>
11*91f16700Schasinglulu #include <bl31/ea_handle.h>
12*91f16700Schasinglulu #include <common/bl_common.h>
13*91f16700Schasinglulu #include <common/debug.h>
14*91f16700Schasinglulu #include <context.h>
15*91f16700Schasinglulu #include <lib/el3_runtime/context_mgmt.h>
16*91f16700Schasinglulu #include <plat/common/platform.h>
17*91f16700Schasinglulu 
18*91f16700Schasinglulu /*
19*91f16700Schasinglulu  * This source file with custom plat_ea_handler function is compiled only when
20*91f16700Schasinglulu  * building TF-A with compile option PLATFORM_TEST_EA_FFH
21*91f16700Schasinglulu  */
22*91f16700Schasinglulu 
23*91f16700Schasinglulu /* Test address(non-existent) used in tftf to cause External aborts */
24*91f16700Schasinglulu #define TEST_ADDRESS	UL(0x7FFFF000)
25*91f16700Schasinglulu 
26*91f16700Schasinglulu void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
27*91f16700Schasinglulu 		void *handle, uint64_t flags)
28*91f16700Schasinglulu {
29*91f16700Schasinglulu #ifdef PLATFORM_TEST_EA_FFH
30*91f16700Schasinglulu 	u_register_t elr_el3;
31*91f16700Schasinglulu 	u_register_t fault_address;
32*91f16700Schasinglulu 	cpu_context_t *ctx = cm_get_context(NON_SECURE);
33*91f16700Schasinglulu 	el3_state_t *el3_ctx = get_el3state_ctx(ctx);
34*91f16700Schasinglulu 	gp_regs_t *gpregs_ctx = get_gpregs_ctx(ctx);
35*91f16700Schasinglulu 	unsigned int level = (unsigned int)GET_EL(read_spsr_el3());
36*91f16700Schasinglulu 
37*91f16700Schasinglulu 	fault_address = read_ctx_reg(gpregs_ctx, CTX_GPREG_X0);
38*91f16700Schasinglulu 
39*91f16700Schasinglulu 	if ((level < MODE_EL3) && (fault_address == TEST_ADDRESS)) {
40*91f16700Schasinglulu 		if (ea_reason == ERROR_EA_SYNC) {
41*91f16700Schasinglulu 			INFO("Handled sync EA from lower EL at address 0x%lx\n", fault_address);
42*91f16700Schasinglulu 			/* To avoid continuous faults, forward return address */
43*91f16700Schasinglulu 			elr_el3 = read_ctx_reg(el3_ctx, CTX_ELR_EL3);
44*91f16700Schasinglulu 			elr_el3 += 4;
45*91f16700Schasinglulu 			write_ctx_reg(el3_ctx, CTX_ELR_EL3, elr_el3);
46*91f16700Schasinglulu 			return;
47*91f16700Schasinglulu 		} else if (ea_reason == ERROR_EA_ASYNC) {
48*91f16700Schasinglulu 			INFO("Handled Serror from lower EL at address 0x%lx\n", fault_address);
49*91f16700Schasinglulu 			return;
50*91f16700Schasinglulu 		}
51*91f16700Schasinglulu 	}
52*91f16700Schasinglulu #endif
53*91f16700Schasinglulu 	plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags);
54*91f16700Schasinglulu }
55