qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v2] target/mips: Initial support for MIPS R5900


From: Maciej W. Rozycki
Subject: Re: [Qemu-devel] [PATCH v2] target/mips: Initial support for MIPS R5900
Date: Wed, 12 Sep 2018 21:23:18 +0100 (BST)
User-agent: Alpine 2.21 (LFD 202 2017-01-01)

Hi Fredrik,

> Aleksandar, Aurelien, Maciej -- are you happy with this initial v2 patch?

 I have been more thorough on this occasion, and I do hope I have caught 
everything.  See the notes below, in addition to what the others wrote.  

 Please apply to v3 accordingly; I started writing this before you sent 
that version.

> --- a/target/mips/mips-defs.h
> +++ b/target/mips/mips-defs.h
> @@ -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)

 I think this has to be (CPU_MIPS3 | INSN_R5900) really.

 While the CPU does support MIPS IV MOVN, MOVZ and PREF instructions, 
that's all it has from that ISA.  Even the Tx79, which was supposed to 
have a regular IEEE-754 FPU, did not have the extra FP condition bits, 
MOVN.fmt, MOVZ.fmt or any of the MOVF* or MOVT* instructions, indexed 
load/store instructions, multiply-accumulate instructions, etc. defined.

 So I think the R5900 has to be treated as a MIPS III implementation, with 
some aberrations.  I don't expect it to be a big deal to add INSN_R5900 
qualification to MOVN, MOVZ and PREF instruction emulation code right 
away.

 Then presumably you are going to add emulation for all the missing MIPS 
III instructions to the Linux kernel eventually, to match the MIPS III 
Linux user ABI?  Apart from LLD and SCD discussed previously this will 
have to include DDIV, DDIVU, DMULT and DMULTU.

 Eventually you'll have to remove all these instructions (plus LL and SC) 
from the system emulation mode.  In fact I think it would make sense to do 
that right away, because I believe it will be a reasonably simple update. 
However if it turns out to be a can of worms after all, then I think we 
can defer it, because we do not have a bare-metal environment ready for 
this CPU anyway (or do we?).

> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -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);

 I think there is no point in executing the multiplication twice if `rd != 
0' and also we want to continue trapping on `sa != 0' for the non-Vr54xx 
case, so how about:

        if (sa) {
            check_insn(ctx, INSN_VR54XX);
            op1 = MASK_MUL_VR54XX(ctx->opcode);
            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
        } else if (rd && (ctx->insn_flags & INSN_R5900)) {
            gen_mul_r5900(ctx, op1, rd, rs, rt);
        } else {
            gen_muldiv(ctx, op1, rd & 3, rs, rt);
        }

?

> --- a/target/mips/translate_init.inc.c
> +++ b/target/mips/translate_init.inc.c
> @@ -410,6 +410,50 @@ const mips_def_t mips_defs[] =
>          .insn_flags = CPU_MIPS32R5 | ASE_MSA,
>          .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),

 Why ICE set but DCE clear?  I guess this corresponds to the incorrect L2 
cache reference as bit #17 is SC on the original R4000.  That reference 
has to go, obviously, as there's no L2 cache indication in the R5900's 
Config register.

 As to ICE and DCE their reset defaults are both 0, so we might as well 
use that, as we don't emulate caches anyway.  If it turns out to matter to 
any software, then we'll have to provide a more correct Config register 
emulation as its writable bits are processor-specific.

> +        /* Note: Config1 is only used internally, the R5900 has only 
> Config0. */
> +        .CP0_Status_rw_bitmask = 0xF4C79C1F,

 Maybe swap the two lines so that the Config1 register reference does not 
confusingly seem to describe the Status r/w bitmask?

> +#ifdef CONFIG_USER_ONLY
> +     /*
> +      * R5900 hardware traps to the Linux kernel for IEEE 754-1985 and LL/SC
> +      * emulation. For user-only, qemu is the kernel, so we emulate the traps
> +      * by simply emulating the instructions directly.
> +      */

 Please use spaces rather than tabs for indentation, as per QEMU's coding 
standard.

> +        .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
> +        .CP0_LLAddr_rw_bitmask = 0xFFFFFFFF,
> +        .CP0_LLAddr_shift = 4,
> +        .CP1_fcr0 = (0x38 << FCR0_PRID) | (0x0 << FCR0_REV),
> +        .CP1_fcr31 = 0,
> +        .CP1_fcr31_rw_bitmask = 0x0183FFFF,
> +#else
> +     /*
> +      * The R5900 COP1 FPU implements single-precision floating-point
> +      * operations but is not entirely IEEE 754-1985 compatible. In
> +      * particular,
> +      *
> +      * - NaN (not a number) and plus/minus infinities are not supported;
> +      * - exception mechanisms are not fully supported;
> +      * - denormalized numbers are not supported;
> +      * - rounding towards nearest and plus/minus infinities are not 
> supported;
> +      * - computed results usually differs in the least significant bit;
> +      * - saturating instructions can differ more than the least significant 
> bit.
> +      *
> +      * Since only rounding towards zero is supported, the two least
> +      * significant bits of FCR31 are hardwired to 01.
> +      *
> +      * FPU emulation is disabled here until it is implemented.
> +      */
> +        .CP0_Config1 = (47 << CP0C1_MMU),
> +#endif /* CONFIG_USER_ONLY */
> +        .SEGBITS = 19,

 This has to be 32, as with any MIPS CPU that implements 32-bit virtual 
addressing only.  Specifically EntryHi register's VPN2 field goes up to 
bit #31, which is (SEGBITS - 1).

> +        .PABITS = 20,

 And this has to be 32 as well, reflecting EntryLo0/1 registers' PFN 
fields going up to bit #25.  This corresponds to bit #31 on the external 
address bus, which is (PABITS - 1).

  Maciej



reply via email to

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