查看: 1932|回复: 0
收起左侧

riscv-tests的使用

[复制链接]

  离线 

  • TA的每日心情
    奋斗
    2021-1-15 13:53
  • 签到天数: 26 天

    [LV.4]

    发表于 2020-8-19 11:37:51 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 新ちゃん 于 2020-8-20 22:25 编辑

    3.4 riscv-tests的使用

    3.4.1 riscv-tests目录的作用。


    riscv-tests目录放的是isa、debug、mt和benchmarks的测试文件、底层相关驱动、及其编译的文件,用于测试rocket-chip cpu的性能,可以适当地理解为系统验证,即通过编写C/汇编实现cpu性能的评估。riscv-tests目录的编译依赖于riscv-gnu-toolchain目录,因为C/汇编编译至bin/hex文件都需要用到工具链,同时反汇编的dump文件也需要用到工具链。一般比较常用的是:riscv$(XLEN)-unknown-elf-gcc、riscv$ (XLEN)-unknown-elf-objdump和riscv$ (XLEN)-unknown-elf-objcopy,$ (XLEN)是rocket-chip cpu的处理位数,有32和64两种。


    3.4.2 riscv-tests目录的详细说明。


    一级目录二级目录说明
    benchmarks-benchmarks测试的源文件。
    -common通用的头文件、C函数、底层汇编文件和链接文件。
    -Makefilemake脚本。可以通过修改bmarks来减少编译文件。
    -其他各测试程序的源代码。
    build-riscv-tests目录编译后生成的elf & dump文件。
    configure-configure脚本将Makefile.in文件转为Makfile。
    configure.ac-利用autoconf将configure.ac生成configure脚本。
    debug-利debug测试的源文件,通过Python脚本模拟openocd和gdb工作。
    -programdebug测试的头文件、汇编文件和C代码。
    -targets链接文件和openocd的cfg文件。
    -其他各测试程序的源代码。
    env-定义了几种cpu使用的环境。
    -encoding.h编码头文件,定义了全部CSR寄存器和几种异常。
    -LICENSELICENSE。
    -pvirtual memory is disabled, only core 0 boots up.不使用虚拟内存,没有S模式,单核。
    -pmdvirtual memory is disabled, all cores boot up.不使用虚拟内存,没有S模式,可以多核。
    -ptvirtual memory is disabled, timer interrupt fires every 100 cycles.不使用虚拟内存,没有S模式,同时使能了内部的timer。
    -vvirtual memory is enabled.使用虚拟内存,有S模式。
    isa-RISC-V 32/64全部指令测试的源文件。
    -macros宏文件。
    -Makefilemake脚本。可以通过修改include $(src_dir)/xx/Makefrag来减少编译文件
    -其他各测试程序的源代码。
    LICENSE-LICENSE。
    mt-矩阵乘法测试的源文件。
    -Makefilemake脚本。可以通过修改bmarks_matmul来减少编译文件。
    -其他各测试程序的源代码。
    README.md-riscv-tests目录的相关说明。

    3.4.3 riscv-tests目录使用例子。



    (1) 新建C程序目录,在riscv-tests/benchmarks中新建test目录。

    1. cd benchmarks && mkdir test
    复制代码

    (2) 编写C语言程序,并保存为test.c。
    test.c:

    1. #define U32 *(volatile unsigned int *)

    2. //--------------------------------------------------------------------------
    3. // Main
    4. void main()
    5. {
    6.   int i;
    7.   for ( i = 0; i < 10; i++ )
    8.     U32(0x20400000+4*i) = i;
    9. }
    复制代码

    (3) 由于我生成的rocket-chip memory_port是从0x2000_0000开始的,所有我需要修改链接文件,告诉gcc工具链,我希望代码从0x2000_0000开始。所以需要修改riscv-tests/benchmarks/common目录下的test.ld。

    1. /* . = 0x80000000; */
    2. . = 0x20000000;
    3. .text.init : { *(.text.init) }
    复制代码

    (4) 再次编译riscv-tests目录,然后在riscv-tests/build/benchmarks目录中能找到编译出来的test.riscv(elf文件) & test.riscv.dump(反汇编文件)。


    (5) 最后对riscv-tests/benchmarks/common目录下的crt.S(汇编代码文件)做分析,每个benchmarks目录下的程序都会用到这个文件,#中文的就是注释。
    我只对这个文件做初步分析,很多关键字各位可以自行百度

    1. #关键字段
    2.   .section ".text.init"
    3.   .globl _start
    4. #最开始的代码,将32个通用寄存器置0。
    5. _start:                        
    6.   li  x1, 0
    7.   li  x2, 0
    8.   li  x3, 0
    9.   li  x4, 0
    10.   li  x5, 0
    11.   li  x6, 0
    12.   li  x7, 0
    13.   li  x8, 0
    14.   li  x9, 0
    15.   li  x10,0
    16.   li  x11,0
    17.   li  x12,0
    18.   li  x13,0
    19.   li  x14,0
    20.   li  x15,0
    21.   li  x16,0
    22.   li  x17,0
    23.   li  x18,0
    24.   li  x19,0
    25.   li  x20,0
    26.   li  x21,0
    27.   li  x22,0
    28.   li  x23,0
    29.   li  x24,0
    30.   li  x25,0
    31.   li  x26,0
    32.   li  x27,0
    33.   li  x28,0
    34.   li  x29,0
    35.   li  x30,0
    36.   li  x31,0

    37. #使用浮点或ROCC,必须置位。
    38.   # enable FPU and accelerator if present
    39.   li t0, MSTATUS_FS | MSTATUS_XS
    40.   csrs mstatus, t0

    41.   # make sure XLEN agrees with compilation choice
    42.   li t0, 1
    43.   slli t0, t0, 31
    44. #if __riscv_xlen == 64
    45.   bgez t0, 1f
    46. #else
    47.   bltz t0, 1f
    48. #endif
    49. 2:
    50.   li a0, 1
    51.   sw a0, tohost, t0
    52.   j 2b
    53. 1:

    54. #如果生成的rocket-chip支持浮点操作,则需要将浮点的32个通用寄存器置0。
    55. #ifdef __riscv_flen
    56.   # initialize FPU if we have one
    57.   la t0, 1f
    58.   csrw mtvec, t0

    59.   fssr    x0
    60.   fmv.s.x f0, x0
    61.   fmv.s.x f1, x0
    62.   fmv.s.x f2, x0
    63.   fmv.s.x f3, x0
    64.   fmv.s.x f4, x0
    65.   fmv.s.x f5, x0
    66.   fmv.s.x f6, x0
    67.   fmv.s.x f7, x0
    68.   fmv.s.x f8, x0
    69.   fmv.s.x f9, x0
    70.   fmv.s.x f10,x0
    71.   fmv.s.x f11,x0
    72.   fmv.s.x f12,x0
    73.   fmv.s.x f13,x0
    74.   fmv.s.x f14,x0
    75.   fmv.s.x f15,x0
    76.   fmv.s.x f16,x0
    77.   fmv.s.x f17,x0
    78.   fmv.s.x f18,x0
    79.   fmv.s.x f19,x0
    80.   fmv.s.x f20,x0
    81.   fmv.s.x f21,x0
    82.   fmv.s.x f22,x0
    83.   fmv.s.x f23,x0
    84.   fmv.s.x f24,x0
    85.   fmv.s.x f25,x0
    86.   fmv.s.x f26,x0
    87.   fmv.s.x f27,x0
    88.   fmv.s.x f28,x0
    89.   fmv.s.x f29,x0
    90.   fmv.s.x f30,x0
    91.   fmv.s.x f31,x0
    92. 1:
    93. #endif

    94. #将trap_entry函数的地址付给mtvec CSR寄存器,发生中断或异常时,PC将会跳至mtvec的地址。
    95.   # initialize trap vector
    96.   la t0, trap_entry
    97.   csrw mtvec, t0

    98. #初始化全局点,设置堆栈的位置
    99.   # initialize global pointer
    100. .option push
    101. .option norelax
    102.   la gp, __global_pointer$
    103. .option pop

    104.   la  tp, _end + 63
    105.   and tp, tp, -64

    106.   # get core id
    107.   csrr a0, mhartid
    108.   # for now, assume only 1 core
    109.   li a1, 1
    110. 1:bgeu a0, a1, 1b

    111.   # give each core 128KB of stack + TLS
    112. #define STKSHIFT 17
    113.   sll a2, a0, STKSHIFT
    114.   add tp, tp, a2
    115.   add sp, a0, 1
    116.   sll sp, sp, STKSHIFT
    117.   add sp, sp, tp

    118. #跳至_init的函数中。
    119.   j _init

    120. #对齐位置,接下来是trap_entry函数的汇编代码。
    121.   .align 2
    122. trap_entry:
    123.   addi sp, sp, -272

    124. #异常/中断发生时,保护现场,将32个通用寄存器的值存到某个地方。
    125.   SREG x1, 1*REGBYTES(sp)
    126.   SREG x2, 2*REGBYTES(sp)
    127.   SREG x3, 3*REGBYTES(sp)
    128.   SREG x4, 4*REGBYTES(sp)
    129.   SREG x5, 5*REGBYTES(sp)
    130.   SREG x6, 6*REGBYTES(sp)
    131.   SREG x7, 7*REGBYTES(sp)
    132.   SREG x8, 8*REGBYTES(sp)
    133.   SREG x9, 9*REGBYTES(sp)
    134.   SREG x10, 10*REGBYTES(sp)
    135.   SREG x11, 11*REGBYTES(sp)
    136.   SREG x12, 12*REGBYTES(sp)
    137.   SREG x13, 13*REGBYTES(sp)
    138.   SREG x14, 14*REGBYTES(sp)
    139.   SREG x15, 15*REGBYTES(sp)
    140.   SREG x16, 16*REGBYTES(sp)
    141.   SREG x17, 17*REGBYTES(sp)
    142.   SREG x18, 18*REGBYTES(sp)
    143.   SREG x19, 19*REGBYTES(sp)
    144.   SREG x20, 20*REGBYTES(sp)
    145.   SREG x21, 21*REGBYTES(sp)
    146.   SREG x22, 22*REGBYTES(sp)
    147.   SREG x23, 23*REGBYTES(sp)
    148.   SREG x24, 24*REGBYTES(sp)
    149.   SREG x25, 25*REGBYTES(sp)
    150.   SREG x26, 26*REGBYTES(sp)
    151.   SREG x27, 27*REGBYTES(sp)
    152.   SREG x28, 28*REGBYTES(sp)
    153.   SREG x29, 29*REGBYTES(sp)
    154.   SREG x30, 30*REGBYTES(sp)
    155.   SREG x31, 31*REGBYTES(sp)

    156. #存好一些特殊的CSR寄存器值,并跳至handle_trap函数中。
    157.   csrr a0, mcause
    158.   csrr a1, mepc
    159.   SREG a1, 32*REGBYTES(sp)
    160.   mv a2, sp
    161.   jal handle_trap
    162.   LREG a1, 32*REGBYTES(sp)
    163.   csrw mepc, a1

    164. #返回之前的工作模式
    165.   # Remain in M-mode after eret
    166.   li t0, MSTATUS_MPP
    167.   csrs mstatus, t0

    168. #恢复现场,将之前保存的32个通用寄存器的值返回。
    169.   LREG x1, 1*REGBYTES(sp)
    170.   LREG x2, 2*REGBYTES(sp)
    171.   LREG x3, 3*REGBYTES(sp)
    172.   LREG x4, 4*REGBYTES(sp)
    173.   LREG x5, 5*REGBYTES(sp)
    174.   LREG x6, 6*REGBYTES(sp)
    175.   LREG x7, 7*REGBYTES(sp)
    176.   LREG x8, 8*REGBYTES(sp)
    177.   LREG x9, 9*REGBYTES(sp)
    178.   LREG x10, 10*REGBYTES(sp)
    179.   LREG x11, 11*REGBYTES(sp)
    180.   LREG x12, 12*REGBYTES(sp)
    181.   LREG x13, 13*REGBYTES(sp)
    182.   LREG x14, 14*REGBYTES(sp)
    183.   LREG x15, 15*REGBYTES(sp)
    184.   LREG x16, 16*REGBYTES(sp)
    185.   LREG x17, 17*REGBYTES(sp)
    186.   LREG x18, 18*REGBYTES(sp)
    187.   LREG x19, 19*REGBYTES(sp)
    188.   LREG x20, 20*REGBYTES(sp)
    189.   LREG x21, 21*REGBYTES(sp)
    190.   LREG x22, 22*REGBYTES(sp)
    191.   LREG x23, 23*REGBYTES(sp)
    192.   LREG x24, 24*REGBYTES(sp)
    193.   LREG x25, 25*REGBYTES(sp)
    194.   LREG x26, 26*REGBYTES(sp)
    195.   LREG x27, 27*REGBYTES(sp)
    196.   LREG x28, 28*REGBYTES(sp)
    197.   LREG x29, 29*REGBYTES(sp)
    198.   LREG x30, 30*REGBYTES(sp)
    199.   LREG x31, 31*REGBYTES(sp)

    200.   addi sp, sp, 272
    201.   mret

    202. .section ".tdata.begin"
    203. .globl _tdata_begin
    204. _tdata_begin:

    205. .section ".tdata.end"
    206. .globl _tdata_end
    207. _tdata_end:

    208. .section ".tbss.end"
    209. .globl _tbss_end
    210. _tbss_end:

    211. .section ".tohost","aw",@progbits
    212. .align 6
    213. .globl tohost
    214. tohost: .dword 0
    215. .align 6
    216. .globl fromhost
    217. fromhost: .dword 0
    复制代码

    本篇完,感谢关注:RISC-V单片机中文网





    上一篇:2020年8月 中国电子学会 第十五届中国研究生电子设计竞赛
    下一篇:chisel3的安装与使用
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-3-29 21:28 , Processed in 0.829697 second(s), 44 queries .

    快速回复 返回顶部 返回列表