[Top][All Lists]

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

MIPS ISA mode switch problem with M14K

From: Geoff Wozniak
Subject: MIPS ISA mode switch problem with M14K
Date: Sun, 12 Mar 2023 19:14:10 -0400
User-agent: Cyrus-JMAP/3.9.0-alpha0-206-g57c8fdedf8-fm-20230227.001-g57c8fded

I am running into some problems with running a bare metal MIPS program that 
switches between MIPS32 and microMIPS.  I'm looking for some advice in the 
event I am doing something wrong.

Here is assembly code for the beginning of the startup code that demonstrates 
the problem.

            .set nomicromips
            .set nomips16
            .section .text
            .globl _reset
            .align 2
            jalx   _startup              # Force an ISA mode change
            .size _reset, . - _reset

            .set micromips
            .globl _startup
            nop                          # This is a 16-bit instruction.
            mfc0   $26, $16, 3           # MFC0 instructions are only here to
            mfc0   $27, $16, 1           #    demonstrate the problem
                                         # Rest of code elided

I build it as follows.

    mips-linux-gnu-gcc-10 -mel -c startup.s
    mips-linux-gnu-gcc-10 -mel -T t.x -o t.elf startup.o -nostartfiles 
-nostdlib -static

The linker script t.x maps the text section to a memory region starting at 
When disassembled, the ELF file looks correct.

    t.elf:     file format elf32-tradlittlemips

    Disassembly of section .text:

    bfc00000 <_reset>:
    bfc00000:   77f00003    jalx    bfc0000c <_startup>
    bfc00004:   00000000    nop
    bfc00008:   00000000    nop

    bfc0000c <_startup>:
    bfc0000c:   0c00        nop
    bfc0000e:   0350 18fc   mfc0    k0,c0_config3
    bfc00012:   0370 08fc   mfc0    k1,c0_config1

The JALX instrution is encoded in MIPS32, and the NOP in _startup is encoded as 
a microMIPS instruction.  Based on the MIPS ISA documentation, the JALX should 
switch the ISA mode to microMIPS, assuming the machine supports it.

I am running the code in QEMU 5.2.0 from Debian 11.6 as follows, using the 
following command

    qemu-system-mipsel -machine mipssim -cpu M14K -nographic -kernel t.elf -s -S

When I connect with gdb-multiarch and attempt to step through the first 
instruction, gdb sits there and nothing happens.  When I add `-d in_asm` to the 
above command and look at the logs from QEMU I see this at the top.

    0xbfc00000:  daui   ra,s0,0x3
    0xbfc00004:  nop

    0xbfc0000c:  0x3500c00
    0xbfc00010:  0x37018fc
    0xbfc00014:  sd gp,2300(gp)
    0xbfc00018:  mult   s0,t1,t4
    0xbfc0001c:  dsll32 v0,t1,0x3
    0xbfc00020:  0x1495910
    0xbfc00024:  0x12a1eac
    0xbfc00028:  syscall    0x4b126
    0xbfc0002c:  dsll32 v0,zero,0xb
    Disassembler disagrees with translator over instruction decoding
    Please report this to qemu-devel@nongnu.org

Looking at contents at address 0xbfc0000c as reported by QEMU, the microMIPS 
NOP instruction (0x0c00) is being intrepreted as part of a 32-bit instruction.  
After looking at the code, the DAUI instruction is an alias for JALX, which is 
printed oddly, but not incorrect.

Based on what I see in the code and various other experiments, the M14K machine 
in QEMU has the value 0x2 in bits 15:14 in the Config3 register of CP0, meaning 
it supports both MIPS32 and microMIPS instructions, and starts with MIPS32 when 
coming out of reset.

All this suggests that QEMU is not switching the ISA mode properly.  However, I 
am unsure if there is something else I should be doing to tell QEMU to support 
the switch.  Based on what I have found in the code and mailing lists, the M14K 
should support microMIPS.  Is this a bug or am I missing something?  Any help 
would be appreciated.

(I have tried this with QEMU 7.2.0 and a locally built one from the master 
branch with the same results.)

-- Geoff

reply via email to

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