GD32V Porting Guide

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

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 mscratch to 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.h
    • XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_irq.h
    • XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_irq.c
    • XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/soc.S

Scheduler

  • Source code:
    • XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_skd.h
    • XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_skd.c
    • XWOS/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.h
    • xwcd/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.