ab_riscv_interpreter/zicsr/
zicsr_helpers.rs1use crate::{CsrError, Csrs, ExecutableInstructionCsr};
4use ab_riscv_primitives::prelude::*;
5use core::hint::cold_path;
6
7#[inline(always)]
13#[doc(hidden)]
14#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
15pub const fn check_csr_privilege_level<Reg, C>(csrs: &C, csr_index: u16) -> Result<(), CsrError>
16where
17 Reg: [const] Register,
18 C: [const] Csrs<Reg>,
19{
20 let current = csrs.privilege_level();
21 let required_bits = ((csr_index >> 8u8) & 0b11) as u8;
22 let required = PrivilegeLevel::from_bits(required_bits).unwrap_or(PrivilegeLevel::Machine);
28
29 if current >= required {
30 Ok(())
31 } else {
32 cold_path();
33 Err(CsrError::InsufficientPrivilege {
34 csr_index,
35 required,
36 current,
37 })
38 }
39}
40
41#[inline(always)]
47#[doc(hidden)]
48pub const fn process_csr_read<Reg, Env, I>(
49 env: &Env,
50 csr_index: u16,
51 will_write: bool,
52 raw_value: Reg::Type,
53) -> Result<Reg::Type, CsrError>
54where
55 Reg: [const] Register,
56 I: [const] ExecutableInstructionCsr<Env, Reg = Reg>,
57{
58 let mut out = Reg::Type::default();
59 match I::prepare_csr_read(env, csr_index, will_write, raw_value, &mut out) {
60 Ok(true) => Ok(out),
61 Ok(false) => {
62 cold_path();
63 Err(CsrError::IllegalRead { csr_index })
64 }
65 Err(err) => {
66 cold_path();
67 Err(err)
68 }
69 }
70}
71
72#[inline(always)]
75#[doc(hidden)]
76pub const fn process_csr_write<Reg, Env, I>(
77 env: &mut Env,
78 csr_index: u16,
79 write_value: Reg::Type,
80) -> Result<Reg::Type, CsrError>
81where
82 Reg: [const] Register,
83 I: [const] ExecutableInstructionCsr<Env, Reg = Reg>,
84{
85 let mut out = Reg::Type::default();
86 match I::prepare_csr_write(env, csr_index, write_value, &mut out) {
87 Ok(true) => Ok(out),
88 Ok(false) => {
89 cold_path();
90 Err(CsrError::IllegalWrite { csr_index })
91 }
92 Err(err) => {
93 cold_path();
94 Err(err)
95 }
96 }
97}