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