Skip to contentSkip to conversation

linux-user/mips: Support the n32 ABI for the R5900

PATCH Applied Fredrik Noring 5 participants 12 messages Nov 8, 2018 – Feb 14, 2021

lore
Share & tools
lore
#0 lore raw

cover linux-user/mips: Support the n32 ABI for the R5900

Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI. Test that DMULT is emulated in user mode.

This series has been successfully built with the 10 different build configurations

{gcc,clang} x -m64 x mips{,64}el-{linux-user,softmmu} {gcc,clang} x -m64 x mipsn32el-linux-user

in addition successfully completing the R5900 test suite

    cd tests/tcg/mips/mipsr5900 && make check
    cd tests/tcg/mips/mipsn32r5900 && make check

Fredrik Noring (2):
linux-user/mips: Support the n32 ABI for the R5900 tests/tcg/mips: Test user mode DMULT for the R5900

 linux-user/mips64/target_elf.h       |  3 +++
 tests/tcg/mips/mipsn32r5900/Makefile | 25 +++++++++++++++++
 tests/tcg/mips/mipsn32r5900/dmult.c  | 40 ++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)
 create mode 100644 tests/tcg/mips/mipsn32r5900/Makefile
 create mode 100644 tests/tcg/mips/mipsn32r5900/dmult.c
Signature · 1 line
2.18.1
#1 lore raw

PATCH 1/2 linux-user/mips: Support the n32 ABI for the R5900

Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI.

---
 linux-user/mips64/target_elf.h | 3 +++
 1 file changed, 3 insertions(+)
linux-user/mips64/target_elf.h +3 -0
index ec55d8542a..5f2f2df29f 100644
@@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags)
     if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_64R6) {
         return "I6400";
     }
+    if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) {
+        return "R5900";
+    }
     return "5KEf";
 }
 #endif
Signature · 1 line
2.18.1
#6 lore raw

PATCH 2/2 tests/tcg/mips: Test user mode DMULT for the R5900

In reply to Fredrik Noring

The R5900 reports itself as MIPS III but does not implement DMULT. Verify that DMULT is emulated properly in user mode by multiplying two 64-bit numbers to produce a 128-bit number.

---
 tests/tcg/mips/mipsn32r5900/Makefile | 25 +++++++++++++++++
 tests/tcg/mips/mipsn32r5900/dmult.c  | 40 ++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)
 create mode 100644 tests/tcg/mips/mipsn32r5900/Makefile
 create mode 100644 tests/tcg/mips/mipsn32r5900/dmult.c
tests/tcg/mips/mipsn32r5900/Makefile new file +25 -0
new file mode 100644
index 0000000000..7dd16723fe
@@ -0,0 +1,25 @@
+-include ../../config-host.mak
+
+CROSS=mips64r5900el-unknown-linux-gnu-
+
+SIM=qemu-mipsn32el
+SIM_FLAGS=-cpu R5900
+
+CC      = $(CROSS)gcc
+CFLAGS  = -Wall -mabi=n32 -march=r5900 -static
+
+TESTCASES = dmult.tst
+
+all: $(TESTCASES)
+
+%.tst: %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+check: $(TESTCASES)
+	@for case in $(TESTCASES); do \
+        echo $(SIM) $(SIM_FLAGS) ./$$case;\
+        $(SIM) $(SIM_FLAGS) ./$$case; \
+	done
+
+clean:
+	$(RM) -rf $(TESTCASES)
tests/tcg/mips/mipsn32r5900/dmult.c new file +40 -0
new file mode 100644
index 0000000000..2827ab5358
@@ -0,0 +1,40 @@
+/*
+ * Test DMULT.
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <assert.h>
+
+struct hi_lo { int64_t hi; uint64_t lo; };
+
+static struct hi_lo dmult(int64_t rs, int64_t rt)
+{
+    int64_t hi;
+    uint64_t lo;
+
+    /*
+     * The R5900 reports itself as MIPS III but does not implement DMULT.
+     * Verify that DMULT is emulated properly in user mode.
+     */
+    __asm__ __volatile__ (
+            "    .set  mips3\n"
+            "    dmult %2, %3\n"
+            "    mfhi  %0\n"
+            "    mflo  %1\n"
+            : "=r" (hi), "=r" (lo)
+            : "r" (rs), "r" (rt));
+
+    return (struct hi_lo) { .hi = hi, .lo = lo };
+}
+
+int main()
+{
+    /* Verify that multiplying two 64-bit numbers yields a 128-bit number. */
+    struct hi_lo r = dmult(2760727302517, 5665449960167);
+
+    assert(r.hi == 847887);
+    assert(r.lo == 7893651516417804947);
+
+    return 0;
+}
Signature · 1 line
2.18.1
Reviewed-by on v1 1/2
#2 lore raw
In reply to Fredrik Noring
Quoted 14 lines · Fredrik Noring

Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI.

