target-alpha: Tidy exception constants.
There's no need to attempt to match EXCP_* values with PALcode entry point offsets. Instead, compress all the values to make for more efficient switch statements within QEMU. We will be doing TLB fill within QEMU proper, not within the PALcode, so all of the ITB/DTB miss, double fault, and access exceptions can be compressed to EXCP_MMFAULT. Compress all of the EXCP_CALL_PAL exceptions into one. Use env->error_code to store the specific entry point. Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
b758aca1f6
commit
07b6c13b09
@ -2508,19 +2508,13 @@ void cpu_loop (CPUState *env)
|
|||||||
fprintf(stderr, "Machine check exception. Exit\n");
|
fprintf(stderr, "Machine check exception. Exit\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
case EXCP_ARITH:
|
case EXCP_SMP_INTERRUPT:
|
||||||
env->lock_addr = -1;
|
case EXCP_CLK_INTERRUPT:
|
||||||
info.si_signo = TARGET_SIGFPE;
|
case EXCP_DEV_INTERRUPT:
|
||||||
info.si_errno = 0;
|
|
||||||
info.si_code = TARGET_FPE_FLTINV;
|
|
||||||
info._sifields._sigfault._addr = env->pc;
|
|
||||||
queue_signal(env, info.si_signo, &info);
|
|
||||||
break;
|
|
||||||
case EXCP_HW_INTERRUPT:
|
|
||||||
fprintf(stderr, "External interrupt. Exit\n");
|
fprintf(stderr, "External interrupt. Exit\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
case EXCP_DFAULT:
|
case EXCP_MMFAULT:
|
||||||
env->lock_addr = -1;
|
env->lock_addr = -1;
|
||||||
info.si_signo = TARGET_SIGSEGV;
|
info.si_signo = TARGET_SIGSEGV;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
@ -2529,22 +2523,6 @@ void cpu_loop (CPUState *env)
|
|||||||
info._sifields._sigfault._addr = env->trap_arg0;
|
info._sifields._sigfault._addr = env->trap_arg0;
|
||||||
queue_signal(env, info.si_signo, &info);
|
queue_signal(env, info.si_signo, &info);
|
||||||
break;
|
break;
|
||||||
case EXCP_DTB_MISS_PAL:
|
|
||||||
fprintf(stderr, "MMU data TLB miss in PALcode\n");
|
|
||||||
exit(1);
|
|
||||||
break;
|
|
||||||
case EXCP_ITB_MISS:
|
|
||||||
fprintf(stderr, "MMU instruction TLB miss\n");
|
|
||||||
exit(1);
|
|
||||||
break;
|
|
||||||
case EXCP_ITB_ACV:
|
|
||||||
fprintf(stderr, "MMU instruction access violation\n");
|
|
||||||
exit(1);
|
|
||||||
break;
|
|
||||||
case EXCP_DTB_MISS_NATIVE:
|
|
||||||
fprintf(stderr, "MMU data TLB miss\n");
|
|
||||||
exit(1);
|
|
||||||
break;
|
|
||||||
case EXCP_UNALIGN:
|
case EXCP_UNALIGN:
|
||||||
env->lock_addr = -1;
|
env->lock_addr = -1;
|
||||||
info.si_signo = TARGET_SIGBUS;
|
info.si_signo = TARGET_SIGBUS;
|
||||||
@ -2562,12 +2540,20 @@ void cpu_loop (CPUState *env)
|
|||||||
info._sifields._sigfault._addr = env->pc;
|
info._sifields._sigfault._addr = env->pc;
|
||||||
queue_signal(env, info.si_signo, &info);
|
queue_signal(env, info.si_signo, &info);
|
||||||
break;
|
break;
|
||||||
|
case EXCP_ARITH:
|
||||||
|
env->lock_addr = -1;
|
||||||
|
info.si_signo = TARGET_SIGFPE;
|
||||||
|
info.si_errno = 0;
|
||||||
|
info.si_code = TARGET_FPE_FLTINV;
|
||||||
|
info._sifields._sigfault._addr = env->pc;
|
||||||
|
queue_signal(env, info.si_signo, &info);
|
||||||
|
break;
|
||||||
case EXCP_FEN:
|
case EXCP_FEN:
|
||||||
/* No-op. Linux simply re-enables the FPU. */
|
/* No-op. Linux simply re-enables the FPU. */
|
||||||
break;
|
break;
|
||||||
case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1):
|
case EXCP_CALL_PAL:
|
||||||
env->lock_addr = -1;
|
env->lock_addr = -1;
|
||||||
switch ((trapnr >> 6) | 0x80) {
|
switch (env->error_code) {
|
||||||
case 0x80:
|
case 0x80:
|
||||||
/* BPT */
|
/* BPT */
|
||||||
info.si_signo = TARGET_SIGTRAP;
|
info.si_signo = TARGET_SIGTRAP;
|
||||||
@ -2658,8 +2644,6 @@ void cpu_loop (CPUState *env)
|
|||||||
goto do_sigill;
|
goto do_sigill;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1):
|
|
||||||
goto do_sigill;
|
|
||||||
case EXCP_DEBUG:
|
case EXCP_DEBUG:
|
||||||
info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP);
|
info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP);
|
||||||
if (info.si_signo) {
|
if (info.si_signo) {
|
||||||
|
@ -289,26 +289,20 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
EXCP_RESET = 0x0000,
|
EXCP_RESET,
|
||||||
EXCP_MCHK = 0x0020,
|
EXCP_MCHK,
|
||||||
EXCP_ARITH = 0x0060,
|
EXCP_SMP_INTERRUPT,
|
||||||
EXCP_HW_INTERRUPT = 0x00E0,
|
EXCP_CLK_INTERRUPT,
|
||||||
EXCP_DFAULT = 0x01E0,
|
EXCP_DEV_INTERRUPT,
|
||||||
EXCP_DTB_MISS_PAL = 0x09E0,
|
EXCP_MMFAULT,
|
||||||
EXCP_ITB_MISS = 0x03E0,
|
EXCP_UNALIGN,
|
||||||
EXCP_ITB_ACV = 0x07E0,
|
EXCP_OPCDEC,
|
||||||
EXCP_DTB_MISS_NATIVE = 0x08E0,
|
EXCP_ARITH,
|
||||||
EXCP_UNALIGN = 0x11E0,
|
EXCP_FEN,
|
||||||
EXCP_OPCDEC = 0x13E0,
|
EXCP_CALL_PAL,
|
||||||
EXCP_FEN = 0x17E0,
|
/* For Usermode emulation. */
|
||||||
EXCP_CALL_PAL = 0x2000,
|
EXCP_STL_C,
|
||||||
EXCP_CALL_PALP = 0x3000,
|
EXCP_STQ_C,
|
||||||
EXCP_CALL_PALE = 0x4000,
|
|
||||||
/* Pseudo exception for console */
|
|
||||||
EXCP_CONSOLE_DISPATCH = 0x4001,
|
|
||||||
EXCP_CONSOLE_FIXUP = 0x4002,
|
|
||||||
EXCP_STL_C = 0x4003,
|
|
||||||
EXCP_STQ_C = 0x4004,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Arithmetic exception */
|
/* Arithmetic exception */
|
||||||
|
@ -164,10 +164,7 @@ void cpu_alpha_store_fpcr (CPUState *env, uint64_t val)
|
|||||||
int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||||
int mmu_idx, int is_softmmu)
|
int mmu_idx, int is_softmmu)
|
||||||
{
|
{
|
||||||
if (rw == 2)
|
env->exception_index = EXCP_MMFAULT;
|
||||||
env->exception_index = EXCP_ITB_MISS;
|
|
||||||
else
|
|
||||||
env->exception_index = EXCP_DFAULT;
|
|
||||||
env->trap_arg0 = address;
|
env->trap_arg0 = address;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1516,7 +1516,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
|
|||||||
#endif
|
#endif
|
||||||
if (palcode >= 0x80 && palcode < 0xC0) {
|
if (palcode >= 0x80 && palcode < 0xC0) {
|
||||||
/* Unprivileged PAL call */
|
/* Unprivileged PAL call */
|
||||||
ret = gen_excp(ctx, EXCP_CALL_PAL + ((palcode & 0x3F) << 6), 0);
|
ret = gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xBF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
@ -1525,7 +1525,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
|
|||||||
if (ctx->mem_idx != MMU_KERNEL_IDX) {
|
if (ctx->mem_idx != MMU_KERNEL_IDX) {
|
||||||
goto invalid_opc;
|
goto invalid_opc;
|
||||||
}
|
}
|
||||||
ret = gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0);
|
ret = gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3F);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Invalid PAL call */
|
/* Invalid PAL call */
|
||||||
|
Loading…
Reference in New Issue
Block a user