diff options
Diffstat (limited to 'target/hppa/int_helper.c')
| -rw-r--r-- | target/hppa/int_helper.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c index 13073ae2bd..f599dccfff 100644 --- a/target/hppa/int_helper.c +++ b/target/hppa/int_helper.c @@ -23,6 +23,7 @@ #include "cpu.h" #include "exec/helper-proto.h" #include "hw/core/cpu.h" +#include "hw/hppa/hppa_hardware.h" #ifndef CONFIG_USER_ONLY static void eval_interrupt(HPPACPU *cpu) @@ -181,7 +182,14 @@ void hppa_cpu_do_interrupt(CPUState *cs) } /* step 7 */ - env->iaoq_f = env->cr[CR_IVA] + 32 * i; + if (i == EXCP_TOC) { + env->iaoq_f = FIRMWARE_START; + /* help SeaBIOS and provide iaoq_b and iasq_back in shadow regs */ + env->gr[24] = env->cr_back[0]; + env->gr[25] = env->cr_back[1]; + } else { + env->iaoq_f = env->cr[CR_IVA] + 32 * i; + } env->iaoq_b = env->iaoq_f + 4; env->iasq_f = 0; env->iasq_b = 0; @@ -219,6 +227,7 @@ void hppa_cpu_do_interrupt(CPUState *cs) [EXCP_PER_INTERRUPT] = "performance monitor interrupt", [EXCP_SYSCALL] = "syscall", [EXCP_SYSCALL_LWS] = "syscall-lws", + [EXCP_TOC] = "TOC (transfer of control)", }; static int count; const char *name = NULL; @@ -248,6 +257,14 @@ bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request) HPPACPU *cpu = HPPA_CPU(cs); CPUHPPAState *env = &cpu->env; + if (interrupt_request & CPU_INTERRUPT_NMI) { + /* Raise TOC (NMI) interrupt */ + cpu_reset_interrupt(cs, CPU_INTERRUPT_NMI); + cs->exception_index = EXCP_TOC; + hppa_cpu_do_interrupt(cs); + return true; + } + /* If interrupts are requested and enabled, raise them. */ if ((env->psw & PSW_I) && (interrupt_request & CPU_INTERRUPT_HARD)) { cs->exception_index = EXCP_EXT_INTERRUPT; |