target/hppa: Define hardware exception types

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2017-10-11 10:03:02 -07:00
parent ba1d0b4482
commit 2986721df7
6 changed files with 110 additions and 32 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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,