Booting L4Re on the CI20: Panic in sigma0

Paul Boddie paul at boddie.org.uk
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
> 
> ...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




More information about the l4-hackers mailing list