qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] linux-user/mips: Low down switchable NaN2008 requirement


From: Philippe Mathieu-Daudé
Subject: Re: [PATCH] linux-user/mips: Low down switchable NaN2008 requirement
Date: Thu, 9 Mar 2023 13:32:06 +0100
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.8.0

Hi Jiaxun,

On 11/2/23 18:34, Jiaxun Yang wrote:
Previously switchable NaN2008 requires fcsr31.nan2008 to be writable
for guest. However as per MIPS arch spec this bit can never be writable.
This cause NaN2008 ELF to be rejected by QEMU.

NaN2008 can be enabled on R2~R5 processors, just make it available
unconditionally.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
  linux-user/mips/cpu_loop.c | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index d5c1c7941d..b5c2ca4a3e 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -301,8 +301,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
target_pt_regs *regs)
      }
      if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
          ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
-        if ((env->active_fpu.fcr31_rw_bitmask &
-              (1 << FCR31_NAN2008)) == 0) {
+        if (!(env->insn_flags & ISA_MIPS_R2)) {
              fprintf(stderr, "ELF binary's NaN mode not supported by CPU\n");
              exit(1);
          }

Looking at R6.06 revision history:

  5.03 August 21, 2013

  • ABS2008 and NAN2008 fields of Table 5.7 “FCSR RegisterField
    Descriptions” were optional in release 3 and could be R/W,
    but as of release 5 are required, read-only, and preset by
    hardware.

So I tried with this change:

-- >8 --
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 05caf54999..5f1364ffaf 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -243,6 +243,13 @@ static void mips_cpu_reset_hold(Object *obj)
     env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
+    if (env->insn_flags & ISA_MIPS_R5) {
+ assert(!(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << FCR31_ABS2008))); + assert(!(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << FCR31_NAN2008)));
+    } else if (env->insn_flags & ISA_MIPS_R3) {
+ assert(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << FCR31_ABS2008)); + assert(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << FCR31_NAN2008));
+    }
     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
     env->msair = env->cpu_model->MSAIR;
     env->insn_flags = env->cpu_model->insn_flags;
---

and got:

$ for cpu in $(./qemu-system-mips64el -cpu help | cut -d\' -f2); do \
  echo -n ${cpu}...;echo q \
  | ./qemu-system-mips64el -accel tcg -cpu ${cpu} \
                           -S -monitor stdio 1> /dev/null || break; \
  echo OK; done
4Kc...OK
4Km...OK
4KEcR1...OK
4KEmR1...OK
4KEc...OK
4KEm...OK
24Kc...OK
24KEc...OK
24Kf...OK
34Kf...OK
74Kf...OK
M14K...OK
M14Kc...OK
P5600...OK
mips32r6-generic...OK
I7200...OK
R4000...OK
VR5432...OK
5Kc...OK
5Kf...OK
20Kc...OK
MIPS64R2-generic...OK
5KEc...OK
5KEf...OK
I6400...OK
I6500...OK
Loongson-2E...OK
Loongson-2F...OK
Loongson-3A1000...OK
Loongson-3A4000...OK
mips64dspr2...OK
Octeon68XX...OK
$

Which CPU are you testing? Where can I get such ELF binary for testing?

Thanks,

Phil.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]