fvp_sync_traps.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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. #include <stdbool.h>
  9. #include <arch.h>
  10. #include <arch_helpers.h>
  11. #include <bl31/sync_handle.h>
  12. #include <context.h>
  13. /*
  14. * SCR_EL3.SCR_TRNDR_BIT also affects execution in EL3, so allow to disable
  15. * the trap temporarily.
  16. */
  17. static void enable_rng_trap(bool enable)
  18. {
  19. uint64_t scr_el3 = read_scr_el3();
  20. if (enable) {
  21. scr_el3 |= SCR_TRNDR_BIT;
  22. } else {
  23. scr_el3 &= ~SCR_TRNDR_BIT;
  24. }
  25. write_scr_el3(scr_el3);
  26. isb();
  27. }
  28. /*
  29. * This emulation code here is not very meaningful: enabling the RNG
  30. * trap typically happens for a reason, so just calling the actual
  31. * hardware instructions might not be useful or even possible.
  32. */
  33. int plat_handle_rng_trap(uint64_t esr_el3, cpu_context_t *ctx)
  34. {
  35. /* extract the target register number from the exception syndrome */
  36. unsigned int rt = get_sysreg_iss_rt(esr_el3);
  37. /* ignore XZR accesses and writes to the register */
  38. if (rt == 31 || is_sysreg_iss_write(esr_el3)) {
  39. return TRAP_RET_CONTINUE;
  40. }
  41. enable_rng_trap(false);
  42. if ((esr_el3 & ISS_SYSREG_OPCODE_MASK) == ISS_SYSREG_OPCODE_RNDR) {
  43. ctx->gpregs_ctx.ctx_regs[rt] = read_rndr();
  44. } else {
  45. ctx->gpregs_ctx.ctx_regs[rt] = read_rndrrs();
  46. }
  47. enable_rng_trap(true);
  48. /*
  49. * We successfully handled the trap, continue with the next
  50. * instruction.
  51. */
  52. return TRAP_RET_CONTINUE;
  53. }