GD32V Porting Guide
3 minute read
Overview
GD32V-related code:
- Architecture Description Layer (ADL):
XWOS/xwcd/soc/riscv/nuclei/gcc - CPU Description Layer (CDL):
XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee - SoC Description Layer (SDL)
- GD32V:
XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v
- GD32V:
Boot Flow
- Program entry:
XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/soc.S: soc_boot
Interrupts
- Uses non-vectored mode, unified entry:
XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/soc.S: soc_isr_entry - Uses the RISC-V standard register
mscratchto implement a dual-stack working mode similar to ARM-Cortex-M - Unified exception entry:
XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/soc.S: soc_esr_entry - Source code:
XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_soc_irq.hXWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_irq.hXWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_irq.cXWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/soc.S
Scheduler
- Source code:
XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_skd.hXWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_skd.cXWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosasmimpl_skd.S
Stack Layout
- RISC-V requires the stack to be 16-byte aligned;
- RISC-V only uses full descending stacks;
- RISC-V ABI documents divide registers into two types: caller-saved (i.e., volatile) and callee-saved (i.e., non-volatile).
Caller-Saved Stack Layout
When entering an interrupt from a thread, the interrupt entry routine automatically saves caller-saved registers to the stack:
* __caller-saved (volatile) context__
* 19 * 4 t6 (x31) ----------
* 18 * 4 t5 (x30) |
* 17 * 4 t4 (x29) |
* 16 * 4 t3 (x28) |
* 15 * 4 a7 (x17) |
* 14 * 4 a6 (x16) |
* 13 * 4 msubm --------+ |
* 12 * 4 mepc | |
* 11 * 4 mcause | |
* 10 * 4 mscratch | |
* 9 * 4 a5 (x15) | RV32I
* 8 * 4 a4 (x14) | |
* 7 * 4 a3 (x13) | |
* 6 * 4 a2 (x12) RV32E |
* 5 * 4 a1 (x11) | |
* 4 * 4 a0 (x10) | |
* 3 * 4 t2 (x7) | |
* 2 * 4 t1 (x6) | |
* 1 * 4 t0 (x5) | |
* 0 * 4 ra (x1) | |
* __caller-saved (volatile) context__
Callee-Saved Stack Layout
When switching contexts, the callee-saved register stack layout that needs to be saved and restored is as follows:
* __callee-saved (non-volatile) context__
* 13 * 4 s11 (x27) |
* 12 * 4 s10 (x26) |
* 11 * 4 s9 (x25) |
* 10 * 4 s8 (x24) |
* 9 * 4 s7 (x23) |
* 8 * 4 s6 (x22) |
* 7 * 4 s5 (x21) RV32I
* 6 * 4 s4 (x20) |
* 5 * 4 s3 (x19) |
* 4 * 4 s2 (x18) |
* 3 * 4 mstatus ------+ |
* 2 * 4 s1 (x9) | |
* 1 * 4 s0 (x8) RV32E |
* 0 * 4 tp (x4) | |
* __callee-saved (non-volatile) context__
Tick Timer
- Uses the timer defined in the RISC-V standard to generate tick interrupts.
- Source code:
xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_syshwt.hxwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_syshwt.c
TLS
TLS is a language feature introduced starting from the C11 standard. XWOS supports TLS:
XWOS/xwcd/soc/riscv/nuclei/xwosimpl_tls.c
XWOS places the TLS data section at the start of the thread stack memory.
------------------------
| Thread Stack Memory |
+----------------------+
SP ---> | |
| |
| |
| |
| |
| |
| Stack Region |
| |
| |
| |
| |
| |
| |
+----------------------+
| |
| Stack Guard |
| |
+----------------------+
| |
| TLS Region |
| |
------------------------
RISC-V has a dedicated register x4 (tp) for TLS. During thread initialization, x4 needs to point to the start of TLS. When switching contexts, the value of x4 must also be switched.