target/hppa: Handle absolute addresses for pa2.0

With pa2.0, absolute addresses are not the same as physical addresses,
and undergo a transformation based on PSW_W.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-09-17 14:54:16 -07:00
parent 931adff314
commit ccdf741c48
2 changed files with 44 additions and 2 deletions

View File

@ -313,6 +313,9 @@ static inline target_ulong hppa_form_gva(CPUHPPAState *env, uint64_t spc,
return hppa_form_gva_psw(env->psw, spc, off); return hppa_form_gva_psw(env->psw, spc, off);
} }
hwaddr hppa_abs_to_phys_pa2_w0(vaddr addr);
hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr);
/* /*
* Since PSW_{I,CB} will never need to be in tb->flags, reuse them. * Since PSW_{I,CB} will never need to be in tb->flags, reuse them.
* TB_FLAG_SR_SAME indicates that SR4 through SR7 all contain the * TB_FLAG_SR_SAME indicates that SR4 through SR7 all contain the

View File

@ -25,6 +25,45 @@
#include "hw/core/cpu.h" #include "hw/core/cpu.h"
#include "trace.h" #include "trace.h"
hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr)
{
if (likely(extract64(addr, 58, 4) != 0xf)) {
/* Memory address space */
return addr & MAKE_64BIT_MASK(0, 62);
}
if (extract64(addr, 54, 4) != 0) {
/* I/O address space */
return addr | MAKE_64BIT_MASK(62, 2);
}
/* PDC address space */
return (addr & MAKE_64BIT_MASK(0, 54)) | MAKE_64BIT_MASK(60, 4);
}
hwaddr hppa_abs_to_phys_pa2_w0(vaddr addr)
{
if (likely(extract32(addr, 28, 4) != 0xf)) {
/* Memory address space */
return addr & MAKE_64BIT_MASK(0, 32);
}
if (extract32(addr, 24, 4) != 0) {
/* I/O address space */
return addr | MAKE_64BIT_MASK(32, 32);
}
/* PDC address space */
return (addr & MAKE_64BIT_MASK(0, 24)) | MAKE_64BIT_MASK(60, 4);
}
static hwaddr hppa_abs_to_phys(CPUHPPAState *env, vaddr addr)
{
if (!hppa_is_pa20(env)) {
return addr;
} else if (env->psw & PSW_W) {
return hppa_abs_to_phys_pa2_w1(addr);
} else {
return hppa_abs_to_phys_pa2_w0(addr);
}
}
static HPPATLBEntry *hppa_find_tlb(CPUHPPAState *env, vaddr addr) static HPPATLBEntry *hppa_find_tlb(CPUHPPAState *env, vaddr addr)
{ {
IntervalTreeNode *i = interval_tree_iter_first(&env->tlb_root, addr, addr); IntervalTreeNode *i = interval_tree_iter_first(&env->tlb_root, addr, addr);
@ -222,7 +261,7 @@ int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
} }
egress: egress:
*pphys = phys; *pphys = phys = hppa_abs_to_phys(env, phys);
*pprot = prot; *pprot = prot;
trace_hppa_tlb_get_physical_address(env, ret, prot, addr, phys); trace_hppa_tlb_get_physical_address(env, ret, prot, addr, phys);
return ret; return ret;
@ -238,7 +277,7 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
/* ??? We really ought to know if the code mmu is disabled too, /* ??? We really ought to know if the code mmu is disabled too,
in order to get the correct debugging dumps. */ in order to get the correct debugging dumps. */
if (!(cpu->env.psw & PSW_D)) { if (!(cpu->env.psw & PSW_D)) {
return addr; return hppa_abs_to_phys(&cpu->env, addr);
} }
excp = hppa_get_physical_address(&cpu->env, addr, MMU_KERNEL_IDX, 0, excp = hppa_get_physical_address(&cpu->env, addr, MMU_KERNEL_IDX, 0,