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