qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RFC] target/mips: Initial support for MIPS R5900


From: Fredrik Noring
Subject: [Qemu-devel] [RFC] target/mips: Initial support for MIPS R5900
Date: Sat, 7 Jul 2018 21:41:39 +0200
User-agent: Mutt/1.9.1 (2017-09-22)

Hi,

This patch implements initial QEMU support for the MIPS R5900. Primarily
code generated by GCC. The only special instruction needed for this, as far
as I can tell, is the three-operand multiply.

The MIPS R5900 is normally taken to be MIPS3, but it has MOVN, MOVZ and PREF
defined in MIPS4 which is why ISA_MIPS4 is chosen for this patch.

I have tested the patch with Linux user mode emulation on a root filesystem
compiled for R5900 and it worked without apparent issues, apart from:

        qemu: Unsupported syscall: 4352 (seccomp)

Some flags in the mips_defs array are marked FIXME as I don't know the
proper values.

Would this patch be an acceptable initial submission for the MIPS R5900?

Fredrik

 ---
 include/elf.h                    |  3 +++
 linux-user/mips/target_elf.h     |  3 +++
 target/mips/mips-defs.h          |  2 ++
 target/mips/translate.c          | 31 ++++++++++++++++++++++++++++++-
 target/mips/translate_init.inc.c | 20 ++++++++++++++++++++
 5 files changed, 58 insertions(+), 1 deletion(-)

--- a/include/elf.h
+++ b/include/elf.h
@@ -48,6 +48,8 @@ typedef int64_t  Elf64_Sxword;
 #define EF_MIPS_ARCH_32R6       0x90000000      /* MIPS32r6 code.  */
 #define EF_MIPS_ARCH_64R6       0xa0000000      /* MIPS64r6 code.  */
 
+#define EF_MIPS_MACH_5900       0x00920000
+
 /* The ABI of a file. */
 #define EF_MIPS_ABI_O32                0x00001000      /* O32 ABI.  */
 #define EF_MIPS_ABI_O64                0x00002000      /* O32 extended for 64 
bit.  */
@@ -62,6 +64,7 @@ typedef int64_t  Elf64_Sxword;
 #define EF_MIPS_FP64      0x00000200
 #define EF_MIPS_NAN2008   0x00000400
 #define EF_MIPS_ARCH      0xf0000000
+#define EF_MIPS_MACH      0x00ff0000
 
 /* These constants define the different elf file types */
 #define ET_NONE   0
--- a/linux-user/mips/target_elf.h
+++ b/linux-user/mips/target_elf.h
@@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags)
     if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) {
         return "mips32r6-generic";
     }
+    if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) {
+        return "R5900";
+    }
     return "24Kf";
 }
 #endif
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -52,6 +52,7 @@
 #define   ASE_MSA       0x01000000
 
 /* Chip specific instructions. */
+#define                INSN_R5900      0x10000000
 #define                INSN_LOONGSON2E  0x20000000
 #define                INSN_LOONGSON2F  0x40000000
 #define                INSN_VR54XX     0x80000000
@@ -62,6 +63,7 @@
 #define                CPU_MIPS3       (CPU_MIPS2 | ISA_MIPS3)
 #define                CPU_MIPS4       (CPU_MIPS3 | ISA_MIPS4)
 #define                CPU_VR54XX      (CPU_MIPS4 | INSN_VR54XX)
+#define                CPU_R5900       (CPU_MIPS4 | INSN_R5900)
 #define                CPU_LOONGSON2E  (CPU_MIPS3 | INSN_LOONGSON2E)
 #define                CPU_LOONGSON2F  (CPU_MIPS3 | INSN_LOONGSON2F)
 
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -3618,6 +3618,31 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
     tcg_temp_free(t1);
 }
 
+static void gen_mul_r5900 (DisasContext *ctx, uint32_t opc,
+                            int rd, int rs, int rt)
+{
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+
+    gen_load_gpr(t0, rs);
+    gen_load_gpr(t1, rt);
+
+    switch (opc) {
+    case OPC_MULT:
+    case OPC_MULTU:
+        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
+        break;
+    default:
+        MIPS_INVAL("mul R5900");
+        generate_exception_end(ctx, EXCP_RI);
+        goto out;
+    }
+
+ out:
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+}
+
 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
                             int rd, int rs, int rt)
 {
@@ -17357,7 +17382,11 @@ static void decode_opc_special_legacy(CPUMIPSState 
*env, DisasContext *ctx)
         break;
     case OPC_MULT:
     case OPC_MULTU:
-        if (sa) {
+        if (ctx->insn_flags & INSN_R5900) {
+            gen_muldiv(ctx, op1, 0, rs, rt);
+            if (rd != 0)
+                gen_mul_r5900(ctx, op1, rd, rs, rt);
+        } else if (sa) {
             check_insn(ctx, INSN_VR54XX);
             op1 = MASK_MUL_VR54XX(ctx->opcode);
             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
--- a/target/mips/translate_init.inc.c
+++ b/target/mips/translate_init.inc.c
@@ -411,6 +411,26 @@ const mips_def_t mips_defs[] =
         .mmu_type = MMU_TYPE_R4000,
     },
     {
+        .name = "R5900",
+        .CP0_PRid = 0x00003800,
+        /* No L2 cache, icache size 32k, dcache size 32k, uncached coherency. 
*/
+        .CP0_Config0 = (1 << 17) | (0x3 << 9) | (0x3 << 6) | (0x2 << CP0C0_K0),
+        /* Note: Config1 is only used internally, the R5900 has only Config0. 
*/
+        .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+        .CP0_LLAddr_rw_bitmask = 0xFFFFFFFF,   /* FIXME */
+        .CP0_LLAddr_shift = 4,                 /* FIXME */
+        .SYNCI_Step = 16,                      /* FIXME */
+        .CCRes = 2,                            /* FIXME */
+        .CP0_Status_rw_bitmask = 0x3678FFFF,   /* FIXME */
+        .CP1_fcr0 = (0x38 << FCR0_PRID) | (0x0 << FCR0_REV),
+        .CP1_fcr31 = 0,
+        .CP1_fcr31_rw_bitmask = 0x0183FFFF,    /* FIXME */
+        .SEGBITS = 40,                         /* FIXME */
+        .PABITS = 36,                          /* FIXME */
+        .insn_flags = CPU_R5900,
+        .mmu_type = MMU_TYPE_R4000,            /* FIXME */
+    },
+    {
         /* A generic CPU supporting MIPS32 Release 6 ISA.
            FIXME: Support IEEE 754-2008 FP.
                   Eventually this should be replaced by a real CPU model. */



reply via email to

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