---
 linux-user/mips64/target_elf.h | 3 +++
 1 file changed, 3 insertions(+)
linux-user/mips64/target_elf.h +0 -0
index ec55d8542a..5f2f2df29f 100644

linux-user/mips64/target_elf.h static inline const char *cpu_get_model(uint32_t eflags) · line 20

Quoted 9 lines
linux-user/mips64/target_elf.h +3 -0
@@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags)
     if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_64R6) {
         return "I6400";
     }
+    if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) {
+        return "R5900";
+    }
     return "5KEf";
 }
 #endif
#7 lore raw
In reply to Fredrik Noring
Quoted 2 lines · Fredrik Noring

Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI. Test that DMULT is emulated in user mode.

if you have time, o32 & n32 support needs to be reworked.

We have two binaries qemu-mips and qemu-mipsn32 sharing the same ELF mask/magic.

As n32 identifies a kernel ABI version, we should have only one binary for qemu-mips and qemu-mipsn32 and the ABI version should be identified at runtime as it is done for ARM:

ce4defa062 Arm Linux EABI syscall support.

[I think we can use e_flags for that]

I never did the change because I don't know where to find mipsn32 binaries to test my changes.

Thanks,
Laurent

#8 lore raw
Quoted 10 lines · Laurent Vivier

if you have time, o32 & n32 support needs to be reworked.

We have two binaries qemu-mips and qemu-mipsn32 sharing the same ELF mask/magic.

As n32 identifies a kernel ABI version, we should have only one binary for qemu-mips and qemu-mipsn32 and the ABI version should be identified at runtime as it is done for ARM:

ce4defa062 Arm Linux EABI syscall support.

Are you sure? So is the ARM ABI handled with ce4defa062 64-bit?

The o32 ABI is 32-bit (32-bit GPR width) while n32 is 64-bit (64-bit GPR
width). The correspondence between the i386 ABI and the x86-64 x32 ABI is analogous to these two ABIs.

How are these x86 ABIs handled WRT the user emulation mode; are they
analogous to the ARM ABIs you've mentioned?

Quoted 1 line

[I think we can use e_flags for that]

The EF_MIPS_ABI2 `e_flags' bit denotes the n32 ABI. The container format
is ELF32 obviously, because addressing is 32-bit with n32.

Quoted 2 lines

I never did the change because I don't know where to find mipsn32 binaries to test my changes.

I believe MIPS64 Debian is all n32.

Maciej

#9 lore raw
Quoted 7 lines · Maciej W. Rozycki
Quoted 5 lines · Laurent Vivier

if you have time, o32 & n32 support needs to be reworked.

We have two binaries qemu-mips and qemu-mipsn32 sharing the same ELF mask/magic.

Quoted 7 lines
Quoted 5 lines

As n32 identifies a kernel ABI version, we should have only one binary for qemu-mips and qemu-mipsn32 and the ABI version should be identified at runtime as it is done for ARM:

ce4defa062 Arm Linux EABI syscall support.

Are you sure? So is the ARM ABI handled with ce4defa062 64-bit?

I'm sure of nothing. It's why it's better if someone involved in mips development has an opinion on it :)

Quoted 10 lines

The o32 ABI is 32-bit (32-bit GPR width) while n32 is 64-bit (64-bit GPR
width). The correspondence between the i386 ABI and the x86-64 x32 ABI is analogous to these two ABIs.
How are these x86 ABIs handled WRT the user emulation mode; are they
analogous to the ARM ABIs you've mentioned?

Quoted 1 line

[I think we can use e_flags for that]

The EF_MIPS_ABI2 `e_flags' bit denotes the n32 ABI. The container format
is ELF32 obviously, because addressing is 32-bit with n32.

OK, I understand better. It looks like qemu-sparc32plus or qemu-ppc64abi32. If this is the case, you're right we need different binaries.

Quoted 4 lines
Quoted 2 lines

I never did the change because I don't know where to find mipsn32 binaries to test my changes.

I believe MIPS64 Debian is all n32.

Some readelf results:

mips64el/stretch

  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:   ELF64
  Flags:   0x80000007, noreorder, pic, cpic, mips64r2

mipsel/stretch

  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:   ELF32
  Flags:   0x70001007, noreorder, pic, cpic, o32, mips32r2

mips/stretch/bin

  Magic:   7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
  Class:   ELF32
  Flags:   0x70001007, noreorder, pic, cpic, o32, mips32r2

So 32bit mips are all o32, 64bit is n32.

Are there any distros that are 32bit but n32? Any binaries that need qemu-mipsn32 or qemu-mipsn32el?

