Following up to myself...
On Thursday 13. July 2017 19.22.32 Paul Boddie wrote:
But now I appear to experience a panic in sigma0 as it starts up, with the message...
Warning: Sigma0 raised an exception --> HALT
[...]
The EPC indeed appears to reference sigma0, with the Cause indicating an erroneous data or instruction fetch operation. Looking at the disassembly of sigma0...
002000e0 <__start>: 2000e0: 3c1c0001 lui gp,0x1 2000e4: 279c7f80 addiu gp,gp,32640 2000e8: 0399e021 addu gp,gp,t9 2000ec: 8f9d8018 lw sp,-32744(gp) 2000f0: 8f99801c lw t9,-32740(gp) 2000f4: 27bdfff0 addiu sp,sp,-16 2000f8: 0320f809 jalr t9 2000fc: 00000000 nop
...it appears that the problem occurs when the global offset table is accessed. The global pointer gets computed as...
0x10000 + 32640 + 0x800a0000 = 0x800b7f80
...with the load-relative operation accessing...
0x800b7f80 - 32744 = 0x800aff98
Of course, t9, which was set to 0x800a0000 (if the register dump can be believed), is completely wrong according to the way it is used conventionally (as a reference to the current routine). So I investigated the initialisation code for sigma0 in the following place:
pkg/l4re-core/sigma0/server/src/ARCH-mips/crt0.S
This is what it looks like:
__start: .cpload $25 /* load GP */ SETUP_GPX64($25, $0) PTR_LA $29, crt0_stack_high PTR_LA $25, init PTR_SUBU $29, (NARGSAVE * SZREG) jalr $25 nop
The problem here is that the .cpload directive (operating on t9/$25) doesn't have a known value of t9 to work with, it would seem. Consequently, the calculations in the generated code work with a value that isn't initialised.
I tried to add the initialisation of t9 before the .cpload directive, but this actually caused the computed offsets to the gp/$28 register to be eight bytes out, thus causing the accessed table addresses to be eight bytes too low. Here is what I tried:
__start: lui $25, %hi(__start) ori $25, $25, %lo(__start) .cpload $25 /* load GP */
Clearly, the two extra instructions were confusing the .cpload directive. So I then introduced another label as follows, making the .cpload directive operate at exactly the referenced place in the program:
__start: lui $25, %hi(__realstart) ori $25, $25, %lo(__realstart) __realstart: .cpload $25 /* load GP */
Now, the value of t9 is correct for the gp operations. At this point, I get the following output:
SIGMA0: Hello! KIP @ 10000 allocated 4KB for maintenance structures SIGMA0: Dump of all resource maps RAM:------------------------ [4:1000;1fff] [4:140000;184fff] [4:190000;197fff] [4:1100000;1164fff] [0:2155000;3fffffff] IOMEM:---------------------- [0:40000000;ffffffff]
I'm guessing that there should be more output after that, but it either isn't produced on UART0 or something is hanging somewhere. Looking at similar code in moe, it appears that a similar measure is required to set up t9. Here is where that code lives:
pkg/l4re-core/moe/server/src/ARCH-mips/crt0.S
Making a similar change in the "_real_start" routine there yields the following additional output:
MOE: Hello world
And that is then the end of output. Maybe I've stumbled across a difference in the way the compilers work here. I'm using the mipsel-linux-gnu cross- compilers in Debian unstable, whereas I imagine that the people who ported the code to MIPS used proprietary toolchains with different characteristics.
Anyway, I guess I'll investigate other places where this might be occurring and hopefully get the "hello" program to do its thing.
Paul