xref: /optee_os/core/arch/riscv/kernel/csr_detect.S (revision c29c4146b9245568365160d97cc3c913cf4cc6be)
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