#ifdef CONFIG_USER_ONLY
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
{
return 0;
}
bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
return false;
}
int riscv_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
int access_type, int mmu_idx)
{
cs->exception_index = QEMU_USER_EXCP_FAULT;
return TRANSLATE_FAIL;
}
void riscv_cpu_do_interrupt(CPUState *cs)
{
cs->exception_index = EXCP_NONE; /* mark handled to qemu */
}
#else
... real implementation here ...
#endif
To keep the code flow straight?
> +int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
> +{
> +#ifdef CONFIG_USER_ONLY
> + return 0;
> +#else
Can you do a large section of USER ONLY stubs instead of sprinkling
the ifdefs? E.g.
> +static int get_physical_address(CPURISCVState *env, hwaddr *physical,
> + int *prot, target_ulong address,
> + int access_type, int mmu_idx)
> +{
> + /* NOTE: the env->pc value visible here will not be
> + * correct, but the value visible to the exception handler
> + * (riscv_cpu_do_interrupt) is correct */
> +
> + const int mode = mmu_idx;
Why don't you just name the actual argument mode and mark it const
if really needed?
> +
> + *prot = 0;
> + CPUState *cs = CPU(riscv_env_get_cpu(env));
Clearing out prot just before declaring cs looks a little odd. Especially
the prot clearing can easily be moved past the next branch.
> + if (access_type == MMU_INST_FETCH) { /* inst access */
> + exception = page_fault_exceptions ?
> + RISCV_EXCP_INST_PAGE_FAULT : RISCV_EXCP_INST_ACCESS_FAULT;
> + env->badaddr = address;
> + } else if (access_type == MMU_DATA_STORE) { /* store access */
> + exception = page_fault_exceptions ?
> + RISCV_EXCP_STORE_PAGE_FAULT : RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
> + env->badaddr = address;
> + } else if (access_type == MMU_DATA_LOAD) { /* load access */
> + exception = page_fault_exceptions ?
> + RISCV_EXCP_LOAD_PAGE_FAULT : RISCV_EXCP_LOAD_ACCESS_FAULT;
> + env->badaddr = address;
> + } else {
> + g_assert_not_reached();
Why isn't this a switch statement?
> + if (access_type == MMU_INST_FETCH) {
> + cs->exception_index = RISCV_EXCP_INST_ADDR_MIS;
> + env->badaddr = addr;
> + } else if (access_type == MMU_DATA_STORE) {
> + cs->exception_index = RISCV_EXCP_STORE_AMO_ADDR_MIS;
> + env->badaddr = addr;
> + } else if (access_type == MMU_DATA_LOAD) {
> + cs->exception_index = RISCV_EXCP_LOAD_ADDR_MIS;
> + env->badaddr = addr;
> + } else {
> + g_assert_not_reached();
> + }
Same here.
> + case CSR_SPTBR:
And just as comment on V2: please don't use CSR_SPTBR here, but
CSR_SAPT, and don't even define the CSR_SPTBR cpp symbol.