Patchwork Modified OpenRisc fpu exception

login
register
mail settings
Submitter Feng Gao
Date Nov. 30, 2012, 7:17 a.m.
Message ID <1354259862-12602-1-git-send-email-gf91597@gmail.com>
Download mbox | patch
Permalink /patch/202887/
State New
Headers show

Comments

Feng Gao - Nov. 30, 2012, 7:17 a.m.
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(-)
陳韋任 - Nov. 30, 2012, 2:59 p.m.
> -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);
> +}

  Please change your subject into "[PATCH v2] ..." so that others will
notice this is a new version patch. See [1] for more detail. Also, you
still doesn't address v1's comment. Why you put both do_raise_exception_err
and do_raise_exception here? It's unnecessary to me.

Regards,
chenwj

[1] http://wiki.qemu.org/Contribute/SubmitAPatch
Peter Maydell - Nov. 30, 2012, 3:03 p.m.
On 30 November 2012 07:17, Feng Gao <gf91597@gmail.com> wrote:
> Add OpenRisc fpu excepiton.
> When an exception raised, CPU can save right PC.

This commit message is very short and quite hard
to understand. It would be nice to see more detail
here on what the patch is trying to do.

thanks
-- PMM
Andreas Färber - Nov. 30, 2012, 4:31 p.m.
Am 30.11.2012 16:03, schrieb Peter Maydell:
> On 30 November 2012 07:17, Feng Gao <gf91597@gmail.com> wrote:
>> Add OpenRisc fpu excepiton.
>> When an exception raised, CPU can save right PC.
> 
> This commit message is very short and quite hard
> to understand. It would be nice to see more detail
> here on what the patch is trying to do.

Also please use a "target-openrisc: " prefix for the subject to conform
to our scheme. This makes it easier to spot relevant patches on the
mailing list and later in the commit history.

Thanks,
Andreas
Feng Gao - Dec. 1, 2012, 10:42 p.m.
Thank you .I will modify the patch and give more infomation about the patch

在 2012年12月1日星期六,Andreas Färber <afaerber@suse.de> 写道:
> Am 30.11.2012 16:03, schrieb Peter Maydell:
>> On 30 November 2012 07:17, Feng Gao <gf91597@gmail.com> wrote:
>>> Add OpenRisc fpu excepiton.
>>> When an exception raised, CPU can save right PC.
>>
>> This commit message is very short and quite hard
>> to understand. It would be nice to see more detail
>> here on what the patch is trying to do.
>
> Also please use a "target-openrisc: " prefix for the subject to conform
> to our scheme. This makes it easier to spot relevant patches on the
> mailing list and later in the commit history.
>
> Thanks,
> Andreas
>
> --
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
>

Patch

diff --git a/target-openrisc/exception.c b/target-openrisc/exception.c
index 58e53c6..39966a7 100644
--- a/target-openrisc/exception.c
+++ b/target-openrisc/exception.c
@@ -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);
+}
+
diff --git a/target-openrisc/exception.h b/target-openrisc/exception.h
index 4b64430..4d1928e 100644
--- a/target-openrisc/exception.h
+++ b/target-openrisc/exception.h
@@ -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 */
diff --git a/target-openrisc/exception_helper.c b/target-openrisc/exception_helper.c
index dab4148..15b9c1f 100644
--- a/target-openrisc/exception_helper.c
+++ b/target-openrisc/exception_helper.c
@@ -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);
 }
diff --git a/target-openrisc/fpu_helper.c b/target-openrisc/fpu_helper.c
index b184d5e..c2890d5 100644
--- a/target-openrisc/fpu_helper.c
+++ b/target-openrisc/fpu_helper.c
@@ -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;                                                           \
 }
 
diff --git a/target-openrisc/int_helper.c b/target-openrisc/int_helper.c
index 2fdfd27..46ec978 100644
--- a/target-openrisc/int_helper.c
+++ b/target-openrisc/int_helper.c
@@ -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;
diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c
index 59ed371..8b687c0 100644
--- a/target-openrisc/mmu_helper.c
+++ b/target-openrisc/mmu_helper.c
@@ -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