target-ppc: rework exception code
... also remove two warnings. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5989 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
2a3ec4b5b3
commit
e06fcd754e
|
@ -918,7 +918,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
|
||||||
/* we restore the process signal mask as the sigreturn should
|
/* we restore the process signal mask as the sigreturn should
|
||||||
do it (XXX: use sigsetjmp) */
|
do it (XXX: use sigsetjmp) */
|
||||||
sigprocmask(SIG_SETMASK, old_set, NULL);
|
sigprocmask(SIG_SETMASK, old_set, NULL);
|
||||||
raise_exception_err(env, env->exception_index, env->error_code);
|
cpu_loop_exit();
|
||||||
} else {
|
} else {
|
||||||
/* activate soft MMU for this block */
|
/* activate soft MMU for this block */
|
||||||
cpu_resume_from_signal(env, puc);
|
cpu_resume_from_signal(env, puc);
|
||||||
|
|
|
@ -38,9 +38,6 @@ register struct CPUPPCState *env asm(AREG0);
|
||||||
#include "softmmu_exec.h"
|
#include "softmmu_exec.h"
|
||||||
#endif /* !defined(CONFIG_USER_ONLY) */
|
#endif /* !defined(CONFIG_USER_ONLY) */
|
||||||
|
|
||||||
void raise_exception_err (CPUState *env, int exception, int error_code);
|
|
||||||
void raise_exception (CPUState *env, int exception);
|
|
||||||
|
|
||||||
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
|
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
|
||||||
int rw, int access_type);
|
int rw, int access_type);
|
||||||
|
|
||||||
|
|
|
@ -39,24 +39,6 @@
|
||||||
//#define DEBUG_EXCEPTIONS
|
//#define DEBUG_EXCEPTIONS
|
||||||
//#define FLUSH_ALL_TLBS
|
//#define FLUSH_ALL_TLBS
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Exceptions processing */
|
|
||||||
|
|
||||||
void raise_exception_err (CPUState *env, int exception, int error_code)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
printf("Raise exception %3x code : %d\n", exception, error_code);
|
|
||||||
#endif
|
|
||||||
env->exception_index = exception;
|
|
||||||
env->error_code = error_code;
|
|
||||||
cpu_loop_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void raise_exception (CPUState *env, int exception)
|
|
||||||
{
|
|
||||||
helper_raise_exception_err(exception, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* PowerPC MMU emulation */
|
/* PowerPC MMU emulation */
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "def-helper.h"
|
#include "def-helper.h"
|
||||||
|
|
||||||
DEF_HELPER_2(raise_exception_err, void, i32, i32)
|
DEF_HELPER_2(raise_exception_err, void, i32, i32)
|
||||||
DEF_HELPER_0(raise_debug, void)
|
DEF_HELPER_1(raise_exception, void, i32)
|
||||||
DEF_HELPER_3(tw, void, tl, tl, i32)
|
DEF_HELPER_3(tw, void, tl, tl, i32)
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
DEF_HELPER_3(td, void, tl, tl, i32)
|
DEF_HELPER_3(td, void, tl, tl, i32)
|
||||||
|
|
|
@ -32,12 +32,17 @@
|
||||||
|
|
||||||
void helper_raise_exception_err (uint32_t exception, uint32_t error_code)
|
void helper_raise_exception_err (uint32_t exception, uint32_t error_code)
|
||||||
{
|
{
|
||||||
raise_exception_err(env, exception, error_code);
|
#if 0
|
||||||
|
printf("Raise exception %3x code : %d\n", exception, error_code);
|
||||||
|
#endif
|
||||||
|
env->exception_index = exception;
|
||||||
|
env->error_code = error_code;
|
||||||
|
cpu_loop_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_raise_debug (void)
|
void helper_raise_exception (uint32_t exception)
|
||||||
{
|
{
|
||||||
raise_exception(env, EXCP_DEBUG);
|
helper_raise_exception_err(exception, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -315,9 +320,9 @@ void helper_lswx(target_ulong addr, uint32_t reg, uint32_t ra, uint32_t rb)
|
||||||
if (likely(xer_bc != 0)) {
|
if (likely(xer_bc != 0)) {
|
||||||
if (unlikely((ra != 0 && reg < ra && (reg + xer_bc) > ra) ||
|
if (unlikely((ra != 0 && reg < ra && (reg + xer_bc) > ra) ||
|
||||||
(reg < rb && (reg + xer_bc) > rb))) {
|
(reg < rb && (reg + xer_bc) > rb))) {
|
||||||
raise_exception_err(env, POWERPC_EXCP_PROGRAM,
|
helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
|
||||||
POWERPC_EXCP_INVAL |
|
POWERPC_EXCP_INVAL |
|
||||||
POWERPC_EXCP_INVAL_LSWX);
|
POWERPC_EXCP_INVAL_LSWX);
|
||||||
} else {
|
} else {
|
||||||
helper_lsw(addr, xer_bc, reg);
|
helper_lsw(addr, xer_bc, reg);
|
||||||
}
|
}
|
||||||
|
@ -738,7 +743,7 @@ static always_inline uint64_t fload_invalid_op_excp (int op)
|
||||||
/* Update the floating-point enabled exception summary */
|
/* Update the floating-point enabled exception summary */
|
||||||
env->fpscr |= 1 << FPSCR_FEX;
|
env->fpscr |= 1 << FPSCR_FEX;
|
||||||
if (msr_fe0 != 0 || msr_fe1 != 0)
|
if (msr_fe0 != 0 || msr_fe1 != 0)
|
||||||
raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_FP | op);
|
helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_FP | op);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -753,8 +758,8 @@ static always_inline uint64_t float_zero_divide_excp (uint64_t arg1, uint64_t ar
|
||||||
/* Update the floating-point enabled exception summary */
|
/* Update the floating-point enabled exception summary */
|
||||||
env->fpscr |= 1 << FPSCR_FEX;
|
env->fpscr |= 1 << FPSCR_FEX;
|
||||||
if (msr_fe0 != 0 || msr_fe1 != 0) {
|
if (msr_fe0 != 0 || msr_fe1 != 0) {
|
||||||
raise_exception_err(env, POWERPC_EXCP_PROGRAM,
|
helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
|
||||||
POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX);
|
POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Set the result to infinity */
|
/* Set the result to infinity */
|
||||||
|
@ -994,7 +999,7 @@ void helper_float_check_status (void)
|
||||||
(env->error_code & POWERPC_EXCP_FP)) {
|
(env->error_code & POWERPC_EXCP_FP)) {
|
||||||
/* Differred floating-point exception after target FPR update */
|
/* Differred floating-point exception after target FPR update */
|
||||||
if (msr_fe0 != 0 || msr_fe1 != 0)
|
if (msr_fe0 != 0 || msr_fe1 != 0)
|
||||||
raise_exception_err(env, env->exception_index, env->error_code);
|
helper_raise_exception_err(env->exception_index, env->error_code);
|
||||||
} else if (env->fp_status.float_exception_flags & float_flag_overflow) {
|
} else if (env->fp_status.float_exception_flags & float_flag_overflow) {
|
||||||
float_overflow_excp();
|
float_overflow_excp();
|
||||||
} else if (env->fp_status.float_exception_flags & float_flag_underflow) {
|
} else if (env->fp_status.float_exception_flags & float_flag_underflow) {
|
||||||
|
@ -1007,7 +1012,7 @@ void helper_float_check_status (void)
|
||||||
(env->error_code & POWERPC_EXCP_FP)) {
|
(env->error_code & POWERPC_EXCP_FP)) {
|
||||||
/* Differred floating-point exception after target FPR update */
|
/* Differred floating-point exception after target FPR update */
|
||||||
if (msr_fe0 != 0 || msr_fe1 != 0)
|
if (msr_fe0 != 0 || msr_fe1 != 0)
|
||||||
raise_exception_err(env, env->exception_index, env->error_code);
|
helper_raise_exception_err(env->exception_index, env->error_code);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1660,7 +1665,7 @@ void helper_store_msr (target_ulong val)
|
||||||
val = hreg_store_msr(env, val, 0);
|
val = hreg_store_msr(env, val, 0);
|
||||||
if (val != 0) {
|
if (val != 0) {
|
||||||
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
|
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
|
||||||
raise_exception(env, val);
|
helper_raise_exception(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1723,7 +1728,7 @@ void helper_tw (target_ulong arg1, target_ulong arg2, uint32_t flags)
|
||||||
((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
|
((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
|
||||||
((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
|
((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
|
||||||
((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
|
((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
|
||||||
raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
|
helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1735,7 +1740,7 @@ void helper_td (target_ulong arg1, target_ulong arg2, uint32_t flags)
|
||||||
((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
|
((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
|
||||||
((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
|
((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
|
||||||
((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01)))))
|
((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01)))))
|
||||||
raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
|
helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1902,14 +1907,14 @@ target_ulong helper_load_dcr (target_ulong dcrn)
|
||||||
if (loglevel != 0) {
|
if (loglevel != 0) {
|
||||||
fprintf(logfile, "No DCR environment\n");
|
fprintf(logfile, "No DCR environment\n");
|
||||||
}
|
}
|
||||||
raise_exception_err(env, POWERPC_EXCP_PROGRAM,
|
helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
|
||||||
POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
|
POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
|
||||||
} else if (unlikely(ppc_dcr_read(env->dcr_env, dcrn, &val) != 0)) {
|
} else if (unlikely(ppc_dcr_read(env->dcr_env, dcrn, &val) != 0)) {
|
||||||
if (loglevel != 0) {
|
if (loglevel != 0) {
|
||||||
fprintf(logfile, "DCR read error %d %03x\n", (int)dcrn, (int)dcrn);
|
fprintf(logfile, "DCR read error %d %03x\n", (int)dcrn, (int)dcrn);
|
||||||
}
|
}
|
||||||
raise_exception_err(env, POWERPC_EXCP_PROGRAM,
|
helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
|
||||||
POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
|
POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
@ -1920,14 +1925,14 @@ void helper_store_dcr (target_ulong dcrn, target_ulong val)
|
||||||
if (loglevel != 0) {
|
if (loglevel != 0) {
|
||||||
fprintf(logfile, "No DCR environment\n");
|
fprintf(logfile, "No DCR environment\n");
|
||||||
}
|
}
|
||||||
raise_exception_err(env, POWERPC_EXCP_PROGRAM,
|
helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
|
||||||
POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
|
POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
|
||||||
} else if (unlikely(ppc_dcr_write(env->dcr_env, dcrn, val) != 0)) {
|
} else if (unlikely(ppc_dcr_write(env->dcr_env, dcrn, val) != 0)) {
|
||||||
if (loglevel != 0) {
|
if (loglevel != 0) {
|
||||||
fprintf(logfile, "DCR write error %d %03x\n", (int)dcrn, (int)dcrn);
|
fprintf(logfile, "DCR write error %d %03x\n", (int)dcrn, (int)dcrn);
|
||||||
}
|
}
|
||||||
raise_exception_err(env, POWERPC_EXCP_PROGRAM,
|
helper_raise_exception_err(POWERPC_EXCP_PROGRAM,
|
||||||
POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
|
POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2671,7 +2676,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
|
||||||
cpu_restore_state(tb, env, pc, NULL);
|
cpu_restore_state(tb, env, pc, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
raise_exception_err(env, env->exception_index, env->error_code);
|
helper_raise_exception_err(env->exception_index, env->error_code);
|
||||||
}
|
}
|
||||||
env = saved_env;
|
env = saved_env;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -347,7 +347,7 @@ static void spr_write_hid0_601 (void *opaque, int sprn, int gprn)
|
||||||
|
|
||||||
gen_helper_store_hid0_601(cpu_gpr[gprn]);
|
gen_helper_store_hid0_601(cpu_gpr[gprn]);
|
||||||
/* Must stop the translation as endianness may have changed */
|
/* Must stop the translation as endianness may have changed */
|
||||||
GEN_STOP(ctx);
|
gen_stop_exception(ctx);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ static void spr_write_40x_dbcr0 (void *opaque, int sprn, int gprn)
|
||||||
|
|
||||||
gen_helper_store_40x_dbcr0(cpu_gpr[gprn]);
|
gen_helper_store_40x_dbcr0(cpu_gpr[gprn]);
|
||||||
/* We must stop translation as we may have rebooted */
|
/* We must stop translation as we may have rebooted */
|
||||||
GEN_STOP(ctx);
|
gen_stop_exception(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spr_write_40x_sler (void *opaque, int sprn, int gprn)
|
static void spr_write_40x_sler (void *opaque, int sprn, int gprn)
|
||||||
|
@ -466,7 +466,7 @@ static void spr_write_excp_vector (void *opaque, int sprn, int gprn)
|
||||||
} else {
|
} else {
|
||||||
printf("Trying to write an unknown exception vector %d %03x\n",
|
printf("Trying to write an unknown exception vector %d %03x\n",
|
||||||
sprn, sprn);
|
sprn, sprn);
|
||||||
GEN_EXCP_PRIVREG(ctx);
|
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue