1 /* 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 */ enable_rng_trap(bool enable)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 */ plat_handle_rng_trap(uint64_t esr_el3,cpu_context_t * ctx)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 } 63