xref: /arm-trusted-firmware/plat/arm/board/fvp/fvp_sync_traps.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2022, ARM Limited. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  *
6*91f16700Schasinglulu  * This file just contains demonstration code, to "handle" RNG traps.
7*91f16700Schasinglulu  */
8*91f16700Schasinglulu 
9*91f16700Schasinglulu #include <stdbool.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include <arch.h>
12*91f16700Schasinglulu #include <arch_helpers.h>
13*91f16700Schasinglulu #include <bl31/sync_handle.h>
14*91f16700Schasinglulu #include <context.h>
15*91f16700Schasinglulu 
16*91f16700Schasinglulu /*
17*91f16700Schasinglulu  * SCR_EL3.SCR_TRNDR_BIT also affects execution in EL3, so allow to disable
18*91f16700Schasinglulu  * the trap temporarily.
19*91f16700Schasinglulu  */
20*91f16700Schasinglulu static void enable_rng_trap(bool enable)
21*91f16700Schasinglulu {
22*91f16700Schasinglulu 	uint64_t scr_el3 = read_scr_el3();
23*91f16700Schasinglulu 
24*91f16700Schasinglulu 	if (enable) {
25*91f16700Schasinglulu 		scr_el3 |= SCR_TRNDR_BIT;
26*91f16700Schasinglulu 	} else {
27*91f16700Schasinglulu 		scr_el3 &= ~SCR_TRNDR_BIT;
28*91f16700Schasinglulu 	}
29*91f16700Schasinglulu 
30*91f16700Schasinglulu 	write_scr_el3(scr_el3);
31*91f16700Schasinglulu 	isb();
32*91f16700Schasinglulu }
33*91f16700Schasinglulu 
34*91f16700Schasinglulu /*
35*91f16700Schasinglulu  * This emulation code here is not very meaningful: enabling the RNG
36*91f16700Schasinglulu  * trap typically happens for a reason, so just calling the actual
37*91f16700Schasinglulu  * hardware instructions might not be useful or even possible.
38*91f16700Schasinglulu  */
39*91f16700Schasinglulu int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx)
40*91f16700Schasinglulu {
41*91f16700Schasinglulu 	/* extract the target register number from the exception syndrome */
42*91f16700Schasinglulu 	unsigned int rt = get_sysreg_iss_rt(esr_el3);
43*91f16700Schasinglulu 
44*91f16700Schasinglulu 	/* ignore XZR accesses and writes to the register */
45*91f16700Schasinglulu 	if (rt == 31 || is_sysreg_iss_write(esr_el3)) {
46*91f16700Schasinglulu 		return TRAP_RET_CONTINUE;
47*91f16700Schasinglulu 	}
48*91f16700Schasinglulu 
49*91f16700Schasinglulu 	enable_rng_trap(false);
50*91f16700Schasinglulu 	if ((esr_el3 & ISS_SYSREG_OPCODE_MASK) == ISS_SYSREG_OPCODE_RNDR) {
51*91f16700Schasinglulu 		ctx->gpregs_ctx.ctx_regs[rt] = read_rndr();
52*91f16700Schasinglulu 	} else {
53*91f16700Schasinglulu 		ctx->gpregs_ctx.ctx_regs[rt] = read_rndrrs();
54*91f16700Schasinglulu 	}
55*91f16700Schasinglulu 	enable_rng_trap(true);
56*91f16700Schasinglulu 
57*91f16700Schasinglulu 	/*
58*91f16700Schasinglulu 	 * We successfully handled the trap, continue with the next
59*91f16700Schasinglulu 	 * instruction.
60*91f16700Schasinglulu 	 */
61*91f16700Schasinglulu 	return TRAP_RET_CONTINUE;
62*91f16700Schasinglulu }
63