mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-18 15:42:09 -06:00
target/hppa: Create raise_exception_with_ior
Handle pa2.0 logic for filling in ISR+IOR. Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
f5b5c85760
commit
8a02b9a68e
1 changed files with 51 additions and 13 deletions
|
@ -289,6 +289,53 @@ hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
return excp == EXCP_DTLB_MISS ? -1 : phys;
|
return excp == EXCP_DTLB_MISS ? -1 : phys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_NORETURN static void
|
||||||
|
raise_exception_with_ior(CPUHPPAState *env, int excp, uintptr_t retaddr,
|
||||||
|
vaddr addr, bool mmu_disabled)
|
||||||
|
{
|
||||||
|
CPUState *cs = env_cpu(env);
|
||||||
|
|
||||||
|
cs->exception_index = excp;
|
||||||
|
|
||||||
|
if (env->psw & PSW_Q) {
|
||||||
|
/*
|
||||||
|
* For pa1.x, the offset and space never overlap, and so we
|
||||||
|
* simply extract the high and low part of the virtual address.
|
||||||
|
*
|
||||||
|
* For pa2.0, the formation of these are described in section
|
||||||
|
* "Interruption Parameter Registers", page 2-15.
|
||||||
|
*/
|
||||||
|
env->cr[CR_IOR] = (uint32_t)addr;
|
||||||
|
env->cr[CR_ISR] = addr >> 32;
|
||||||
|
|
||||||
|
if (hppa_is_pa20(env)) {
|
||||||
|
if (mmu_disabled) {
|
||||||
|
/*
|
||||||
|
* If data translation was disabled, the ISR contains
|
||||||
|
* the upper portion of the abs address, zero-extended.
|
||||||
|
*/
|
||||||
|
env->cr[CR_ISR] &= 0x3fffffff;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* If data translation was enabled, the upper two bits
|
||||||
|
* of the IOR (the b field) are equal to the two space
|
||||||
|
* bits from the base register used to form the gva.
|
||||||
|
*/
|
||||||
|
uint64_t b;
|
||||||
|
|
||||||
|
cpu_restore_state(cs, retaddr);
|
||||||
|
|
||||||
|
b = env->gr[env->unwind_breg];
|
||||||
|
b >>= (env->psw & PSW_W ? 62 : 30);
|
||||||
|
env->cr[CR_IOR] |= b << 62;
|
||||||
|
|
||||||
|
cpu_loop_exit(cs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cpu_loop_exit_restore(cs, retaddr);
|
||||||
|
}
|
||||||
|
|
||||||
bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
|
bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
|
||||||
MMUAccessType type, int mmu_idx,
|
MMUAccessType type, int mmu_idx,
|
||||||
bool probe, uintptr_t retaddr)
|
bool probe, uintptr_t retaddr)
|
||||||
|
@ -318,14 +365,10 @@ bool hppa_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
trace_hppa_tlb_fill_excp(env, addr, size, type, mmu_idx);
|
trace_hppa_tlb_fill_excp(env, addr, size, type, mmu_idx);
|
||||||
|
|
||||||
/* Failure. Raise the indicated exception. */
|
/* Failure. Raise the indicated exception. */
|
||||||
cs->exception_index = excp;
|
raise_exception_with_ior(env, excp, retaddr,
|
||||||
if (cpu->env.psw & PSW_Q) {
|
addr, mmu_idx == MMU_PHYS_IDX);
|
||||||
/* ??? Needs tweaking for hppa64. */
|
|
||||||
cpu->env.cr[CR_IOR] = addr;
|
|
||||||
cpu->env.cr[CR_ISR] = addr >> 32;
|
|
||||||
}
|
|
||||||
cpu_loop_exit_restore(cs, retaddr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_hppa_tlb_fill_success(env, addr & TARGET_PAGE_MASK,
|
trace_hppa_tlb_fill_success(env, addr & TARGET_PAGE_MASK,
|
||||||
|
@ -553,16 +596,11 @@ target_ulong HELPER(lpa)(CPUHPPAState *env, target_ulong addr)
|
||||||
excp = hppa_get_physical_address(env, addr, MMU_KERNEL_IDX, 0,
|
excp = hppa_get_physical_address(env, addr, MMU_KERNEL_IDX, 0,
|
||||||
&phys, &prot, NULL);
|
&phys, &prot, NULL);
|
||||||
if (excp >= 0) {
|
if (excp >= 0) {
|
||||||
if (env->psw & PSW_Q) {
|
|
||||||
/* ??? Needs tweaking for hppa64. */
|
|
||||||
env->cr[CR_IOR] = addr;
|
|
||||||
env->cr[CR_ISR] = addr >> 32;
|
|
||||||
}
|
|
||||||
if (excp == EXCP_DTLB_MISS) {
|
if (excp == EXCP_DTLB_MISS) {
|
||||||
excp = EXCP_NA_DTLB_MISS;
|
excp = EXCP_NA_DTLB_MISS;
|
||||||
}
|
}
|
||||||
trace_hppa_tlb_lpa_failed(env, addr);
|
trace_hppa_tlb_lpa_failed(env, addr);
|
||||||
hppa_dynamic_excp(env, excp, GETPC());
|
raise_exception_with_ior(env, excp, GETPC(), addr, false);
|
||||||
}
|
}
|
||||||
trace_hppa_tlb_lpa_success(env, addr, phys);
|
trace_hppa_tlb_lpa_success(env, addr, phys);
|
||||||
return phys;
|
return phys;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue