Booting L4Re on the CI20: Panic in sigma0

Paul Boddie paul at
Fri Jul 14 01:11:38 CEST 2017

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
> 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:


This is what it looks like:

        .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

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:

        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:

        lui $25, %hi(__realstart)
        ori $25, $25, %lo(__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

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:


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.


More information about the l4-hackers mailing list