@@ -11,6 +11,18 @@ LOG_CATEGORY("machine.csr.control_state");
1111
1212namespace machine { namespace CSR {
1313
14+ static CSR::PrivilegeLevel csr_min_privilege_from_addr (const Address &addr) {
15+ uint32_t csr = addr.data & 0xfffu ; // csr[11:0]
16+ uint32_t min_bits = (csr >> 8 ) & 0x3 ; // csr[9:8] per spec
17+ switch (min_bits) {
18+ case 0u : return PrivilegeLevel::UNPRIVILEGED;
19+ case 1u : return PrivilegeLevel::SUPERVISOR;
20+ case 2u : return PrivilegeLevel::HYPERVISOR;
21+ case 3u : return PrivilegeLevel::MACHINE;
22+ default : return PrivilegeLevel::MACHINE;
23+ }
24+ }
25+
1426 ControlState::ControlState (Xlen xlen, ConfigIsaWord isa_word) : xlen(xlen) {
1527 reset ();
1628 uint64_t misa = read_internal (CSR::Id::MISA).as_u64 ();
@@ -55,19 +67,29 @@ namespace machine { namespace CSR {
5567 }
5668 }
5769
58- RegisterValue ControlState::read (Address address) const {
70+ RegisterValue ControlState::read (Address address, PrivilegeLevel current_privilege ) const {
5971 // Only machine level privilege is supported so no checking is needed.
6072 size_t reg_id = get_register_internal_id (address);
73+ if (PrivilegeLevel min_priv = csr_min_privilege_from_addr (address); current_privilege < min_priv) {
74+ throw SIMULATOR_EXCEPTION (
75+ UnsupportedInstruction,
76+ QString (" CSR %1 inaccessible at current privilege level" ).arg (address.data ), " " );
77+ }
6178 RegisterValue value = register_data[reg_id];
6279 DEBUG (" Read CSR[%u] == 0x%" PRIx64, address.data , value.as_u64 ());
6380 emit read_signal (reg_id, value);
6481 return value;
6582 }
6683
67- void ControlState::write (Address address, RegisterValue value) {
84+ void ControlState::write (Address address, RegisterValue value, PrivilegeLevel current_privilege ) {
6885 DEBUG (
6986 " Write CSR[%u/%zu] <== 0x%zu" , address.data , get_register_internal_id (address),
7087 value.as_u64 ());
88+ if (PrivilegeLevel min_priv = csr_min_privilege_from_addr (address); current_privilege < min_priv) {
89+ throw SIMULATOR_EXCEPTION (
90+ UnsupportedInstruction,
91+ QString (" CSR %1 inaccessible at current privilege level" ).arg (address.data ), " " );
92+ }
7193 // Attempts to write a read-only register also raise illegal instruction exceptions.
7294 if (!address.is_writable ()) {
7395 throw SIMULATOR_EXCEPTION (
0 commit comments