Thanks,
Laurent

#10 lore raw
Quoted 9 lines · Laurent Vivier
Quoted 1 line

I believe MIPS64 Debian is all n32.

Some readelf results:

mips64el/stretch

  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:   ELF64
  Flags:   0x80000007, noreorder, pic, cpic, mips64r2

Hmm, that's weird -- what executable did you check? There may be some
that are n64, or maybe they've switched (which I would applaud, FWIW). I remember seeing mostly n32, with minimal support for n64, but that was a while ago -- jessie or suchlike, I believe. Using MIPS64r2 as the base ISA also looks new to me, that used to be plain MIPS III, and some of Debian's MIPS build systems used to be either MIPS III (Lemote Loongson) or MIPS64r1 (Broadcom SiByte).

Quoted 1 line

Are there any distros that are 32bit but n32?

You need 64-bit hardware for n32, so you can't do a 32-bit distribution
with n32. FAOD n32 is ILP32 with 64-bit `long long' and 64-bit stack slots both using the native 64-bit register width.

Quoted 1 line

Any binaries that need qemu-mipsn32 or qemu-mipsn32el?

I'd expect at least the n32 dynamic loader (along with libc and some
other essential DSOs) to be present with MIPS64 Debian. Traditionally, under the FHS rules, it would be installed as /lib32/ld.so.1 (with the o32 one as /lib/ld.so.1 and the n64 as /lib64/ld.so.1), but Debian uses their own multiarch filesystem layout standard, and offhand I don't remember what the paths are defined to there.

Anyway, once you have tracked down the `ld.so.1' binary you can invoke it
directly for some output, and it should be good enough for your smoke test purposes IIUC.

I am away travelling through the end of this week and I have limited
access to resources. I can help more once I am back next week.

Maciej

#11 lore raw
Quoted 8 lines · Maciej W. Rozycki
Quoted 7 lines

Some readelf results:

mips64el/stretch

  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:   ELF64
  Flags:   0x80000007, noreorder, pic, cpic, mips64r2
Quoted 7 lines

Hmm, that's weird -- what executable did you check? There may be some
that are n64, or maybe they've switched (which I would applaud, FWIW). I remember seeing mostly n32, with minimal support for n64, but that was a while ago -- jessie or suchlike, I believe. Using MIPS64r2 as the base ISA also looks new to me, that used to be plain MIPS III, and some of Debian's MIPS build systems used to be either MIPS III (Lemote Loongson) or MIPS64r1 (Broadcom SiByte).

OK, I definitely got this confused. I did some checking and jessie
didn't even have a 64-bit MIPS port. I got their build systems right though, and the kernel is 64-bit for systems that support it.

Quoted 8 lines
Quoted 1 line

Any binaries that need qemu-mipsn32 or qemu-mipsn32el?

I'd expect at least the n32 dynamic loader (along with libc and some
other essential DSOs) to be present with MIPS64 Debian. Traditionally, under the FHS rules, it would be installed as /lib32/ld.so.1 (with the o32 one as /lib/ld.so.1 and the n64 as /lib64/ld.so.1), but Debian uses their own multiarch filesystem layout standard, and offhand I don't remember what the paths are defined to there.

So with jessie you can install the `libc6-dev-mipsn32' package, which
will get you n32 glibc development libraries and will pull the complementing n32 dynamic loader (at /lib32/ld.so.1 actually) and n32 glibc shared libraries as well.

Unfortunately multilib support files, such as the CRT files, seem to be
missing from GCC for n32 or I cannot find them. Otherwise you would be able to compile and link n32 binaries just by calling `gcc -mabi=n32'. Still the dynamic loader is directly runnable, as I noted above.

HTH,

Maciej

#4 lore raw
Quoted 2 lines · Philippe Mathieu-Daudé

On Thu, Nov 8, 2018 at 7:45 PM Fredrik Noring <[email protected]> wrote:

Oops, an old patch from 2018 and was never applied?

Quoted 11 lines
Quoted 8 lines

Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI.

---
 linux-user/mips64/target_elf.h | 3 +++
 1 file changed, 3 insertions(+)

Regards,
Bin

#5 lore raw
In reply to Philippe Mathieu-Daudé

Le 14/02/2021 à 16:17, Philippe Mathieu-Daudé a écrit :

Quoted 5 lines · Fredrik Noring
Quoted 4 lines

Recognise the R5900, which reports itself as MIPS III, as a 64-bit CPU supporting the n32 ABI.

Quoted 8 lines
Quoted 4 lines
---
 linux-user/mips64/target_elf.h | 3 +++
 1 file changed, 3 insertions(+)

Applied to my linux-user-for-6.0 branch.

Thanks,
Laurent