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