1e10bcf3bSAlvin Chang/* SPDX-License-Identifier: BSD-2-Clause */ 2e10bcf3bSAlvin Chang/* 3e10bcf3bSAlvin Chang * Copyright (c) 2024 Andes Technology Corporation 4e10bcf3bSAlvin Chang */ 5e10bcf3bSAlvin Chang 6e10bcf3bSAlvin Chang#include <asm.S> 7e10bcf3bSAlvin Chang#include <riscv.h> 8e10bcf3bSAlvin Chang 9e10bcf3bSAlvin Chang#define DETECT_OP_CSRR 0 10e10bcf3bSAlvin Chang#define DETECT_OP_CSRRW 1 11e10bcf3bSAlvin Chang 12e10bcf3bSAlvin Chang.macro save_and_disable_xie reg 13e10bcf3bSAlvin Chang csrrw \reg, CSR_XIE, zero 14e10bcf3bSAlvin Chang.endm 15e10bcf3bSAlvin Chang 16e10bcf3bSAlvin Chang.macro restore_xie reg 17e10bcf3bSAlvin Chang csrw CSR_XIE, \reg 18e10bcf3bSAlvin Chang.endm 19e10bcf3bSAlvin Chang 20e10bcf3bSAlvin Chang.macro save_and_replace_xtvec reg, label 21e10bcf3bSAlvin Chang la \reg, \label 22e10bcf3bSAlvin Chang csrrw \reg, CSR_XTVEC, \reg 23e10bcf3bSAlvin Chang.endm 24e10bcf3bSAlvin Chang 25e10bcf3bSAlvin Chang.macro restore_xtvec reg 26e10bcf3bSAlvin Chang csrw CSR_XTVEC, \reg 27e10bcf3bSAlvin Chang.endm 28e10bcf3bSAlvin Chang 29e10bcf3bSAlvin Chang/** 30e10bcf3bSAlvin Chang * @brief A temporary trap handler to handle an exception during csr detection. 31e10bcf3bSAlvin Chang * If csr read/write instruction leads to a trap, CPU will enter this 32e10bcf3bSAlvin Chang * function and XRET with a0 = 0, which means the csr is not detected. 33e10bcf3bSAlvin Chang * The caller must expect that a0 is used in this function. 34e10bcf3bSAlvin Chang */ 35e10bcf3bSAlvin ChangFUNC csr_detect_trap_vect , : 36e10bcf3bSAlvin Chang csrr a0, CSR_XEPC 37e10bcf3bSAlvin Chang addi a0, a0, 4 38e10bcf3bSAlvin Chang csrw CSR_XEPC, a0 39e10bcf3bSAlvin Chang mv a0, zero 40e10bcf3bSAlvin Chang XRET 41e10bcf3bSAlvin ChangEND_FUNC csr_detect_trap_vect 42e10bcf3bSAlvin Chang 43e10bcf3bSAlvin Chang/* Detect CSR by csrr/csrrw instruction. a0=1 if detected, otherwise a0=0 */ 44e10bcf3bSAlvin Chang.macro detect_csr csr, op, reg0, reg1, reg2 45*c29c4146SAlvin Chang li a0, 1 46e10bcf3bSAlvin Chang save_and_disable_xie \reg0 47e10bcf3bSAlvin Chang save_and_replace_xtvec \reg1, csr_detect_trap_vect 48e10bcf3bSAlvin Chang.if \op == DETECT_OP_CSRR 49e10bcf3bSAlvin Chang csrr \reg2, \csr 50e10bcf3bSAlvin Chang.elseif \op == DETECT_OP_CSRRW 51e10bcf3bSAlvin Chang csrrw \reg2, \csr, zero 52e10bcf3bSAlvin Chang.endif 53e10bcf3bSAlvin Chang restore_xtvec \reg1 54e10bcf3bSAlvin Chang restore_xie \reg0 55e10bcf3bSAlvin Chang.endm 56e10bcf3bSAlvin Chang 57e10bcf3bSAlvin Chang.macro detect_csr_by_csrr csr, reg0, reg1, reg2 58e10bcf3bSAlvin Chang detect_csr \csr, DETECT_OP_CSRR, \reg0, \reg1, \reg2 59e10bcf3bSAlvin Chang.endm 60e10bcf3bSAlvin Chang 61e10bcf3bSAlvin Chang.macro detect_csr_by_csrrw csr, reg0, reg1, reg2 62e10bcf3bSAlvin Chang detect_csr \csr, DETECT_OP_CSRRW, \reg0, \reg1, \reg2 63e10bcf3bSAlvin Chang.endm 64e10bcf3bSAlvin Chang 65e10bcf3bSAlvin Chang/** 66e10bcf3bSAlvin Chang * bool riscv_detect_csr_seed(void); 67e10bcf3bSAlvin Chang * @brief A helper function to detect if CSR seed is accessible. The value of a0 68e10bcf3bSAlvin Chang * will be cleared by csr_detect_trap_vect() if exception occurs. 69e10bcf3bSAlvin Chang * @retval 1 if CSR seed is detected, otherwise 0 70e10bcf3bSAlvin Chang */ 71e10bcf3bSAlvin ChangFUNC riscv_detect_csr_seed , : 72e10bcf3bSAlvin Chang detect_csr_by_csrrw seed, a1, a2, a3 73e10bcf3bSAlvin Chang ret 74e10bcf3bSAlvin ChangEND_FUNC riscv_detect_csr_seed 75