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.

  1. 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
PC (next) 0x1008
  1. 0x1008 = lw t1, -4(t0)
    • Load value in memory address (t0 - 4), store in t1
    • t1 = Mem[0x1004 - 4] = Mem[0x1000] = MSEL = 0b1111 = 0xF
Register Value
t0 0x1004
t1 0x000F
PC (next) 0x100C
  1. 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
  1. 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
  1. 0x1014 = lw t0, 252(t0)
    • Load value in memory address t0 + 252, store in t0
    • t0 = Mem[0x107C + 0xFC] = Mem[0x1178] = 0x????
Register Value
t0 0x????
t1 0x0078
PC (next) 0x1018
  1. 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.

  • I would use the tag risc-v not risc for this question
    – mumbel
    Sep 24, 2021 at 3:30
  • @mumbel oddly, I don't see a risc-v tag Sep 24, 2021 at 12:31

2 Answers 2


MSEL is 4 pins, as in 4 bits. This means 1111 is not 0x1111, but 0b1111 or 0xf. So your math is correct everywhere but the 0x8888 would be 0x78 instead.

auipc t0, 0       <- t0 = pc + 0 => 0x1004
lw t1, -4(t0)     <- t1 = -4(0x1004) => 0xf
slli t1, t1, 0x3  <- t1 = 0xf << 3 == 0xf * 8 => 0x78
add t0, t0, t1    <- t0 = 0x1004 + 0x78 => 0x107c
lw t0, 252(t0)    <- t0 = 252(0x107c) == 0(0x1178) => ???
jr t0             <- goto ???
  • Well that leaves me equally as confused 😂 Sep 24, 2021 at 4:34
  • Heh, at least 0x1178 is mapped. Which part is confusing or just no clue what's in memory at 0x1178?
    – mumbel
    Sep 24, 2021 at 5:05
  • @mumble no clue what's at that address, and the pin select guide suggests 0b1111 should jump to 0x0001_0000 for ZSBL Sep 24, 2021 at 11:44

I can't find the full memory map, but I've been told that this table can be interpreted similarly. Basically, whatever address is calculated using MSEL will have the value in the "Reset address" field. So, it's not an address to value mapping, but since it's the only variable in the algorithm, it alone determines what address will be jumped to in the final instruction, so the mapping is still valid.

Another way to look at it is that MSEL is an index into a jump table, and the base is calculated in the rest of the algorithm.

Table 9: Target of the reset vector

MSEL Reset address Purpose
0000 0x0000_1004 loops forever waiting for debugger
0001 0x2000_0000 memory-mapped QSPI0
0010 0x3000_0000 memory-mapped QSPI1
0011 0x4000_0000 uncached ChipLink
0100 0x6000_0000 cached ChipLink
0101 0x0001_0000 ZSBL
0110 0x0001_0000 ZSBL
0111 0x0001_0000 ZSBL
1000 0x0001_0000 ZSBL
1001 0x0001_0000 ZSBL
1010 0x0001_0000 ZSBL
1011 0x0001_0000 ZSBL
1100 0x0001_0000 ZSBL
1101 0x0001_0000 ZSBL
1110 0x0001_0000 ZSBL
1111 0x0001_0000 ZSBL

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.