@@ -20,8 +20,35 @@
#include "cpu.h"
#include "exception.h"
-void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp)
+void QEMU_NORETURN do_raise_exception_err(OpenRISCCPU *cpu,
+ uint32_t exception,
+ uintptr_t pc)
{
- cpu->env.exception_index = excp;
+ TranslationBlock *tb;
+
+ /* openrisc cpu has fifteen exceptions */
+ if (exception < 0xe)
+ qemu_log("%s: %d\n", __func__, exception);
+
+ cpu->env.exception_index = exception;
+
+ if (pc) {
+ /* now we have a real cpu fault */
+ tb = tb_find_pc(pc);
+ if (tb) {
+ /* the PC is inside the translated code. It means that we have
+ a virtual CPU fault */
+ cpu_restore_state(tb, &cpu->env, pc);
+ }
+ }
+
cpu_loop_exit(&cpu->env);
}
+
+void QEMU_NORETURN do_raise_exception(OpenRISCCPU *cpu,
+ uint32_t exception,
+ uintptr_t pc)
+{
+ do_raise_exception_err(cpu, exception, pc);
+}
+
@@ -23,6 +23,10 @@
#include "cpu.h"
#include "qemu-common.h"
-void QEMU_NORETURN raise_exception(OpenRISCCPU *cpu, uint32_t excp);
-
+void QEMU_NORETURN do_raise_exception_err(OpenRISCCPU *cpu,
+ uint32_t exception,
+ uintptr_t pc);
+void QEMU_NORETURN do_raise_exception(OpenRISCCPU *cpu,
+ uint32_t exception,
+ uintptr_t pc);
#endif /* QEMU_OPENRISC_EXCP_H */
@@ -25,5 +25,5 @@ void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp)
{
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));
- raise_exception(cpu, excp);
+ do_raise_exception(cpu, excp, 0);
}
@@ -51,17 +51,21 @@ static inline uint32_t ieee_ex_to_openrisc(OpenRISCCPU *cpu, int fexcp)
return ret;
}
-static inline void update_fpcsr(OpenRISCCPU *cpu)
+static inline void update_fpcsr(OpenRISCCPU *cpu, uintptr_t pc)
{
int tmp = ieee_ex_to_openrisc(cpu,
get_float_exception_flags(&cpu->env.fp_status));
SET_FP_CAUSE(cpu->env.fpcsr, tmp);
- if ((GET_FP_ENABLE(cpu->env.fpcsr) & tmp) &&
- (cpu->env.fpcsr & FPCSR_FPEE)) {
- helper_exception(&cpu->env, EXCP_FPE);
- } else {
- UPDATE_FP_FLAGS(cpu->env.fpcsr, tmp);
+ if (tmp) {
+ set_float_exception_flags(0, &cpu->env.fp_status);
+
+ if ((GET_FP_ENABLE(cpu->env.fpcsr) & tmp) &&
+ (cpu->env.fpcsr & FPCSR_FPEE)) {
+ do_raise_exception(cpu, EXCP_FPE, pc);
+ } else {
+ UPDATE_FP_FLAGS(cpu->env.fpcsr, tmp);
+ }
}
}
@@ -72,7 +76,7 @@ uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
set_float_exception_flags(0, &cpu->env.fp_status);
itofd = int32_to_float64(val, &cpu->env.fp_status);
- update_fpcsr(cpu);
+ update_fpcsr(cpu, GETPC());
return itofd;
}
@@ -84,7 +88,7 @@ uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)
set_float_exception_flags(0, &cpu->env.fp_status);
itofs = int32_to_float32(val, &cpu->env.fp_status);
- update_fpcsr(cpu);
+ update_fpcsr(cpu, GETPC());
return itofs;
}
@@ -96,7 +100,7 @@ uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val)
set_float_exception_flags(0, &cpu->env.fp_status);
ftoid = float32_to_int64(val, &cpu->env.fp_status);
- update_fpcsr(cpu);
+ update_fpcsr(cpu, GETPC());
return ftoid;
}
@@ -108,7 +112,7 @@ uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val)
set_float_exception_flags(0, &cpu->env.fp_status);
ftois = float32_to_int32(val, &cpu->env.fp_status);
- update_fpcsr(cpu);
+ update_fpcsr(cpu, GETPC());
return ftois;
}
@@ -123,7 +127,7 @@ uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); \
set_float_exception_flags(0, &cpu->env.fp_status); \
result = float64_ ## name(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
return result; \
} \
\
@@ -134,7 +138,7 @@ uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); \
set_float_exception_flags(0, &cpu->env.fp_status); \
result = float32_ ## name(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
return result; \
} \
@@ -163,7 +167,7 @@ uint64_t helper_float_ ## name1 ## name2 ## _d(CPUOpenRISCState *env, \
result = float64_ ## name2(result, temp, &cpu->env.fp_status); \
val1 = result >> 32; \
val2 = (uint32_t) (result & 0xffffffff); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
cpu->env.fpmaddlo = val2; \
cpu->env.fpmaddhi = val1; \
return 0; \
@@ -183,7 +187,7 @@ uint32_t helper_float_ ## name1 ## name2 ## _s(CPUOpenRISCState *env, \
result = float64_ ## name2(result, temp, &cpu->env.fp_status); \
val1 = result >> 32; \
val2 = (uint32_t) (result & 0xffffffff); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
cpu->env.fpmaddlo = val2; \
cpu->env.fpmaddhi = val1; \
return 0; \
@@ -201,7 +205,7 @@ uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); \
set_float_exception_flags(0, &cpu->env.fp_status); \
res = float64_ ## name(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
return res; \
} \
\
@@ -212,7 +216,7 @@ uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); \
set_float_exception_flags(0, &cpu->env.fp_status); \
res = float32_ ## name(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
return res; \
}
@@ -230,7 +234,7 @@ uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); \
set_float_exception_flags(0, &cpu->env.fp_status); \
res = !float64_eq_quiet(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
return res; \
} \
\
@@ -241,7 +245,7 @@ uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); \
set_float_exception_flags(0, &cpu->env.fp_status); \
res = !float32_eq_quiet(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
return res; \
}
@@ -256,7 +260,7 @@ uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); \
set_float_exception_flags(0, &cpu->env.fp_status); \
res = !float64_le(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
return res; \
} \
\
@@ -267,7 +271,7 @@ uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); \
set_float_exception_flags(0, &cpu->env.fp_status); \
res = !float32_le(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
return res; \
}
FLOAT_CMPGT(gt)
@@ -281,7 +285,7 @@ uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); \
set_float_exception_flags(0, &cpu->env.fp_status); \
res = !float64_lt(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
return res; \
} \
\
@@ -292,7 +296,7 @@ uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \
OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env)); \
set_float_exception_flags(0, &cpu->env.fp_status); \
res = !float32_lt(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
+ update_fpcsr(cpu, GETPC()); \
return res; \
}
@@ -72,7 +72,7 @@ uint32_t HELPER(mul32)(CPUOpenRISCState *env,
cpu->env.sr |= (SR_OV | SR_CY);
if (cpu->env.sr & SR_OVE) {
- raise_exception(cpu, EXCP_RANGE);
+ do_raise_exception(cpu, EXCP_RANGE, GETPC());
}
return result;
@@ -19,6 +19,7 @@
*/
#include "cpu.h"
+#include "exception.h"
#ifndef CONFIG_USER_ONLY
#include "softmmu_exec.h"
@@ -39,25 +40,13 @@
void tlb_fill(CPUOpenRISCState *env, target_ulong addr, int is_write,
int mmu_idx, uintptr_t retaddr)
{
- TranslationBlock *tb;
- unsigned long pc;
int ret;
+ OpenRISCCPU *cpu = OPENRISC_CPU(ENV_GET_CPU(env));
ret = cpu_openrisc_handle_mmu_fault(env, addr, is_write, mmu_idx);
if (ret) {
- if (retaddr) {
- /* now we have a real cpu fault. */
- pc = (unsigned long)retaddr;
- tb = tb_find_pc(pc);
- if (tb) {
- /* the PC is inside the translated code. It means that we
- have a virtual CPU fault. */
- cpu_restore_state(tb, env, pc);
- }
- }
- /* Raise Exception. */
- cpu_loop_exit(env);
+ do_raise_exception_err(cpu, env->exception_index, retaddr);
}
}
#endif
Add OpenRisc fpu excepiton. When an exception raised, CPU can save right PC. Signed-off-by: Feng Gao <gf91597@gmail.com> --- target-openrisc/exception.c | 31 +++++++++++++++++++++-- target-openrisc/exception.h | 8 ++++-- target-openrisc/exception_helper.c | 2 +- target-openrisc/fpu_helper.c | 48 +++++++++++++++++++----------------- target-openrisc/int_helper.c | 2 +- target-openrisc/mmu_helper.c | 17 +++---------- 6 files changed, 66 insertions(+), 42 deletions(-)