I cannot understand source code in legalize_privilege() shown below:
reg_t processor_t::legalize_privilege(reg_t prv)
{
if (!supports_extension('U'))
return PRV_M;
if (prv == PRV_HS || (prv == PRV_S && !supports_extension('S')))
return PRV_U;
//according to my understanding, HS mode actually works in Supervisor mode. So PRV_S should be returned here.
return prv;
}
PRV_HSis only used as a dummy privilege level within the simulator for CSR permission checks.In the H-extension specification, HS-mode takes the place of S-mode (level
1).The integer value
2is used forPRV_HSto distinguish it fromPRV_S, but that is a reserved value in the RISC-V Privileged Architecture (ISA Manual Vol. 2 § 1.2 Privilege Levels) and not used by the H-extension.It is therefore illegal to actually set this mode. To set either HS- or S-mode, always use
PRV_S.In the same condition, you can also see that it is illegal to set S-mode if the S-extension is not supported.
Both of these cases are illegal, so the privilege level is instead forced to the lowest level, which is
PRV_U.The only use of
PRV_HSis in the permission check segment ofprocessor_t::get_csr(here), where it is used instead ofPRV_Sif the processor is not in a virtual state (as set byprocessor_t::set_virt), to permit access to Hypervisor CSRs.This is because the CSR address encodes the minimum privilege level required for access in bits [9:8], which is defined as
10b = 2for Hypervisor CSRs, even though there is no such distinct privilege level (ISA Manual Vol. 2 § 2.1 CSR Address Mapping Conventions).