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