summaryrefslogtreecommitdiff
path: root/target/hppa/int_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2017-10-21 22:53:35 -0700
committerRichard Henderson <richard.henderson@linaro.org>2018-01-30 10:08:18 -0800
commitc301f34e798e2921cc4c4d1983512f1499e80996 (patch)
treea51b1ab447993f8157cd42761c7edf83c66dbf67 /target/hppa/int_helper.c
parent660eefe1ca20ac118191bffcd23e721afec94142 (diff)
downloadqemu-c301f34e798e2921cc4c4d1983512f1499e80996.tar.gz
target/hppa: Implement IASQ
Any one TB will have only one space value. If we change spaces, we change TBs. Thus BE and BEV must exit the TB immediately. Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/hppa/int_helper.c')
-rw-r--r--target/hppa/int_helper.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index a59aae1189..02963b80c6 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -32,6 +32,8 @@ void hppa_cpu_do_interrupt(CPUState *cs)
int i = cs->exception_index;
target_ureg iaoq_f = env->iaoq_f;
target_ureg iaoq_b = env->iaoq_b;
+ uint64_t iasq_f = env->iasq_f;
+ uint64_t iasq_b = env->iasq_b;
#ifndef CONFIG_USER_ONLY
target_ureg old_psw;
@@ -44,6 +46,8 @@ void hppa_cpu_do_interrupt(CPUState *cs)
cpu_hppa_put_psw(env, PSW_W | (i == EXCP_HPMC ? PSW_M : 0));
/* step 3 */
+ env->cr[CR_IIASQ] = iasq_f >> 32;
+ env->cr_back[0] = iasq_b >> 32;
env->cr[CR_IIAOQ] = iaoq_f;
env->cr_back[1] = iaoq_b;
@@ -79,6 +83,9 @@ void hppa_cpu_do_interrupt(CPUState *cs)
hwaddr paddr;
paddr = vaddr = iaoq_f & -4;
+ if (old_psw & PSW_C) {
+ vaddr = hppa_form_gva_psw(old_psw, iasq_f, iaoq_f & -4);
+ }
env->cr[CR_IIR] = ldl_phys(cs->as, paddr);
}
break;
@@ -101,6 +108,8 @@ void hppa_cpu_do_interrupt(CPUState *cs)
/* step 7 */
env->iaoq_f = env->cr[CR_IVA] + 32 * i;
env->iaoq_b = env->iaoq_f + 4;
+ env->iasq_f = 0;
+ env->iasq_b = 0;
#endif
if (qemu_loglevel_mask(CPU_LOG_INT)) {
@@ -151,10 +160,11 @@ void hppa_cpu_do_interrupt(CPUState *cs)
qemu_log("INT %6d: %s @ " TARGET_FMT_lx "," TARGET_FMT_lx
" -> " TREG_FMT_lx " " TARGET_FMT_lx "\n",
++count, name,
- (target_ulong)iaoq_f,
- (target_ulong)iaoq_b,
+ hppa_form_gva(env, iasq_f, iaoq_f),
+ hppa_form_gva(env, iasq_b, iaoq_b),
env->iaoq_f,
- (target_ulong)env->cr[CR_IOR]);
+ hppa_form_gva(env, (uint64_t)env->cr[CR_ISR] << 32,
+ env->cr[CR_IOR]));
}
cs->exception_index = -1;
}