GD32V移植说明

概述

GD32V相关的代码:

  • 架构描述层(ADL): XWOS/xwcd/soc/riscv/nuclei/gcc
  • CPU描述层(CDL): XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee
  • SOC描述层(SDL)
    • GD32V: XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v

启动流程

  • 程序入口: XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/soc.S: soc_boot

中断

  • 采用 非向量模式 ,统一的入口: XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/soc.S: soc_isr_entry
  • 使用RISC-V标准寄存器 mscratch 来实现ARM-Cortex-M类似的双栈结构的工作方式
  • 异常统一的入口 XWOS/xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/soc.S: soc_esr_entry
  • 源码:
    • 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

调度

  • 源码:
    • 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

栈结构

  • RISC-V要求栈必须按 16字节 对齐;
  • RISC-V只使用 满递减栈
  • RISC-V的ABI文档中将寄存器分为两类:caller-saved (即volatile)和callee-saved (即non-volatile) 。

caller-saved栈结构

从线程进入中断时,中断入口程序会自动将caller-saved寄存器保存到栈中:

 *  __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栈结构

切换上下文时,需要保存与恢复callee-saved寄存器栈结构如下:

 *  __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__

滴答定时器

  • 使用RISC-V标准中定义的定时器来产生滴答中断。
  • 源码:
    • xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_syshwt.h
    • xwcd/soc/riscv/nuclei/gcc/bumblebee/gd32v/xwosimpl_syshwt.c

TLS

TLS是C11标准开始引入的语言特性。XWOS支持TLS:

XWOS/xwcd/soc/riscv/nuclei/xwosimpl_tls.c

XWOS将TLS数据段放在线程栈内存起始的位置。

            ------------------------
            | Thread Stack Memmory |
            +----------------------+
   SP --->  |                      |
            |                      |
            |                      |
            |                      |
            |                      |
            |                      |
            |     Stack Region     |
            |                      |
            |                      |
            |                      |
            |                      |
            |                      |
            |                      |
            +----------------------+
            |                      |
            |     Stack Guard      |
            |                      |
            +----------------------+
            |                      |
            |      TLS Region      |
            |                      |
            ------------------------

RISC-V有专门用于TLS的寄存器x4(tp),在线程初始化时,需要让x4指向TLS的起始位置。 切换上下文时也要切换x4的值。