I'm reading the manual for the SiFive FU540-C000 trying to understand the boot process, and I'm not making sense of the initial steps after power on.
I'm using MSEL = 1111
based on the recommendation for the software I'm booting from SD card.
On power-on, all cores jump to 0x1004 while running directly off of the external clock input, expected to be 33.3 MHz. The memory at this location contains:
Table 8: Reset vector ROM
Address Contents 0x1000 The MSEL pin state 0x1004 auipc t0, 0 0x1008 lw t1, -4(t0) 0x100C slli t1, t1, 0x3 0x1010 add t0, t0, t1 0x1014 lw t0, 252(t0) 0x1018 jr t0
This is how I've decoded the instructions.
0x1004 = auipc t0, 0
- AUIPC uses the top 20 bits of the immediate, extends 0 to the low 12, then adds the PC value of the auipc instruction. Store in t0
- t0 = 0x0 << 12 = 0x0 + 0x1004
Register | Value |
---|---|
t0 | 0x1004 |
t1 | UNDEF |
PC (next) | 0x1008 |
0x1008 = lw t1, -4(t0)
- Load value in memory address
(t0 - 4)
, store in t1 - t1 = Mem[0x1004 - 4] = Mem[0x1000] = MSEL = 0b1111 = 0xF
- Load value in memory address
Register | Value |
---|---|
t0 | 0x1004 |
t1 | 0x000F |
PC (next) | 0x100C |
0x100C = slli t1, t1, 0x3
- t1 is left shifted 3, store in t1
- t1 = 0b1111 << 3 = 0b1111000 = 0x78
Register | Value |
---|---|
t0 | 0x1004 |
t1 | 0x0078 |
PC (next) | 0x1010 |
0x1010 = add t0, t0, t1
- t1 is added to t0, store in t0
- t0 = 0x1004 + 0x0078 = 0x107C
Register | Value |
---|---|
t0 | 0x107C |
t1 | 0x0078 |
PC (next) | 0x1014 |
0x1014 = lw t0, 252(t0)
- Load value in memory address
t0 + 252
, store in t0 - t0 = Mem[0x107C + 0xFC] = Mem[0x1178] = 0x????
- Load value in memory address
Register | Value |
---|---|
t0 | 0x???? |
t1 | 0x0078 |
PC (next) | 0x1018 |
0x1018 = jr t0
- jump directly to address in t0
- PC = 0x????
Register | Value |
---|---|
t0 | 0x???? |
t1 | 0x0788 |
PC (next) | 0x???? |
The problem is that, according to the manual, MSEL = 0b1111 should jump to 0x0001_0000, doesn't mention anything about what's at 0x1178
Base | Top | Attr. | Description Notes |
---|---|---|---|
0x0000_0000 | 0x0000_00FF | Reserved | |
0x0000_0100 | 0x0000_0FFF | RWX A | Debug |
0x0000_1000 | 0x0000_1FFF | R X | Mode Select |
0x0000_2000 | 0x0000_FFFF | Reserved | |
0x0001_0000 | 0x0001_7FFF | R X | Mask ROM (32 KiB) |
0x0001_8000 | 0x00FF_FFFF | Reserved | |
0x0100_0000 | 0x0100_1FFF | RWX A | S51 DTIM (8 KiB) |
Did I interpret something wrong, or is there something else going on in this boot sequence that I'm not getting?
--EDIT 1--
In my original math I shifted the hex values left instead of binary. Going to attribute that to brain tired. It still isn't any more clear what's happening after the jump instruction.
--EDIT 2--
It was pointed out that I was using LW incorrectly, loading the value in the register instead of the value in memory indicated by the address in register. Updated the math and still no more clear.
--EDIT 3--
Thanks to mumbel for pointing out my incorrect use of the MSEL value. I treated as 0x1111 instead 0f 0b1111 = 0xF. I swear I know hex and binary.