target/hppa: Define hardware exception types
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
ba1d0b4482
commit
2986721df7
@ -3773,21 +3773,41 @@ void cpu_loop(CPUHPPAState *env)
|
||||
env->iaoq_f = env->gr[31];
|
||||
env->iaoq_b = env->gr[31] + 4;
|
||||
break;
|
||||
case EXCP_SIGSEGV:
|
||||
case EXCP_ITLB_MISS:
|
||||
case EXCP_DTLB_MISS:
|
||||
case EXCP_NA_ITLB_MISS:
|
||||
case EXCP_NA_DTLB_MISS:
|
||||
case EXCP_IMP:
|
||||
case EXCP_DMP:
|
||||
case EXCP_DMB:
|
||||
case EXCP_PAGE_REF:
|
||||
case EXCP_DMAR:
|
||||
case EXCP_DMPI:
|
||||
info.si_signo = TARGET_SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_SEGV_ACCERR;
|
||||
info._sifields._sigfault._addr = env->ior;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_SIGILL:
|
||||
case EXCP_UNALIGN:
|
||||
info.si_signo = TARGET_SIGBUS;
|
||||
info.si_errno = 0;
|
||||
info.si_code = 0;
|
||||
info._sifields._sigfault._addr = env->ior;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_ILL:
|
||||
case EXCP_PRIV_OPR:
|
||||
case EXCP_PRIV_REG:
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->iaoq_f;
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
break;
|
||||
case EXCP_SIGFPE:
|
||||
case EXCP_OVERFLOW:
|
||||
case EXCP_COND:
|
||||
case EXCP_ASSIST:
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = 0;
|
||||
|
@ -40,11 +40,40 @@
|
||||
#define MMU_USER_IDX 0
|
||||
#define TARGET_INSN_START_EXTRA_WORDS 1
|
||||
|
||||
#define EXCP_SYSCALL 1
|
||||
#define EXCP_SYSCALL_LWS 2
|
||||
#define EXCP_SIGSEGV 3
|
||||
#define EXCP_SIGILL 4
|
||||
#define EXCP_SIGFPE 5
|
||||
/* Hardware exceptions, interupts, faults, and traps. */
|
||||
#define EXCP_HPMC 1 /* high priority machine check */
|
||||
#define EXCP_POWER_FAIL 2
|
||||
#define EXCP_RC 3 /* recovery counter */
|
||||
#define EXCP_EXT_INTERRUPT 4 /* external interrupt */
|
||||
#define EXCP_LPMC 5 /* low priority machine check */
|
||||
#define EXCP_ITLB_MISS 6 /* itlb miss / instruction page fault */
|
||||
#define EXCP_IMP 7 /* instruction memory protection trap */
|
||||
#define EXCP_ILL 8 /* illegal instruction trap */
|
||||
#define EXCP_BREAK 9 /* break instruction */
|
||||
#define EXCP_PRIV_OPR 10 /* privileged operation trap */
|
||||
#define EXCP_PRIV_REG 11 /* privileged register trap */
|
||||
#define EXCP_OVERFLOW 12 /* signed overflow trap */
|
||||
#define EXCP_COND 13 /* trap-on-condition */
|
||||
#define EXCP_ASSIST 14 /* assist exception trap */
|
||||
#define EXCP_DTLB_MISS 15 /* dtlb miss / data page fault */
|
||||
#define EXCP_NA_ITLB_MISS 16 /* non-access itlb miss */
|
||||
#define EXCP_NA_DTLB_MISS 17 /* non-access dtlb miss */
|
||||
#define EXCP_DMP 18 /* data memory protection trap */
|
||||
#define EXCP_DMB 19 /* data memory break trap */
|
||||
#define EXCP_TLB_DIRTY 20 /* tlb dirty bit trap */
|
||||
#define EXCP_PAGE_REF 21 /* page reference trap */
|
||||
#define EXCP_ASSIST_EMU 22 /* assist emulation trap */
|
||||
#define EXCP_HPT 23 /* high-privilege transfer trap */
|
||||
#define EXCP_LPT 24 /* low-privilege transfer trap */
|
||||
#define EXCP_TB 25 /* taken branch trap */
|
||||
#define EXCP_DMAR 26 /* data memory access rights trap */
|
||||
#define EXCP_DMPI 27 /* data memory protection id trap */
|
||||
#define EXCP_UNALIGN 28 /* unaligned data reference trap */
|
||||
#define EXCP_PER_INTERRUPT 29 /* performance monitor interrupt */
|
||||
|
||||
/* Exceptions for linux-user emulation. */
|
||||
#define EXCP_SYSCALL 30
|
||||
#define EXCP_SYSCALL_LWS 31
|
||||
|
||||
/* Taken from Linux kernel: arch/parisc/include/asm/psw.h */
|
||||
#define PSW_I 0x00000001
|
||||
|
@ -74,25 +74,52 @@ void hppa_cpu_do_interrupt(CPUState *cs)
|
||||
int i = cs->exception_index;
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_INT)) {
|
||||
static const char * const names[] = {
|
||||
[EXCP_HPMC] = "high priority machine check",
|
||||
[EXCP_POWER_FAIL] = "power fail interrupt",
|
||||
[EXCP_RC] = "recovery counter trap",
|
||||
[EXCP_EXT_INTERRUPT] = "external interrupt",
|
||||
[EXCP_LPMC] = "low priority machine check",
|
||||
[EXCP_ITLB_MISS] = "instruction tlb miss fault",
|
||||
[EXCP_IMP] = "instruction memory protection trap",
|
||||
[EXCP_ILL] = "illegal instruction trap",
|
||||
[EXCP_BREAK] = "break instruction trap",
|
||||
[EXCP_PRIV_OPR] = "privileged operation trap",
|
||||
[EXCP_PRIV_REG] = "privileged register trap",
|
||||
[EXCP_OVERFLOW] = "overflow trap",
|
||||
[EXCP_COND] = "conditional trap",
|
||||
[EXCP_ASSIST] = "assist exception trap",
|
||||
[EXCP_DTLB_MISS] = "data tlb miss fault",
|
||||
[EXCP_NA_ITLB_MISS] = "non-access instruction tlb miss",
|
||||
[EXCP_NA_DTLB_MISS] = "non-access data tlb miss",
|
||||
[EXCP_DMP] = "data memory protection trap",
|
||||
[EXCP_DMB] = "data memory break trap",
|
||||
[EXCP_TLB_DIRTY] = "tlb dirty bit trap",
|
||||
[EXCP_PAGE_REF] = "page reference trap",
|
||||
[EXCP_ASSIST_EMU] = "assist emulation trap",
|
||||
[EXCP_HPT] = "high-privilege transfer trap",
|
||||
[EXCP_LPT] = "low-privilege transfer trap",
|
||||
[EXCP_TB] = "taken branch trap",
|
||||
[EXCP_DMAR] = "data memory access rights trap",
|
||||
[EXCP_DMPI] = "data memory protection id trap",
|
||||
[EXCP_UNALIGN] = "unaligned data reference trap",
|
||||
[EXCP_PER_INTERRUPT] = "performance monitor interrupt",
|
||||
[EXCP_SYSCALL] = "syscall",
|
||||
[EXCP_SYSCALL_LWS] = "syscall-lws",
|
||||
};
|
||||
static int count;
|
||||
const char *name = "<unknown>";
|
||||
const char *name = NULL;
|
||||
|
||||
switch (i) {
|
||||
case EXCP_SYSCALL:
|
||||
name = "syscall";
|
||||
break;
|
||||
case EXCP_SIGSEGV:
|
||||
name = "sigsegv";
|
||||
break;
|
||||
case EXCP_SIGILL:
|
||||
name = "sigill";
|
||||
break;
|
||||
case EXCP_SIGFPE:
|
||||
name = "sigfpe";
|
||||
break;
|
||||
if (i >= 0 && i < ARRAY_SIZE(names)) {
|
||||
name = names[i];
|
||||
}
|
||||
if (name) {
|
||||
qemu_log("INT %6d: %s ia_f=" TARGET_FMT_lx "\n",
|
||||
++count, name, env->iaoq_f);
|
||||
} else {
|
||||
qemu_log("INT %6d: unknown %d ia_f=" TARGET_FMT_lx "\n",
|
||||
++count, i, env->iaoq_f);
|
||||
}
|
||||
qemu_log("INT %6d: %s ia_f=" TARGET_FMT_lx "\n",
|
||||
++count, name, env->iaoq_f);
|
||||
}
|
||||
cs->exception_index = -1;
|
||||
}
|
||||
|
@ -29,7 +29,9 @@ int hppa_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
|
||||
{
|
||||
HPPACPU *cpu = HPPA_CPU(cs);
|
||||
|
||||
cs->exception_index = EXCP_SIGSEGV;
|
||||
/* ??? Test between data page fault and data memory protection trap,
|
||||
which would affect si_code. */
|
||||
cs->exception_index = EXCP_DMP;
|
||||
cpu->env.ior = address;
|
||||
return 1;
|
||||
}
|
||||
|
@ -44,14 +44,14 @@ static void QEMU_NORETURN dynexcp(CPUHPPAState *env, int excp, uintptr_t ra)
|
||||
void HELPER(tsv)(CPUHPPAState *env, target_ulong cond)
|
||||
{
|
||||
if (unlikely((target_long)cond < 0)) {
|
||||
dynexcp(env, EXCP_SIGFPE, GETPC());
|
||||
dynexcp(env, EXCP_OVERFLOW, GETPC());
|
||||
}
|
||||
}
|
||||
|
||||
void HELPER(tcond)(CPUHPPAState *env, target_ulong cond)
|
||||
{
|
||||
if (unlikely(cond)) {
|
||||
dynexcp(env, EXCP_SIGFPE, GETPC());
|
||||
dynexcp(env, EXCP_COND, GETPC());
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,7 +235,7 @@ static void update_fr0_op(CPUHPPAState *env, uintptr_t ra)
|
||||
env->fr[0] = (uint64_t)shadow << 32;
|
||||
|
||||
if (hard_exp & shadow) {
|
||||
dynexcp(env, EXCP_SIGFPE, ra);
|
||||
dynexcp(env, EXCP_ASSIST, ra);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,7 +462,7 @@ static DisasJumpType gen_excp(DisasContext *ctx, int exception)
|
||||
static DisasJumpType gen_illegal(DisasContext *ctx)
|
||||
{
|
||||
nullify_over(ctx);
|
||||
return nullify_end(ctx, gen_excp(ctx, EXCP_SIGILL));
|
||||
return nullify_end(ctx, gen_excp(ctx, EXCP_ILL));
|
||||
}
|
||||
|
||||
static bool use_goto_tb(DisasContext *ctx, target_ulong dest)
|
||||
@ -1578,7 +1578,7 @@ static DisasJumpType do_page_zero(DisasContext *ctx)
|
||||
|
||||
switch (ctx->iaoq_f) {
|
||||
case 0x00: /* Null pointer call */
|
||||
gen_excp_1(EXCP_SIGSEGV);
|
||||
gen_excp_1(EXCP_IMP);
|
||||
return DISAS_NORETURN;
|
||||
|
||||
case 0xb0: /* LWS */
|
||||
@ -1597,7 +1597,7 @@ static DisasJumpType do_page_zero(DisasContext *ctx)
|
||||
|
||||
default:
|
||||
do_sigill:
|
||||
gen_excp_1(EXCP_SIGILL);
|
||||
gen_excp_1(EXCP_ILL);
|
||||
return DISAS_NORETURN;
|
||||
}
|
||||
}
|
||||
@ -1614,7 +1614,7 @@ static DisasJumpType trans_break(DisasContext *ctx, uint32_t insn,
|
||||
const DisasInsn *di)
|
||||
{
|
||||
nullify_over(ctx);
|
||||
return nullify_end(ctx, gen_excp(ctx, EXCP_DEBUG));
|
||||
return nullify_end(ctx, gen_excp(ctx, EXCP_BREAK));
|
||||
}
|
||||
|
||||
static DisasJumpType trans_sync(DisasContext *ctx, uint32_t insn,
|
||||
|
Loading…
Reference in New Issue
Block a user