[SPARC/Leon3] Application compiled by RCC 1.2 won't start
Host environment
- Operating system: Windows 10
- Host architecture: x64
- QEMU flavor: qemu-system-sparc
- QEMU version: 7.0.50 (v7.0.0-11902-g1d935f4a02-dirty)
- QEMU command line: (see below)
Emulated/Virtualized environment
- Architecture: SPARC
- Machine: LEON3, RTEMS OS
- GCC Version: sparc-rtems-gcc.exe (GCC) 4.4.6
Description of problem
Even simple "hello world" application compiled by Gaisler RCC 1.2 compiler ("space-certified" GCC 4.4.6 with RTEMS OS) for Leon3 CPU won't start on QEMU - QEMU silently exits before getting into Init.
In real hardware it works.
(I know that the GCC 4.4.6 is quite ancient now, usage of this toolchain is forced)
Steps to reproduce
Steps provided for Windows system, but I suspect it works exactly the same in Linux system.
- Get
sparc-rtems-4.10-gcc-4.4.6-1.2.25-mingwGCC from here: https://www.gaisler.com/anonftp/rcc/rcc-1.2/1.2.25/ - Unpack it to
c:\opt(it doesn't work from other directories./optfor Linux) - Create simple "Hello world" RTEMS application.
- Run it by
qemu-system-sparc -machine leon3_generic -nographic -monitor null -serial stdio -m 64M -kernel fail.elf - Result is exiting before getting into
Init.
Simple example attached (with ELF). It should print It works. Exiting. and exit.
Additional information
Log:
...
----------------
IN: ambapp_for_each_dev
0x40005430: clr %o0 ! 0x0
0x40005434: ret
0x40005438: restore %g0, %o0, %o0
----------------
IN: amba_initialize
0x40003aa8: cmp %o0, 0
0x40003aac: be 0x40003b4c
0x40003ab0: nop
----------------
IN: amba_initialize
0x40003b4c: mov 1, %g1
0x40003b50: ta 0
1: Trap Instruction (v=80)
pc: 40003b50 npc: 40003b54
%g0-7: 00000000 00000001 00000000 00000000 00000000 00000000 400007c0 00000000
%o0-7: 00000000 00000034 00000001 0000000d 40004b04 00000000 43fffe60 40003aa0
%l0-7: 40025800 00000000 00000000 00000000 00000000 00000000 00000000 00000000
%i0-7: 00000000 00000000 00000000 00000000 00000000 00000000 43fffec0 40002b78
psr: f3400fe5 (icc: -Z-- SPE: SPE) wim: 00000002
fsr: 00000000 y: ffffffff
----------------
IN:
0x40003a18: cmp %g1, 3
0x40003a1c: bne 0x40003a34
0x40003a20: and %i0, 0xf00, %l4
----------------
IN:
0x40003a34: ta 0
2: Trap Instruction (v=80)
pc: 40003a34 npc: 40003a38
%g0-7: 00000000 00000001 00000000 00000000 00000000 00000000 400007c0 00000000
%o0-7: 00000000 00000034 00000001 0000000d 40004b04 00000000 43fffe00 40005470
%l0-7: f3400fc4 40003b50 40003b54 00000080 00000000 40026ab8 00000000 fffff800
%i0-7: 00000000 00000034 00000001 0000000d 40004b04 00000000 43fffe60 40003aa0
psr: f3900fc4 (icc: N--C SPE: SP-) wim: 00000002
fsr: 00000000 y: ffffffff
3: Trap Instruction (v=80)
pc: 40003a34 npc: 40003a38
%g0-7: 00000000 00000001 00000000 00000000 00000000 00000000 400007c0 00000000
%o0-7: 00000000 00000034 00000001 0000000d 40004b04 00000000 43fffe00 40005470
%l0-7: f3400fc4 40003b50 40003b54 00000080 00000000 40026ab8 00000000 fffff800
%i0-7: 00000000 00000034 00000001 0000000d 40004b04 00000000 43fffe60 40003aa0
psr: f3900fc4 (icc: N--C SPE: SP-) wim: 00000002
fsr: 00000000 y: ffffffff
// repeating until sudden and quiet exit from QEMU
After digging it seems that target code requires byte access to GRLIB APB PNP registers that is not implemented in QEMU now. Adding code supporting byte access seems to help.
The quick patch is:
--- a/hw/misc/grlib_ahb_apb_pnp.c
+++ b/hw/misc/grlib_ahb_apb_pnp.c
@@ -249,6 +249,11 @@ static uint64_t grlib_apb_pnp_read(void *opaque, hwaddr offset, unsigned size)
val = apb_pnp->regs[offset >> 2];
trace_grlib_apb_pnp_read(offset, val);
+ if (size == 1) {
+ val >>= (24 - (offset & 3) * 8);
+ val &= 0x0ff;
+ }
+
return val;
}
@@ -263,7 +268,7 @@ static const MemoryRegionOps grlib_apb_pnp_ops = {
.write = grlib_apb_pnp_write,
.endianness = DEVICE_BIG_ENDIAN,
.impl = {
- .min_access_size = 4,
+ .min_access_size = 1,
.max_access_size = 4,
},
};
The custom compiled QEMU with this patch is used in project for over half a year and it works fine, but I don't know if it is a proper fix.