riscvarchive / riscv-newlib

RISC-V port of newlib
GNU General Public License v2.0
95 stars 117 forks source link

How is the stack pointer set in the newlib library? #39

Closed pentin-as closed 6 years ago

pentin-as commented 6 years ago

I see that sp is used here: https://github.com/riscv/riscv-newlib/blob/77e11e1800f57cac7f5468b2bd064100a44755d4/libgloss/riscv/crt0.S#L38 But before that it was not set anywhere.

I see that sp is set for ARM: https://github.com/riscv/riscv-newlib/blob/77e11e1800f57cac7f5468b2bd064100a44755d4/libgloss/arm/crt0.S#L196

I see that sp is set in the RISC-V tests: https://github.com/riscv/riscv-test-env/blob/68cad7baf3ed0a4553fffd14726d24519ee1296a/v/entry.S#L30 https://github.com/riscv/riscv-tests/blob/c37ac4c0a6d7523c96864861a1c9a1181b5cccd5/benchmarks/common/crt.S#L132

But it is not set in newlib. Why?

jim-wilson commented 6 years ago

A BSP (board support package) is very target dependent.

Program compiled using the RISC-V newlib and libgloss ports are known to work on the gdb simulator and riscv-qemu user mode simulator. Looking at the gdb simulator, I see that it explicitly sets a0 and sp before starting execution of the program. Our libgloss port is ignoring a0, but it is using the sp set by the simulator. We use qemu user mode for running these programs, so of course that will also have a stack and a0/a1/a2 already set before calling start, same as a unix exec() call. I wouldn't expect this to work on bare metal, as if you are running in machine mode on bare metal you are going to have to set some CSRs and newlib/libgloss has no support for that. It should work running under any OS that supplies the stack before starting a program.

sifive/freedom-e-sdk on the other hand is expected to work on bare metal. It has a start.S file that loads sp from a _sp global variable that is defined in the linker script. It also initializes various CSRs so that user code can work. Perhaps this is what you are looking for.

pentin-as commented 6 years ago

thank you