mirror of
https://github.com/lowRISC/ibex.git
synced 2025-06-28 17:24:11 -04:00
vendored riscv test env for common macro files
This commit is contained in:
parent
d51437bcf9
commit
72e9bcd488
20 changed files with 1801 additions and 1633 deletions
|
@ -10,6 +10,10 @@
|
||||||
RVTEST_RV64M
|
RVTEST_RV64M
|
||||||
RVTEST_CODE_BEGIN
|
RVTEST_CODE_BEGIN
|
||||||
|
|
||||||
|
# setting machine handler
|
||||||
|
la t0, mtvec_handler
|
||||||
|
csrw mtvec, t0
|
||||||
|
|
||||||
# setting the PMP region
|
# setting the PMP region
|
||||||
la t0, pmp_region_start
|
la t0, pmp_region_start
|
||||||
srli t1, t0, PMP_SHIFT
|
srli t1, t0, PMP_SHIFT
|
||||||
|
@ -23,8 +27,14 @@ RVTEST_CODE_BEGIN
|
||||||
# access across the boundary between PMP and non-PMP
|
# access across the boundary between PMP and non-PMP
|
||||||
lw t1, -2(t0)
|
lw t1, -2(t0)
|
||||||
|
|
||||||
|
j pass
|
||||||
|
|
||||||
TEST_PASSFAIL
|
TEST_PASSFAIL
|
||||||
|
|
||||||
|
.balign 256
|
||||||
|
mtvec_handler:
|
||||||
|
j fail
|
||||||
|
|
||||||
RVTEST_CODE_END
|
RVTEST_CODE_END
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
ld_script: link.ld
|
ld_script: link.ld
|
||||||
includes: .
|
includes: .
|
||||||
gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
|
gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
|
||||||
|
-I../../../vendor/riscv-test-env/
|
||||||
|
-I../../../vendor/riscv-test-env/p/
|
||||||
|
-I../../../vendor/riscv-tests/isa/macros/scalar/
|
||||||
rtl_test: core_ibex_base_test
|
rtl_test: core_ibex_base_test
|
||||||
rtl_params:
|
rtl_params:
|
||||||
PMPEnable: 1
|
PMPEnable: 1
|
||||||
|
@ -28,3 +31,10 @@
|
||||||
iterations: 1
|
iterations: 1
|
||||||
test_srcs: empty/empty.S
|
test_srcs: empty/empty.S
|
||||||
config: base
|
config: base
|
||||||
|
|
||||||
|
- test: access_pmp_overlap
|
||||||
|
desc: >
|
||||||
|
PMP access basic test
|
||||||
|
iterations: 1
|
||||||
|
test_srcs: access_pmp_overlap/access_pmp_overlap.S
|
||||||
|
config: base
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Copyright lowRISC contributors.
|
||||||
// Ibex specific macros
|
// Ibex specific macros
|
||||||
#define SIGNATURE_ADDR 0x8ffffff8
|
#define SIGNATURE_ADDR 0x8ffffff8
|
||||||
|
|
||||||
|
|
|
@ -1,754 +0,0 @@
|
||||||
// See LICENSE for license details.
|
|
||||||
// clang-format off
|
|
||||||
|
|
||||||
#ifndef __TEST_MACROS_SCALAR_H
|
|
||||||
#define __TEST_MACROS_SCALAR_H
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# Helper macros
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1))
|
|
||||||
|
|
||||||
#define TEST_CASE( testnum, testreg, correctval, code... ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
code; \
|
|
||||||
li x7, MASK_XLEN(correctval); \
|
|
||||||
bne testreg, x7, fail;
|
|
||||||
|
|
||||||
# We use a macro hack to simpify code generation for various numbers
|
|
||||||
# of bubble cycles.
|
|
||||||
|
|
||||||
#define TEST_INSERT_NOPS_0
|
|
||||||
#define TEST_INSERT_NOPS_1 nop; TEST_INSERT_NOPS_0
|
|
||||||
#define TEST_INSERT_NOPS_2 nop; TEST_INSERT_NOPS_1
|
|
||||||
#define TEST_INSERT_NOPS_3 nop; TEST_INSERT_NOPS_2
|
|
||||||
#define TEST_INSERT_NOPS_4 nop; TEST_INSERT_NOPS_3
|
|
||||||
#define TEST_INSERT_NOPS_5 nop; TEST_INSERT_NOPS_4
|
|
||||||
#define TEST_INSERT_NOPS_6 nop; TEST_INSERT_NOPS_5
|
|
||||||
#define TEST_INSERT_NOPS_7 nop; TEST_INSERT_NOPS_6
|
|
||||||
#define TEST_INSERT_NOPS_8 nop; TEST_INSERT_NOPS_7
|
|
||||||
#define TEST_INSERT_NOPS_9 nop; TEST_INSERT_NOPS_8
|
|
||||||
#define TEST_INSERT_NOPS_10 nop; TEST_INSERT_NOPS_9
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# RV64UI MACROS
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# Tests for instructions with immediate operand
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11))
|
|
||||||
|
|
||||||
#define TEST_IMM_OP( testnum, inst, result, val1, imm ) \
|
|
||||||
TEST_CASE( testnum, x14, result, \
|
|
||||||
li x1, MASK_XLEN(val1); \
|
|
||||||
inst x14, x1, SEXT_IMM(imm); \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_IMM_SRC1_EQ_DEST( testnum, inst, result, val1, imm ) \
|
|
||||||
TEST_CASE( testnum, x1, result, \
|
|
||||||
li x1, MASK_XLEN(val1); \
|
|
||||||
inst x1, x1, SEXT_IMM(imm); \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_IMM_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \
|
|
||||||
TEST_CASE( testnum, x6, result, \
|
|
||||||
li x4, 0; \
|
|
||||||
1: li x1, MASK_XLEN(val1); \
|
|
||||||
inst x14, x1, SEXT_IMM(imm); \
|
|
||||||
TEST_INSERT_NOPS_ ## nop_cycles \
|
|
||||||
addi x6, x14, 0; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_IMM_SRC1_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \
|
|
||||||
TEST_CASE( testnum, x14, result, \
|
|
||||||
li x4, 0; \
|
|
||||||
1: li x1, MASK_XLEN(val1); \
|
|
||||||
TEST_INSERT_NOPS_ ## nop_cycles \
|
|
||||||
inst x14, x1, SEXT_IMM(imm); \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_IMM_ZEROSRC1( testnum, inst, result, imm ) \
|
|
||||||
TEST_CASE( testnum, x1, result, \
|
|
||||||
inst x1, x0, SEXT_IMM(imm); \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_IMM_ZERODEST( testnum, inst, val1, imm ) \
|
|
||||||
TEST_CASE( testnum, x0, 0, \
|
|
||||||
li x1, MASK_XLEN(val1); \
|
|
||||||
inst x0, x1, SEXT_IMM(imm); \
|
|
||||||
)
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# Tests for an instruction with register operands
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define TEST_R_OP( testnum, inst, result, val1 ) \
|
|
||||||
TEST_CASE( testnum, x14, result, \
|
|
||||||
li x1, val1; \
|
|
||||||
inst x14, x1; \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_R_SRC1_EQ_DEST( testnum, inst, result, val1 ) \
|
|
||||||
TEST_CASE( testnum, x1, result, \
|
|
||||||
li x1, val1; \
|
|
||||||
inst x1, x1; \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_R_DEST_BYPASS( testnum, nop_cycles, inst, result, val1 ) \
|
|
||||||
TEST_CASE( testnum, x6, result, \
|
|
||||||
li x4, 0; \
|
|
||||||
1: li x1, val1; \
|
|
||||||
inst x14, x1; \
|
|
||||||
TEST_INSERT_NOPS_ ## nop_cycles \
|
|
||||||
addi x6, x14, 0; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
)
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# Tests for an instruction with register-register operands
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define TEST_RR_OP( testnum, inst, result, val1, val2 ) \
|
|
||||||
TEST_CASE( testnum, x14, result, \
|
|
||||||
li x1, MASK_XLEN(val1); \
|
|
||||||
li x2, MASK_XLEN(val2); \
|
|
||||||
inst x14, x1, x2; \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_RR_SRC1_EQ_DEST( testnum, inst, result, val1, val2 ) \
|
|
||||||
TEST_CASE( testnum, x1, result, \
|
|
||||||
li x1, MASK_XLEN(val1); \
|
|
||||||
li x2, MASK_XLEN(val2); \
|
|
||||||
inst x1, x1, x2; \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_RR_SRC2_EQ_DEST( testnum, inst, result, val1, val2 ) \
|
|
||||||
TEST_CASE( testnum, x2, result, \
|
|
||||||
li x1, MASK_XLEN(val1); \
|
|
||||||
li x2, MASK_XLEN(val2); \
|
|
||||||
inst x2, x1, x2; \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_RR_SRC12_EQ_DEST( testnum, inst, result, val1 ) \
|
|
||||||
TEST_CASE( testnum, x1, result, \
|
|
||||||
li x1, MASK_XLEN(val1); \
|
|
||||||
inst x1, x1, x1; \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_RR_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, val2 ) \
|
|
||||||
TEST_CASE( testnum, x6, result, \
|
|
||||||
li x4, 0; \
|
|
||||||
1: li x1, MASK_XLEN(val1); \
|
|
||||||
li x2, MASK_XLEN(val2); \
|
|
||||||
inst x14, x1, x2; \
|
|
||||||
TEST_INSERT_NOPS_ ## nop_cycles \
|
|
||||||
addi x6, x14, 0; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_RR_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
|
|
||||||
TEST_CASE( testnum, x14, result, \
|
|
||||||
li x4, 0; \
|
|
||||||
1: li x1, MASK_XLEN(val1); \
|
|
||||||
TEST_INSERT_NOPS_ ## src1_nops \
|
|
||||||
li x2, MASK_XLEN(val2); \
|
|
||||||
TEST_INSERT_NOPS_ ## src2_nops \
|
|
||||||
inst x14, x1, x2; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_RR_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
|
|
||||||
TEST_CASE( testnum, x14, result, \
|
|
||||||
li x4, 0; \
|
|
||||||
1: li x2, MASK_XLEN(val2); \
|
|
||||||
TEST_INSERT_NOPS_ ## src1_nops \
|
|
||||||
li x1, MASK_XLEN(val1); \
|
|
||||||
TEST_INSERT_NOPS_ ## src2_nops \
|
|
||||||
inst x14, x1, x2; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_RR_ZEROSRC1( testnum, inst, result, val ) \
|
|
||||||
TEST_CASE( testnum, x2, result, \
|
|
||||||
li x1, MASK_XLEN(val); \
|
|
||||||
inst x2, x0, x1; \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_RR_ZEROSRC2( testnum, inst, result, val ) \
|
|
||||||
TEST_CASE( testnum, x2, result, \
|
|
||||||
li x1, MASK_XLEN(val); \
|
|
||||||
inst x2, x1, x0; \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_RR_ZEROSRC12( testnum, inst, result ) \
|
|
||||||
TEST_CASE( testnum, x1, result, \
|
|
||||||
inst x1, x0, x0; \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_RR_ZERODEST( testnum, inst, val1, val2 ) \
|
|
||||||
TEST_CASE( testnum, x0, 0, \
|
|
||||||
li x1, MASK_XLEN(val1); \
|
|
||||||
li x2, MASK_XLEN(val2); \
|
|
||||||
inst x0, x1, x2; \
|
|
||||||
)
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# Test memory instructions
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define TEST_LD_OP( testnum, inst, result, offset, base ) \
|
|
||||||
TEST_CASE( testnum, x14, result, \
|
|
||||||
li x15, result; /* Tell the exception handler the expected result. */ \
|
|
||||||
la x1, base; \
|
|
||||||
inst x14, offset(x1); \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_ST_OP( testnum, load_inst, store_inst, result, offset, base ) \
|
|
||||||
TEST_CASE( testnum, x14, result, \
|
|
||||||
la x1, base; \
|
|
||||||
li x2, result; \
|
|
||||||
la x15, 7f; /* Tell the exception handler how to skip this test. */ \
|
|
||||||
store_inst x2, offset(x1); \
|
|
||||||
load_inst x14, offset(x1); \
|
|
||||||
j 8f; \
|
|
||||||
7: \
|
|
||||||
/* Set up the correct result for TEST_CASE(). */ \
|
|
||||||
mv x14, x2; \
|
|
||||||
8: \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define TEST_LD_DEST_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
li x4, 0; \
|
|
||||||
1: la x1, base; \
|
|
||||||
inst x14, offset(x1); \
|
|
||||||
TEST_INSERT_NOPS_ ## nop_cycles \
|
|
||||||
addi x6, x14, 0; \
|
|
||||||
li x7, result; \
|
|
||||||
bne x6, x7, fail; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b; \
|
|
||||||
|
|
||||||
#define TEST_LD_SRC1_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
li x4, 0; \
|
|
||||||
1: la x1, base; \
|
|
||||||
TEST_INSERT_NOPS_ ## nop_cycles \
|
|
||||||
inst x14, offset(x1); \
|
|
||||||
li x7, result; \
|
|
||||||
bne x14, x7, fail; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
|
|
||||||
#define TEST_ST_SRC12_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
li x4, 0; \
|
|
||||||
1: li x1, result; \
|
|
||||||
TEST_INSERT_NOPS_ ## src1_nops \
|
|
||||||
la x2, base; \
|
|
||||||
TEST_INSERT_NOPS_ ## src2_nops \
|
|
||||||
store_inst x1, offset(x2); \
|
|
||||||
load_inst x14, offset(x2); \
|
|
||||||
li x7, result; \
|
|
||||||
bne x14, x7, fail; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
|
|
||||||
#define TEST_ST_SRC21_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
li x4, 0; \
|
|
||||||
1: la x2, base; \
|
|
||||||
TEST_INSERT_NOPS_ ## src1_nops \
|
|
||||||
li x1, result; \
|
|
||||||
TEST_INSERT_NOPS_ ## src2_nops \
|
|
||||||
store_inst x1, offset(x2); \
|
|
||||||
load_inst x14, offset(x2); \
|
|
||||||
li x7, result; \
|
|
||||||
bne x14, x7, fail; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
|
|
||||||
#define TEST_BR2_OP_TAKEN( testnum, inst, val1, val2 ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
li x1, val1; \
|
|
||||||
li x2, val2; \
|
|
||||||
inst x1, x2, 2f; \
|
|
||||||
bne x0, TESTNUM, fail; \
|
|
||||||
1: bne x0, TESTNUM, 3f; \
|
|
||||||
2: inst x1, x2, 1b; \
|
|
||||||
bne x0, TESTNUM, fail; \
|
|
||||||
3:
|
|
||||||
|
|
||||||
#define TEST_BR2_OP_NOTTAKEN( testnum, inst, val1, val2 ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
li x1, val1; \
|
|
||||||
li x2, val2; \
|
|
||||||
inst x1, x2, 1f; \
|
|
||||||
bne x0, TESTNUM, 2f; \
|
|
||||||
1: bne x0, TESTNUM, fail; \
|
|
||||||
2: inst x1, x2, 1b; \
|
|
||||||
3:
|
|
||||||
|
|
||||||
#define TEST_BR2_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
li x4, 0; \
|
|
||||||
1: li x1, val1; \
|
|
||||||
TEST_INSERT_NOPS_ ## src1_nops \
|
|
||||||
li x2, val2; \
|
|
||||||
TEST_INSERT_NOPS_ ## src2_nops \
|
|
||||||
inst x1, x2, fail; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
|
|
||||||
#define TEST_BR2_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
li x4, 0; \
|
|
||||||
1: li x2, val2; \
|
|
||||||
TEST_INSERT_NOPS_ ## src1_nops \
|
|
||||||
li x1, val1; \
|
|
||||||
TEST_INSERT_NOPS_ ## src2_nops \
|
|
||||||
inst x1, x2, fail; \
|
|
||||||
addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# Test jump instructions
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define TEST_JR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
li x4, 0; \
|
|
||||||
1: la x6, 2f; \
|
|
||||||
TEST_INSERT_NOPS_ ## nop_cycles \
|
|
||||||
inst x6; \
|
|
||||||
bne x0, TESTNUM, fail; \
|
|
||||||
2: addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
|
|
||||||
#define TEST_JALR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
li x4, 0; \
|
|
||||||
1: la x6, 2f; \
|
|
||||||
TEST_INSERT_NOPS_ ## nop_cycles \
|
|
||||||
inst x13, x6, 0; \
|
|
||||||
bne x0, TESTNUM, fail; \
|
|
||||||
2: addi x4, x4, 1; \
|
|
||||||
li x5, 2; \
|
|
||||||
bne x4, x5, 1b \
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# RV64UF MACROS
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# Tests floating-point instructions
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define qNaNh 0h:7e00
|
|
||||||
#define sNaNh 0h:7c01
|
|
||||||
#define qNaNf 0f:7fc00000
|
|
||||||
#define sNaNf 0f:7f800001
|
|
||||||
#define qNaN 0d:7ff8000000000000
|
|
||||||
#define sNaN 0d:7ff0000000000001
|
|
||||||
|
|
||||||
#define TEST_FP_OP_H_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
la a0, test_ ## testnum ## _data ;\
|
|
||||||
flh f0, 0(a0); \
|
|
||||||
flh f1, 2(a0); \
|
|
||||||
flh f2, 4(a0); \
|
|
||||||
lh a3, 6(a0); \
|
|
||||||
code; \
|
|
||||||
fsflags a1, x0; \
|
|
||||||
li a2, flags; \
|
|
||||||
bne a0, a3, fail; \
|
|
||||||
bne a1, a2, fail; \
|
|
||||||
.pushsection .data; \
|
|
||||||
.align 1; \
|
|
||||||
test_ ## testnum ## _data: \
|
|
||||||
.float16 val1; \
|
|
||||||
.float16 val2; \
|
|
||||||
.float16 val3; \
|
|
||||||
.result; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
#define TEST_FP_OP_S_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
la a0, test_ ## testnum ## _data ;\
|
|
||||||
flw f0, 0(a0); \
|
|
||||||
flw f1, 4(a0); \
|
|
||||||
flw f2, 8(a0); \
|
|
||||||
lw a3, 12(a0); \
|
|
||||||
code; \
|
|
||||||
fsflags a1, x0; \
|
|
||||||
li a2, flags; \
|
|
||||||
bne a0, a3, fail; \
|
|
||||||
bne a1, a2, fail; \
|
|
||||||
.pushsection .data; \
|
|
||||||
.align 2; \
|
|
||||||
test_ ## testnum ## _data: \
|
|
||||||
.float val1; \
|
|
||||||
.float val2; \
|
|
||||||
.float val3; \
|
|
||||||
.result; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
#define TEST_FP_OP_D_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
la a0, test_ ## testnum ## _data ;\
|
|
||||||
fld f0, 0(a0); \
|
|
||||||
fld f1, 8(a0); \
|
|
||||||
fld f2, 16(a0); \
|
|
||||||
ld a3, 24(a0); \
|
|
||||||
code; \
|
|
||||||
fsflags a1, x0; \
|
|
||||||
li a2, flags; \
|
|
||||||
bne a0, a3, fail; \
|
|
||||||
bne a1, a2, fail; \
|
|
||||||
.pushsection .data; \
|
|
||||||
.align 3; \
|
|
||||||
test_ ## testnum ## _data: \
|
|
||||||
.double val1; \
|
|
||||||
.double val2; \
|
|
||||||
.double val3; \
|
|
||||||
.result; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
// TODO: assign a separate mem location for the comparison address?
|
|
||||||
#define TEST_FP_OP_D32_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
la a0, test_ ## testnum ## _data ;\
|
|
||||||
fld f0, 0(a0); \
|
|
||||||
fld f1, 8(a0); \
|
|
||||||
fld f2, 16(a0); \
|
|
||||||
lw a3, 24(a0); \
|
|
||||||
lw t1, 28(a0); \
|
|
||||||
code; \
|
|
||||||
fsflags a1, x0; \
|
|
||||||
li a2, flags; \
|
|
||||||
bne a0, a3, fail; \
|
|
||||||
bne t1, t2, fail; \
|
|
||||||
bne a1, a2, fail; \
|
|
||||||
.pushsection .data; \
|
|
||||||
.align 3; \
|
|
||||||
test_ ## testnum ## _data: \
|
|
||||||
.double val1; \
|
|
||||||
.double val2; \
|
|
||||||
.double val3; \
|
|
||||||
.result; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
#define TEST_FCVT_S_D32( testnum, result, val1 ) \
|
|
||||||
TEST_FP_OP_D32_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
|
|
||||||
fcvt.s.d f3, f0; fcvt.d.s f3, f3; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
|
|
||||||
|
|
||||||
#define TEST_FCVT_S_D( testnum, result, val1 ) \
|
|
||||||
TEST_FP_OP_D_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
|
|
||||||
fcvt.s.d f3, f0; fcvt.d.s f3, f3; fmv.x.d a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FCVT_D_S( testnum, result, val1 ) \
|
|
||||||
TEST_FP_OP_S_INTERNAL( testnum, 0, float result, val1, 0.0, 0.0, \
|
|
||||||
fcvt.d.s f3, f0; fcvt.s.d f3, f3; fmv.x.s a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FCVT_H_S( testnum, result, val1 ) \
|
|
||||||
TEST_FP_OP_H_INTERNAL( testnum, 0, float16 result, val1, 0.0, 0.0, \
|
|
||||||
fcvt.s.h f3, f0; fcvt.h.s f3, f3; fmv.x.h a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FCVT_H_D( testnum, result, val1 ) \
|
|
||||||
TEST_FP_OP_H_INTERNAL( testnum, 0, float16 result, val1, 0.0, 0.0, \
|
|
||||||
fcvt.d.h f3, f0; fcvt.h.d f3, f3; fmv.x.h a0, f3)
|
|
||||||
|
|
||||||
|
|
||||||
#define TEST_FP_OP1_H( testnum, inst, flags, result, val1 ) \
|
|
||||||
TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, val1, 0.0, 0.0, \
|
|
||||||
inst f3, f0; fmv.x.h a0, f3;)
|
|
||||||
|
|
||||||
#define TEST_FP_OP1_S( testnum, inst, flags, result, val1 ) \
|
|
||||||
TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, 0.0, 0.0, \
|
|
||||||
inst f3, f0; fmv.x.s a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_OP1_D32( testnum, inst, flags, result, val1 ) \
|
|
||||||
TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
|
|
||||||
inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
|
|
||||||
// ^: store computation result in address from a0, load high-word into t2
|
|
||||||
|
|
||||||
#define TEST_FP_OP1_D( testnum, inst, flags, result, val1 ) \
|
|
||||||
TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
|
|
||||||
inst f3, f0; fmv.x.d a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_OP1_S_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
|
|
||||||
TEST_FP_OP_S_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
|
|
||||||
inst f3, f0; fmv.x.s a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_OP1_H_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
|
|
||||||
TEST_FP_OP_H_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \
|
|
||||||
inst f3, f0; fmv.x.h a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_OP1_D32_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
|
|
||||||
TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
|
|
||||||
inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
|
|
||||||
// ^: store computation result in address from a0, load high-word into t2
|
|
||||||
|
|
||||||
#define TEST_FP_OP1_D_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
|
|
||||||
TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
|
|
||||||
inst f3, f0; fmv.x.d a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_OP2_S( testnum, inst, flags, result, val1, val2 ) \
|
|
||||||
TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, 0.0, \
|
|
||||||
inst f3, f0, f1; fmv.x.s a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_OP2_H( testnum, inst, flags, result, val1, val2 ) \
|
|
||||||
TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, val1, val2, 0.0, \
|
|
||||||
inst f3, f0, f1; fmv.x.h a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \
|
|
||||||
TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
|
|
||||||
inst f3, f0, f1; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
|
|
||||||
// ^: store computation result in address from a0, load high-word into t2
|
|
||||||
|
|
||||||
#define TEST_FP_OP2_D( testnum, inst, flags, result, val1, val2 ) \
|
|
||||||
TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
|
|
||||||
inst f3, f0, f1; fmv.x.d a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_OP3_S( testnum, inst, flags, result, val1, val2, val3 ) \
|
|
||||||
TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, val3, \
|
|
||||||
inst f3, f0, f1, f2; fmv.x.s a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_OP3_H( testnum, inst, flags, result, val1, val2, val3 ) \
|
|
||||||
TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, val1, val2, val3, \
|
|
||||||
inst f3, f0, f1, f2; fmv.x.h a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \
|
|
||||||
TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, val3, \
|
|
||||||
inst f3, f0, f1, f2; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
|
|
||||||
// ^: store computation result in address from a0, load high-word into t2
|
|
||||||
|
|
||||||
#define TEST_FP_OP3_D( testnum, inst, flags, result, val1, val2, val3 ) \
|
|
||||||
TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, val3, \
|
|
||||||
inst f3, f0, f1, f2; fmv.x.d a0, f3)
|
|
||||||
|
|
||||||
#define TEST_FP_INT_OP_S( testnum, inst, flags, result, val1, rm ) \
|
|
||||||
TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \
|
|
||||||
inst a0, f0, rm)
|
|
||||||
|
|
||||||
#define TEST_FP_INT_OP_H( testnum, inst, flags, result, val1, rm ) \
|
|
||||||
TEST_FP_OP_H_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \
|
|
||||||
inst a0, f0, rm)
|
|
||||||
|
|
||||||
#define TEST_FP_INT_OP_D32( testnum, inst, flags, result, val1, rm ) \
|
|
||||||
TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
|
|
||||||
inst a0, f0, f1; li t2, 0)
|
|
||||||
|
|
||||||
#define TEST_FP_INT_OP_D( testnum, inst, flags, result, val1, rm ) \
|
|
||||||
TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
|
|
||||||
inst a0, f0, rm)
|
|
||||||
|
|
||||||
#define TEST_FP_CMP_OP_S( testnum, inst, flags, result, val1, val2 ) \
|
|
||||||
TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, val2, 0.0, \
|
|
||||||
inst a0, f0, f1)
|
|
||||||
|
|
||||||
#define TEST_FP_CMP_OP_H( testnum, inst, flags, result, val1, val2 ) \
|
|
||||||
TEST_FP_OP_H_INTERNAL( testnum, flags, hword result, val1, val2, 0.0, \
|
|
||||||
inst a0, f0, f1)
|
|
||||||
|
|
||||||
#define TEST_FP_CMP_OP_D32( testnum, inst, flags, result, val1, val2 ) \
|
|
||||||
TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
|
|
||||||
inst a0, f0, f1; li t2, 0)
|
|
||||||
|
|
||||||
#define TEST_FP_CMP_OP_D( testnum, inst, flags, result, val1, val2 ) \
|
|
||||||
TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
|
|
||||||
inst a0, f0, f1)
|
|
||||||
|
|
||||||
#define TEST_FCLASS_S(testnum, correct, input) \
|
|
||||||
TEST_CASE(testnum, a0, correct, li a0, input; fmv.s.x fa0, a0; \
|
|
||||||
fclass.s a0, fa0)
|
|
||||||
|
|
||||||
#define TEST_FCLASS_D32(testnum, correct, input) \
|
|
||||||
TEST_CASE(testnum, a0, correct, \
|
|
||||||
la a0, test_ ## testnum ## _data ;\
|
|
||||||
fld fa0, 0(a0); \
|
|
||||||
fclass.d a0, fa0) \
|
|
||||||
.pushsection .data; \
|
|
||||||
.align 3; \
|
|
||||||
test_ ## testnum ## _data: \
|
|
||||||
.dword input; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
#define TEST_FCLASS_D(testnum, correct, input) \
|
|
||||||
TEST_CASE(testnum, a0, correct, li a0, input; fmv.d.x fa0, a0; \
|
|
||||||
fclass.d a0, fa0)
|
|
||||||
|
|
||||||
#define TEST_INT_FP_OP_S( testnum, inst, result, val1 ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
la a0, test_ ## testnum ## _data ;\
|
|
||||||
lw a3, 0(a0); \
|
|
||||||
li a0, val1; \
|
|
||||||
inst f0, a0; \
|
|
||||||
fsflags x0; \
|
|
||||||
fmv.x.s a0, f0; \
|
|
||||||
bne a0, a3, fail; \
|
|
||||||
.pushsection .data; \
|
|
||||||
.align 2; \
|
|
||||||
test_ ## testnum ## _data: \
|
|
||||||
.float result; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
#define TEST_INT_FP_OP_H( testnum, inst, result, val1 ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
la a0, test_ ## testnum ## _data ;\
|
|
||||||
lh a3, 0(a0); \
|
|
||||||
li a0, val1; \
|
|
||||||
inst f0, a0; \
|
|
||||||
fsflags x0; \
|
|
||||||
fmv.x.h a0, f0; \
|
|
||||||
bne a0, a3, fail; \
|
|
||||||
.pushsection .data; \
|
|
||||||
.align 1; \
|
|
||||||
test_ ## testnum ## _data: \
|
|
||||||
.float16 result; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
#define TEST_INT_FP_OP_D32( testnum, inst, result, val1 ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
la a0, test_ ## testnum ## _data ;\
|
|
||||||
lw a3, 0(a0); \
|
|
||||||
lw a4, 4(a0); \
|
|
||||||
li a1, val1; \
|
|
||||||
inst f0, a1; \
|
|
||||||
\
|
|
||||||
fsd f0, 0(a0); \
|
|
||||||
lw a1, 4(a0); \
|
|
||||||
lw a0, 0(a0); \
|
|
||||||
\
|
|
||||||
fsflags x0; \
|
|
||||||
bne a0, a3, fail; \
|
|
||||||
bne a1, a4, fail; \
|
|
||||||
.pushsection .data; \
|
|
||||||
.align 3; \
|
|
||||||
test_ ## testnum ## _data: \
|
|
||||||
.double result; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
#define TEST_INT_FP_OP_D( testnum, inst, result, val1 ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
la a0, test_ ## testnum ## _data ;\
|
|
||||||
ld a3, 0(a0); \
|
|
||||||
li a0, val1; \
|
|
||||||
inst f0, a0; \
|
|
||||||
fsflags x0; \
|
|
||||||
fmv.x.d a0, f0; \
|
|
||||||
bne a0, a3, fail; \
|
|
||||||
.pushsection .data; \
|
|
||||||
.align 3; \
|
|
||||||
test_ ## testnum ## _data: \
|
|
||||||
.double result; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
// We need some special handling here to allow 64-bit comparison in 32-bit arch
|
|
||||||
// TODO: find a better name and clean up when intended for general usage?
|
|
||||||
#define TEST_CASE_D32( testnum, testreg1, testreg2, correctval, code... ) \
|
|
||||||
test_ ## testnum: \
|
|
||||||
code; \
|
|
||||||
la x15, test_ ## testnum ## _data ; \
|
|
||||||
lw x7, 0(x15); \
|
|
||||||
lw x15, 4(x15); \
|
|
||||||
li TESTNUM, testnum; \
|
|
||||||
bne testreg1, x7, fail;\
|
|
||||||
bne testreg2, x15, fail;\
|
|
||||||
.pushsection .data; \
|
|
||||||
.align 3; \
|
|
||||||
test_ ## testnum ## _data: \
|
|
||||||
.dword correctval; \
|
|
||||||
.popsection
|
|
||||||
|
|
||||||
// ^ x14 is used in some other macros, to avoid issues we use x15 for upper word
|
|
||||||
|
|
||||||
#define MISALIGNED_LOAD_HANDLER \
|
|
||||||
li t0, CAUSE_MISALIGNED_LOAD; \
|
|
||||||
csrr t1, mcause; \
|
|
||||||
bne t0, t1, fail; \
|
|
||||||
\
|
|
||||||
/* We got a misaligned exception. Pretend we handled it in software */ \
|
|
||||||
/* by loading the correct result here. */ \
|
|
||||||
mv a4, a5; \
|
|
||||||
\
|
|
||||||
/* And skip this instruction */ \
|
|
||||||
csrr t0, mepc; \
|
|
||||||
addi t0, t0, 4; \
|
|
||||||
csrw mepc, t0; \
|
|
||||||
mret
|
|
||||||
|
|
||||||
#define MISALIGNED_STORE_HANDLER \
|
|
||||||
li t0, CAUSE_MISALIGNED_STORE; \
|
|
||||||
csrr t1, mcause; \
|
|
||||||
bne t0, t1, fail; \
|
|
||||||
\
|
|
||||||
/* We got a misaligned exception. Skip this test. */ \
|
|
||||||
csrw mepc, x15; \
|
|
||||||
mret
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# Pass and fail code (assumes test num is in TESTNUM)
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define TEST_PASSFAIL \
|
|
||||||
bne x0, TESTNUM, pass; \
|
|
||||||
fail: \
|
|
||||||
RVTEST_FAIL; \
|
|
||||||
pass: \
|
|
||||||
RVTEST_PASS \
|
|
||||||
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
# Test data section
|
|
||||||
#-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define TEST_DATA
|
|
||||||
|
|
||||||
#endif
|
|
89
vendor/patches/riscv_test_env/changes.patch
vendored
Normal file
89
vendor/patches/riscv_test_env/changes.patch
vendored
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
diff --git a/p/riscv_test.h b/p/riscv_test.h
|
||||||
|
index fe14f086..18fdc0a7 100644
|
||||||
|
--- a/p/riscv_test.h
|
||||||
|
+++ b/p/riscv_test.h
|
||||||
|
@@ -1,9 +1,11 @@
|
||||||
|
// See LICENSE for license details.
|
||||||
|
+// clang-format off
|
||||||
|
|
||||||
|
#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
|
||||||
|
#define _ENV_PHYSICAL_SINGLE_CORE_H
|
||||||
|
|
||||||
|
-#include "../encoding.h"
|
||||||
|
+#include "encoding.h"
|
||||||
|
+#include "ibex_macros.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Begin Macro
|
||||||
|
@@ -190,14 +192,13 @@ handle_exception: \
|
||||||
|
1: ori TESTNUM, TESTNUM, 1337; \
|
||||||
|
write_tohost: \
|
||||||
|
sw TESTNUM, tohost, t5; \
|
||||||
|
- sw zero, tohost + 4, t5; \
|
||||||
|
j write_tohost; \
|
||||||
|
reset_vector: \
|
||||||
|
INIT_XREG; \
|
||||||
|
RISCV_MULTICORE_DISABLE; \
|
||||||
|
- INIT_SATP; \
|
||||||
|
+ /*INIT_SATP; Ibex doesn't support supervisor mode */ \
|
||||||
|
INIT_PMP; \
|
||||||
|
- DELEGATE_NO_TRAPS; \
|
||||||
|
+ /*DELEGATE_NO_TRAPS; Ibex doesn't support supervisor mode */ \
|
||||||
|
li TESTNUM, 0; \
|
||||||
|
la t0, trap_vector; \
|
||||||
|
csrw mtvec, t0; \
|
||||||
|
@@ -212,7 +213,7 @@ reset_vector: \
|
||||||
|
(1 << CAUSE_MISALIGNED_FETCH) | \
|
||||||
|
(1 << CAUSE_USER_ECALL) | \
|
||||||
|
(1 << CAUSE_BREAKPOINT); \
|
||||||
|
- csrw medeleg, t0; \
|
||||||
|
+ /*csrw medeleg, t0; Ibex doesn't support supervisor mode */ \
|
||||||
|
1: csrwi mstatus, 0; \
|
||||||
|
init; \
|
||||||
|
EXTRA_INIT; \
|
||||||
|
@@ -236,20 +237,24 @@ reset_vector: \
|
||||||
|
|
||||||
|
#define RVTEST_PASS \
|
||||||
|
fence; \
|
||||||
|
- li TESTNUM, 1; \
|
||||||
|
- li a7, 93; \
|
||||||
|
- li a0, 0; \
|
||||||
|
- ecall
|
||||||
|
+ li x2, SIGNATURE_ADDR; \
|
||||||
|
+ li x1, (FINISHED_IRQ << 8) | CORE_STATUS; \
|
||||||
|
+ sw x1, 0(x2); \
|
||||||
|
+ li x1, (TEST_PASS << 8) | TEST_RESULT; \
|
||||||
|
+ sw x1, 0(x2); \
|
||||||
|
+ 2:; \
|
||||||
|
+ j 2b;
|
||||||
|
|
||||||
|
#define TESTNUM gp
|
||||||
|
#define RVTEST_FAIL \
|
||||||
|
fence; \
|
||||||
|
-1: beqz TESTNUM, 1b; \
|
||||||
|
- sll TESTNUM, TESTNUM, 1; \
|
||||||
|
- or TESTNUM, TESTNUM, 1; \
|
||||||
|
- li a7, 93; \
|
||||||
|
- addi a0, TESTNUM, 0; \
|
||||||
|
- ecall
|
||||||
|
+ li x2, SIGNATURE_ADDR; \
|
||||||
|
+ li x1, (FINISHED_IRQ << 8) | CORE_STATUS; \
|
||||||
|
+ sw x1, 0(x2); \
|
||||||
|
+ li x1, (TEST_FAIL << 8) | TEST_RESULT; \
|
||||||
|
+ sw x1, 0(x2); \
|
||||||
|
+ 2:; \
|
||||||
|
+ j 2b;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Data Section Macro
|
||||||
|
@@ -260,8 +265,8 @@ reset_vector: \
|
||||||
|
#define RVTEST_DATA_BEGIN \
|
||||||
|
EXTRA_DATA \
|
||||||
|
.pushsection .tohost,"aw",@progbits; \
|
||||||
|
- .align 6; .global tohost; tohost: .dword 0; .size tohost, 8; \
|
||||||
|
- .align 6; .global fromhost; fromhost: .dword 0; .size fromhost, 8;\
|
||||||
|
+ .align 6; .global tohost; tohost: .dword 0; \
|
||||||
|
+ .align 6; .global fromhost; fromhost: .dword 0; \
|
||||||
|
.popsection; \
|
||||||
|
.align 4; .global begin_signature; begin_signature:
|
||||||
|
|
24
vendor/riscv-test-env/LICENSE
vendored
Normal file
24
vendor/riscv-test-env/LICENSE
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
Copyright (c) 2012-2015, The Regents of the University of California (Regents).
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the Regents nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
|
||||||
|
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
|
||||||
|
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
|
||||||
|
HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
|
||||||
|
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
File diff suppressed because it is too large
Load diff
17
vendor/riscv-test-env/p/link.ld
vendored
Normal file
17
vendor/riscv-test-env/p/link.ld
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000000;
|
||||||
|
.text.init : { *(.text.init) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.tohost : { *(.tohost) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.text : { *(.text) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.data : { *(.data) }
|
||||||
|
.bss : { *(.bss) }
|
||||||
|
_end = .;
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#define _ENV_PHYSICAL_SINGLE_CORE_H
|
#define _ENV_PHYSICAL_SINGLE_CORE_H
|
||||||
|
|
||||||
#include "encoding.h"
|
#include "encoding.h"
|
||||||
|
#include "ibex_macros.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
// Begin Macro
|
// Begin Macro
|
17
vendor/riscv-test-env/pm/link.ld
vendored
Normal file
17
vendor/riscv-test-env/pm/link.ld
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000000;
|
||||||
|
.text.init : { *(.text.init) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.tohost : { *(.tohost) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.text : { *(.text) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.data : { *(.data) }
|
||||||
|
.bss : { *(.bss) }
|
||||||
|
_end = .;
|
||||||
|
}
|
||||||
|
|
11
vendor/riscv-test-env/pm/riscv_test.h
vendored
Normal file
11
vendor/riscv-test-env/pm/riscv_test.h
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#ifndef _ENV_PHYSICAL_MULTI_CORE_H
|
||||||
|
#define _ENV_PHYSICAL_MULTI_CORE_H
|
||||||
|
|
||||||
|
#include "../p/riscv_test.h"
|
||||||
|
|
||||||
|
#undef RISCV_MULTICORE_DISABLE
|
||||||
|
#define RISCV_MULTICORE_DISABLE
|
||||||
|
|
||||||
|
#endif
|
17
vendor/riscv-test-env/pt/link.ld
vendored
Normal file
17
vendor/riscv-test-env/pt/link.ld
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000000;
|
||||||
|
.text.init : { *(.text.init) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.tohost : { *(.tohost) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.text : { *(.text) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.data : { *(.data) }
|
||||||
|
.bss : { *(.bss) }
|
||||||
|
_end = .;
|
||||||
|
}
|
||||||
|
|
69
vendor/riscv-test-env/pt/riscv_test.h
vendored
Normal file
69
vendor/riscv-test-env/pt/riscv_test.h
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#ifndef _ENV_PHYSICAL_SINGLE_CORE_TIMER_H
|
||||||
|
#define _ENV_PHYSICAL_SINGLE_CORE_TIMER_H
|
||||||
|
|
||||||
|
#include "../p/riscv_test.h"
|
||||||
|
|
||||||
|
#define TIMER_INTERVAL 2
|
||||||
|
|
||||||
|
#undef EXTRA_INIT_TIMER
|
||||||
|
#define EXTRA_INIT_TIMER \
|
||||||
|
li a0, MIP_MTIP; \
|
||||||
|
csrs mie, a0; \
|
||||||
|
csrr a0, mtime; \
|
||||||
|
addi a0, a0, TIMER_INTERVAL; \
|
||||||
|
csrw mtimecmp, a0; \
|
||||||
|
|
||||||
|
#if SSTATUS_XS != 0x18000
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
#define XS_SHIFT 15
|
||||||
|
|
||||||
|
#undef INTERRUPT_HANDLER
|
||||||
|
#define INTERRUPT_HANDLER \
|
||||||
|
slli t5, t5, 1; \
|
||||||
|
srli t5, t5, 1; \
|
||||||
|
add t5, t5, -IRQ_M_TIMER; \
|
||||||
|
bnez t5, other_exception; /* other interrups shouldn't happen */\
|
||||||
|
csrr t5, mtime; \
|
||||||
|
addi t5, t5, TIMER_INTERVAL; \
|
||||||
|
csrw mtimecmp, t5; \
|
||||||
|
mret; \
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Data Section Macro
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#undef EXTRA_DATA
|
||||||
|
#define EXTRA_DATA \
|
||||||
|
.align 3; \
|
||||||
|
regspill: \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
.dword 0xdeadbeefcafebabe; \
|
||||||
|
evac: \
|
||||||
|
.skip 32768; \
|
||||||
|
|
||||||
|
#endif
|
162
vendor/riscv-test-env/v/entry.S
vendored
Normal file
162
vendor/riscv-test-env/v/entry.S
vendored
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
#include "riscv_test.h"
|
||||||
|
|
||||||
|
#if __riscv_xlen == 64
|
||||||
|
# define STORE sd
|
||||||
|
# define LOAD ld
|
||||||
|
# define REGBYTES 8
|
||||||
|
#else
|
||||||
|
# define STORE sw
|
||||||
|
# define LOAD lw
|
||||||
|
# define REGBYTES 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STACK_TOP (_end + 4096)
|
||||||
|
|
||||||
|
.section ".text.init","ax",@progbits
|
||||||
|
.globl _start
|
||||||
|
.align 2
|
||||||
|
_start:
|
||||||
|
j handle_reset
|
||||||
|
|
||||||
|
/* NMI vector */
|
||||||
|
.align 2
|
||||||
|
nmi_vector:
|
||||||
|
j wtf
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
trap_vector:
|
||||||
|
j wtf
|
||||||
|
|
||||||
|
handle_reset:
|
||||||
|
li x1, 0
|
||||||
|
li x2, 0
|
||||||
|
li x3, 0
|
||||||
|
li x4, 0
|
||||||
|
li x5, 0
|
||||||
|
li x6, 0
|
||||||
|
li x7, 0
|
||||||
|
li x8, 0
|
||||||
|
li x9, 0
|
||||||
|
li x10, 0
|
||||||
|
li x11, 0
|
||||||
|
li x12, 0
|
||||||
|
li x13, 0
|
||||||
|
li x14, 0
|
||||||
|
li x15, 0
|
||||||
|
li x16, 0
|
||||||
|
li x17, 0
|
||||||
|
li x18, 0
|
||||||
|
li x19, 0
|
||||||
|
li x20, 0
|
||||||
|
li x21, 0
|
||||||
|
li x22, 0
|
||||||
|
li x23, 0
|
||||||
|
li x24, 0
|
||||||
|
li x25, 0
|
||||||
|
li x26, 0
|
||||||
|
li x27, 0
|
||||||
|
li x28, 0
|
||||||
|
li x29, 0
|
||||||
|
li x30, 0
|
||||||
|
li x31, 0
|
||||||
|
|
||||||
|
la t0, trap_vector
|
||||||
|
csrw mtvec, t0
|
||||||
|
la sp, STACK_TOP - SIZEOF_TRAPFRAME_T
|
||||||
|
csrr t0, mhartid
|
||||||
|
slli t0, t0, 12
|
||||||
|
add sp, sp, t0
|
||||||
|
csrw mscratch, sp
|
||||||
|
call extra_boot
|
||||||
|
la a0, userstart
|
||||||
|
j vm_boot
|
||||||
|
|
||||||
|
.globl pop_tf
|
||||||
|
pop_tf:
|
||||||
|
LOAD t0,33*REGBYTES(a0)
|
||||||
|
csrw sepc,t0
|
||||||
|
LOAD x1,1*REGBYTES(a0)
|
||||||
|
LOAD x2,2*REGBYTES(a0)
|
||||||
|
LOAD x3,3*REGBYTES(a0)
|
||||||
|
LOAD x4,4*REGBYTES(a0)
|
||||||
|
LOAD x5,5*REGBYTES(a0)
|
||||||
|
LOAD x6,6*REGBYTES(a0)
|
||||||
|
LOAD x7,7*REGBYTES(a0)
|
||||||
|
LOAD x8,8*REGBYTES(a0)
|
||||||
|
LOAD x9,9*REGBYTES(a0)
|
||||||
|
LOAD x11,11*REGBYTES(a0)
|
||||||
|
LOAD x12,12*REGBYTES(a0)
|
||||||
|
LOAD x13,13*REGBYTES(a0)
|
||||||
|
LOAD x14,14*REGBYTES(a0)
|
||||||
|
LOAD x15,15*REGBYTES(a0)
|
||||||
|
LOAD x16,16*REGBYTES(a0)
|
||||||
|
LOAD x17,17*REGBYTES(a0)
|
||||||
|
LOAD x18,18*REGBYTES(a0)
|
||||||
|
LOAD x19,19*REGBYTES(a0)
|
||||||
|
LOAD x20,20*REGBYTES(a0)
|
||||||
|
LOAD x21,21*REGBYTES(a0)
|
||||||
|
LOAD x22,22*REGBYTES(a0)
|
||||||
|
LOAD x23,23*REGBYTES(a0)
|
||||||
|
LOAD x24,24*REGBYTES(a0)
|
||||||
|
LOAD x25,25*REGBYTES(a0)
|
||||||
|
LOAD x26,26*REGBYTES(a0)
|
||||||
|
LOAD x27,27*REGBYTES(a0)
|
||||||
|
LOAD x28,28*REGBYTES(a0)
|
||||||
|
LOAD x29,29*REGBYTES(a0)
|
||||||
|
LOAD x30,30*REGBYTES(a0)
|
||||||
|
LOAD x31,31*REGBYTES(a0)
|
||||||
|
LOAD a0,10*REGBYTES(a0)
|
||||||
|
sret
|
||||||
|
|
||||||
|
.global trap_entry
|
||||||
|
.align 2
|
||||||
|
trap_entry:
|
||||||
|
csrrw sp, sscratch, sp
|
||||||
|
|
||||||
|
# save gprs
|
||||||
|
STORE x1,1*REGBYTES(sp)
|
||||||
|
STORE x3,3*REGBYTES(sp)
|
||||||
|
STORE x4,4*REGBYTES(sp)
|
||||||
|
STORE x5,5*REGBYTES(sp)
|
||||||
|
STORE x6,6*REGBYTES(sp)
|
||||||
|
STORE x7,7*REGBYTES(sp)
|
||||||
|
STORE x8,8*REGBYTES(sp)
|
||||||
|
STORE x9,9*REGBYTES(sp)
|
||||||
|
STORE x10,10*REGBYTES(sp)
|
||||||
|
STORE x11,11*REGBYTES(sp)
|
||||||
|
STORE x12,12*REGBYTES(sp)
|
||||||
|
STORE x13,13*REGBYTES(sp)
|
||||||
|
STORE x14,14*REGBYTES(sp)
|
||||||
|
STORE x15,15*REGBYTES(sp)
|
||||||
|
STORE x16,16*REGBYTES(sp)
|
||||||
|
STORE x17,17*REGBYTES(sp)
|
||||||
|
STORE x18,18*REGBYTES(sp)
|
||||||
|
STORE x19,19*REGBYTES(sp)
|
||||||
|
STORE x20,20*REGBYTES(sp)
|
||||||
|
STORE x21,21*REGBYTES(sp)
|
||||||
|
STORE x22,22*REGBYTES(sp)
|
||||||
|
STORE x23,23*REGBYTES(sp)
|
||||||
|
STORE x24,24*REGBYTES(sp)
|
||||||
|
STORE x25,25*REGBYTES(sp)
|
||||||
|
STORE x26,26*REGBYTES(sp)
|
||||||
|
STORE x27,27*REGBYTES(sp)
|
||||||
|
STORE x28,28*REGBYTES(sp)
|
||||||
|
STORE x29,29*REGBYTES(sp)
|
||||||
|
STORE x30,30*REGBYTES(sp)
|
||||||
|
STORE x31,31*REGBYTES(sp)
|
||||||
|
|
||||||
|
csrrw t0,sscratch,sp
|
||||||
|
STORE t0,2*REGBYTES(sp)
|
||||||
|
|
||||||
|
# get sr, epc, badvaddr, cause
|
||||||
|
csrr t0,sstatus
|
||||||
|
STORE t0,32*REGBYTES(sp)
|
||||||
|
csrr t0,sepc
|
||||||
|
STORE t0,33*REGBYTES(sp)
|
||||||
|
csrr t0,stval
|
||||||
|
STORE t0,34*REGBYTES(sp)
|
||||||
|
csrr t0,scause
|
||||||
|
STORE t0,35*REGBYTES(sp)
|
||||||
|
|
||||||
|
move a0, sp
|
||||||
|
j handle_trap
|
17
vendor/riscv-test-env/v/link.ld
vendored
Normal file
17
vendor/riscv-test-env/v/link.ld
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000000;
|
||||||
|
.text.init : { *(.text.init) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.tohost : { *(.tohost) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.text : { *(.text) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.data : { *(.data) }
|
||||||
|
.bss : { *(.bss) }
|
||||||
|
_end = .;
|
||||||
|
}
|
||||||
|
|
80
vendor/riscv-test-env/v/riscv_test.h
vendored
Normal file
80
vendor/riscv-test-env/v/riscv_test.h
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#ifndef _ENV_VIRTUAL_SINGLE_CORE_H
|
||||||
|
#define _ENV_VIRTUAL_SINGLE_CORE_H
|
||||||
|
|
||||||
|
#include "../p/riscv_test.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Begin Macro
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#undef RVTEST_FP_ENABLE
|
||||||
|
#define RVTEST_FP_ENABLE fssr x0
|
||||||
|
|
||||||
|
#undef RVTEST_VECTOR_ENABLE
|
||||||
|
#define RVTEST_VECTOR_ENABLE \
|
||||||
|
csrwi fcsr, 0; \
|
||||||
|
csrwi vcsr, 0;
|
||||||
|
|
||||||
|
#undef RVTEST_CODE_BEGIN
|
||||||
|
#define RVTEST_CODE_BEGIN \
|
||||||
|
.text; \
|
||||||
|
.global extra_boot; \
|
||||||
|
extra_boot: \
|
||||||
|
EXTRA_INIT \
|
||||||
|
ret; \
|
||||||
|
.global userstart; \
|
||||||
|
userstart: \
|
||||||
|
init
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Pass/Fail Macro
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#undef RVTEST_PASS
|
||||||
|
#define RVTEST_PASS li a0, 1; scall
|
||||||
|
|
||||||
|
#undef RVTEST_FAIL
|
||||||
|
#define RVTEST_FAIL sll a0, TESTNUM, 1; 1:beqz a0, 1b; or a0, a0, 1; scall;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Data Section Macro
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#undef RVTEST_DATA_END
|
||||||
|
#define RVTEST_DATA_END
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Supervisor mode definitions and macros
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define MAX_TEST_PAGES 63 // this must be the period of the LFSR below
|
||||||
|
#define LFSR_NEXT(x) (((((x)^((x)>>1)) & 1) << 5) | ((x) >> 1))
|
||||||
|
|
||||||
|
#define PGSHIFT 12
|
||||||
|
#define PGSIZE (1UL << PGSHIFT)
|
||||||
|
|
||||||
|
#define SIZEOF_TRAPFRAME_T ((__riscv_xlen / 8) * 36)
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
typedef unsigned long pte_t;
|
||||||
|
#define LEVELS (sizeof(pte_t) == sizeof(uint64_t) ? 3 : 2)
|
||||||
|
#define PTIDXBITS (PGSHIFT - (sizeof(pte_t) == 8 ? 3 : 2))
|
||||||
|
#define VPN_BITS (PTIDXBITS * LEVELS)
|
||||||
|
#define VA_BITS (VPN_BITS + PGSHIFT)
|
||||||
|
#define PTES_PER_PT (1UL << RISCV_PGLEVEL_BITS)
|
||||||
|
#define MEGAPAGE_SIZE (PTES_PER_PT * PGSIZE)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
long gpr[32];
|
||||||
|
long sr;
|
||||||
|
long epc;
|
||||||
|
long badvaddr;
|
||||||
|
long cause;
|
||||||
|
} trapframe_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
114
vendor/riscv-test-env/v/string.c
vendored
Normal file
114
vendor/riscv-test-env/v/string.c
vendored
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
void* memcpy(void* dest, const void* src, size_t len)
|
||||||
|
{
|
||||||
|
if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) {
|
||||||
|
const uintptr_t* s = src;
|
||||||
|
uintptr_t *d = dest;
|
||||||
|
while (d < (uintptr_t*)(dest + len))
|
||||||
|
*d++ = *s++;
|
||||||
|
} else {
|
||||||
|
const char* s = src;
|
||||||
|
char *d = dest;
|
||||||
|
while (d < (char*)(dest + len))
|
||||||
|
*d++ = *s++;
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memset(void* dest, int byte, size_t len)
|
||||||
|
{
|
||||||
|
if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) {
|
||||||
|
uintptr_t word = byte & 0xFF;
|
||||||
|
word |= word << 8;
|
||||||
|
word |= word << 16;
|
||||||
|
word |= word << 16 << 16;
|
||||||
|
|
||||||
|
uintptr_t *d = dest;
|
||||||
|
while (d < (uintptr_t*)(dest + len))
|
||||||
|
*d++ = word;
|
||||||
|
} else {
|
||||||
|
char *d = dest;
|
||||||
|
while (d < (char*)(dest + len))
|
||||||
|
*d++ = byte;
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t strlen(const char *s)
|
||||||
|
{
|
||||||
|
const char *p = s;
|
||||||
|
while (*p)
|
||||||
|
p++;
|
||||||
|
return p - s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strcmp(const char* s1, const char* s2)
|
||||||
|
{
|
||||||
|
unsigned char c1, c2;
|
||||||
|
|
||||||
|
do {
|
||||||
|
c1 = *s1++;
|
||||||
|
c2 = *s2++;
|
||||||
|
} while (c1 != 0 && c1 == c2);
|
||||||
|
|
||||||
|
return c1 - c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memcmp(const void* s1, const void* s2, size_t n)
|
||||||
|
{
|
||||||
|
if ((((uintptr_t)s1 | (uintptr_t)s2) & (sizeof(uintptr_t)-1)) == 0) {
|
||||||
|
const uintptr_t* u1 = s1;
|
||||||
|
const uintptr_t* u2 = s2;
|
||||||
|
const uintptr_t* end = u1 + (n / sizeof(uintptr_t));
|
||||||
|
while (u1 < end) {
|
||||||
|
if (*u1 != *u2)
|
||||||
|
break;
|
||||||
|
u1++;
|
||||||
|
u2++;
|
||||||
|
}
|
||||||
|
n -= (const void*)u1 - s1;
|
||||||
|
s1 = u1;
|
||||||
|
s2 = u2;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (n--) {
|
||||||
|
unsigned char c1 = *(const unsigned char*)s1++;
|
||||||
|
unsigned char c2 = *(const unsigned char*)s2++;
|
||||||
|
if (c1 != c2)
|
||||||
|
return c1 - c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* strcpy(char* dest, const char* src)
|
||||||
|
{
|
||||||
|
char* d = dest;
|
||||||
|
while ((*d++ = *src++))
|
||||||
|
;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
long atol(const char* str)
|
||||||
|
{
|
||||||
|
long res = 0;
|
||||||
|
int sign = 0;
|
||||||
|
|
||||||
|
while (*str == ' ')
|
||||||
|
str++;
|
||||||
|
|
||||||
|
if (*str == '-' || *str == '+') {
|
||||||
|
sign = *str == '-';
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*str) {
|
||||||
|
res *= 10;
|
||||||
|
res += *str++ - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return sign ? -res : res;
|
||||||
|
}
|
300
vendor/riscv-test-env/v/vm.c
vendored
Normal file
300
vendor/riscv-test-env/v/vm.c
vendored
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "riscv_test.h"
|
||||||
|
|
||||||
|
#if __riscv_xlen == 32
|
||||||
|
# define SATP_MODE_CHOICE SATP_MODE_SV32
|
||||||
|
#elif defined(Sv48)
|
||||||
|
# define SATP_MODE_CHOICE SATP_MODE_SV48
|
||||||
|
#else
|
||||||
|
# define SATP_MODE_CHOICE SATP_MODE_SV39
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void trap_entry();
|
||||||
|
void pop_tf(trapframe_t*);
|
||||||
|
|
||||||
|
extern volatile uint64_t tohost;
|
||||||
|
extern volatile uint64_t fromhost;
|
||||||
|
|
||||||
|
static void do_tohost(uint64_t tohost_value)
|
||||||
|
{
|
||||||
|
while (tohost)
|
||||||
|
fromhost = 0;
|
||||||
|
tohost = tohost_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define pa2kva(pa) ((void*)(pa) - DRAM_BASE - MEGAPAGE_SIZE)
|
||||||
|
#define uva2kva(pa) ((void*)(pa) - MEGAPAGE_SIZE)
|
||||||
|
|
||||||
|
#define flush_page(addr) asm volatile ("sfence.vma %0" : : "r" (addr) : "memory")
|
||||||
|
|
||||||
|
static uint64_t lfsr63(uint64_t x)
|
||||||
|
{
|
||||||
|
uint64_t bit = (x ^ (x >> 1)) & 1;
|
||||||
|
return (x >> 1) | (bit << 62);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cputchar(int x)
|
||||||
|
{
|
||||||
|
do_tohost(0x0101000000000000 | (unsigned char)x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cputstring(const char* s)
|
||||||
|
{
|
||||||
|
while (*s)
|
||||||
|
cputchar(*s++);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void terminate(int code)
|
||||||
|
{
|
||||||
|
do_tohost(code);
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wtf()
|
||||||
|
{
|
||||||
|
terminate(841);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define stringify1(x) #x
|
||||||
|
#define stringify(x) stringify1(x)
|
||||||
|
#define assert(x) do { \
|
||||||
|
if (x) break; \
|
||||||
|
cputstring("Assertion failed: " stringify(x) "\n"); \
|
||||||
|
terminate(3); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define l1pt pt[0]
|
||||||
|
#define user_l2pt pt[1]
|
||||||
|
#if SATP_MODE_CHOICE == SATP_MODE_SV48
|
||||||
|
# define NPT 6
|
||||||
|
# define kernel_l2pt pt[2]
|
||||||
|
# define kernel_l3pt pt[3]
|
||||||
|
# define user_l3pt pt[4]
|
||||||
|
# define user_llpt pt[5]
|
||||||
|
#elif SATP_MODE_CHOICE == SATP_MODE_SV39
|
||||||
|
# define NPT 4
|
||||||
|
# define kernel_l2pt pt[2]
|
||||||
|
# define user_llpt pt[3]
|
||||||
|
#elif SATP_MODE_CHOICE == SATP_MODE_SV32
|
||||||
|
# define NPT 2
|
||||||
|
# define user_llpt user_l2pt
|
||||||
|
#else
|
||||||
|
# error Unknown SATP_MODE_CHOICE
|
||||||
|
#endif
|
||||||
|
pte_t pt[NPT][PTES_PER_PT] __attribute__((aligned(PGSIZE)));
|
||||||
|
|
||||||
|
typedef struct { pte_t addr; void* next; } freelist_t;
|
||||||
|
|
||||||
|
freelist_t user_mapping[MAX_TEST_PAGES];
|
||||||
|
freelist_t freelist_nodes[MAX_TEST_PAGES];
|
||||||
|
freelist_t *freelist_head, *freelist_tail;
|
||||||
|
|
||||||
|
void printhex(uint64_t x)
|
||||||
|
{
|
||||||
|
char str[17];
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10);
|
||||||
|
x >>= 4;
|
||||||
|
}
|
||||||
|
str[16] = 0;
|
||||||
|
|
||||||
|
cputstring(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void evict(unsigned long addr)
|
||||||
|
{
|
||||||
|
assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
|
||||||
|
addr = addr/PGSIZE*PGSIZE;
|
||||||
|
|
||||||
|
freelist_t* node = &user_mapping[addr/PGSIZE];
|
||||||
|
if (node->addr)
|
||||||
|
{
|
||||||
|
// check accessed and dirty bits
|
||||||
|
assert(user_llpt[addr/PGSIZE] & PTE_A);
|
||||||
|
uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
|
||||||
|
if (memcmp((void*)addr, uva2kva(addr), PGSIZE)) {
|
||||||
|
assert(user_llpt[addr/PGSIZE] & PTE_D);
|
||||||
|
memcpy(uva2kva(addr), (void*)addr, PGSIZE);
|
||||||
|
}
|
||||||
|
write_csr(sstatus, sstatus);
|
||||||
|
|
||||||
|
user_mapping[addr/PGSIZE].addr = 0;
|
||||||
|
|
||||||
|
if (freelist_tail == 0)
|
||||||
|
freelist_head = freelist_tail = node;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
freelist_tail->next = node;
|
||||||
|
freelist_tail = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_fault(uintptr_t addr, uintptr_t cause)
|
||||||
|
{
|
||||||
|
assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
|
||||||
|
addr = addr/PGSIZE*PGSIZE;
|
||||||
|
|
||||||
|
if (user_llpt[addr/PGSIZE]) {
|
||||||
|
if (!(user_llpt[addr/PGSIZE] & PTE_A)) {
|
||||||
|
user_llpt[addr/PGSIZE] |= PTE_A;
|
||||||
|
} else {
|
||||||
|
assert(!(user_llpt[addr/PGSIZE] & PTE_D) && cause == CAUSE_STORE_PAGE_FAULT);
|
||||||
|
user_llpt[addr/PGSIZE] |= PTE_D;
|
||||||
|
}
|
||||||
|
flush_page(addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
freelist_t* node = freelist_head;
|
||||||
|
assert(node);
|
||||||
|
freelist_head = node->next;
|
||||||
|
if (freelist_head == freelist_tail)
|
||||||
|
freelist_tail = 0;
|
||||||
|
|
||||||
|
uintptr_t new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X;
|
||||||
|
user_llpt[addr/PGSIZE] = new_pte | PTE_A | PTE_D;
|
||||||
|
flush_page(addr);
|
||||||
|
|
||||||
|
assert(user_mapping[addr/PGSIZE].addr == 0);
|
||||||
|
user_mapping[addr/PGSIZE] = *node;
|
||||||
|
|
||||||
|
uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
|
||||||
|
memcpy((void*)addr, uva2kva(addr), PGSIZE);
|
||||||
|
write_csr(sstatus, sstatus);
|
||||||
|
|
||||||
|
user_llpt[addr/PGSIZE] = new_pte;
|
||||||
|
flush_page(addr);
|
||||||
|
|
||||||
|
asm volatile ("fence.i");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_trap(trapframe_t* tf)
|
||||||
|
{
|
||||||
|
if (tf->cause == CAUSE_USER_ECALL)
|
||||||
|
{
|
||||||
|
int n = tf->gpr[10];
|
||||||
|
|
||||||
|
for (long i = 1; i < MAX_TEST_PAGES; i++)
|
||||||
|
evict(i*PGSIZE);
|
||||||
|
|
||||||
|
terminate(n);
|
||||||
|
}
|
||||||
|
else if (tf->cause == CAUSE_ILLEGAL_INSTRUCTION)
|
||||||
|
{
|
||||||
|
assert(tf->epc % 4 == 0);
|
||||||
|
|
||||||
|
int* fssr;
|
||||||
|
asm ("jal %0, 1f; fssr x0; 1:" : "=r"(fssr));
|
||||||
|
|
||||||
|
if (*(int*)tf->epc == *fssr)
|
||||||
|
terminate(1); // FP test on non-FP hardware. "succeed."
|
||||||
|
else
|
||||||
|
assert(!"illegal instruction");
|
||||||
|
tf->epc += 4;
|
||||||
|
}
|
||||||
|
else if (tf->cause == CAUSE_FETCH_PAGE_FAULT || tf->cause == CAUSE_LOAD_PAGE_FAULT || tf->cause == CAUSE_STORE_PAGE_FAULT)
|
||||||
|
handle_fault(tf->badvaddr, tf->cause);
|
||||||
|
else
|
||||||
|
assert(!"unexpected exception");
|
||||||
|
|
||||||
|
pop_tf(tf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void coherence_torture()
|
||||||
|
{
|
||||||
|
// cause coherence misses without affecting program semantics
|
||||||
|
uint64_t random = ENTROPY;
|
||||||
|
while (1) {
|
||||||
|
uintptr_t paddr = DRAM_BASE + ((random % (2 * (MAX_TEST_PAGES + 1) * PGSIZE)) & -4);
|
||||||
|
#ifdef __riscv_atomic
|
||||||
|
if (random & 1) // perform a no-op write
|
||||||
|
asm volatile ("amoadd.w zero, zero, (%0)" :: "r"(paddr));
|
||||||
|
else // perform a read
|
||||||
|
#endif
|
||||||
|
asm volatile ("lw zero, (%0)" :: "r"(paddr));
|
||||||
|
random = lfsr63(random);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vm_boot(uintptr_t test_addr)
|
||||||
|
{
|
||||||
|
uint64_t random = ENTROPY;
|
||||||
|
if (read_csr(mhartid) > 0)
|
||||||
|
coherence_torture();
|
||||||
|
|
||||||
|
_Static_assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t), "???");
|
||||||
|
|
||||||
|
#if (MAX_TEST_PAGES > PTES_PER_PT) || (DRAM_BASE % MEGAPAGE_SIZE) != 0
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
// map user to lowermost megapage
|
||||||
|
l1pt[0] = ((pte_t)user_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
|
||||||
|
// map kernel to uppermost megapage
|
||||||
|
#if SATP_MODE_CHOICE == SATP_MODE_SV48
|
||||||
|
l1pt[PTES_PER_PT-1] = ((pte_t)kernel_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
|
||||||
|
kernel_l2pt[PTES_PER_PT-1] = ((pte_t)kernel_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
|
||||||
|
kernel_l3pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
|
||||||
|
user_l2pt[0] = ((pte_t)user_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
|
||||||
|
user_l3pt[0] = ((pte_t)user_llpt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
|
||||||
|
#elif SATP_MODE_CHOICE == SATP_MODE_SV39
|
||||||
|
l1pt[PTES_PER_PT-1] = ((pte_t)kernel_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
|
||||||
|
kernel_l2pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
|
||||||
|
user_l2pt[0] = ((pte_t)user_llpt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
|
||||||
|
#elif SATP_MODE_CHOICE == SATP_MODE_SV32
|
||||||
|
l1pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
|
||||||
|
#else
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
uintptr_t vm_choice = SATP_MODE_CHOICE;
|
||||||
|
uintptr_t satp_value = ((uintptr_t)l1pt >> PGSHIFT)
|
||||||
|
| (vm_choice * (SATP_MODE & ~(SATP_MODE<<1)));
|
||||||
|
write_csr(satp, satp_value);
|
||||||
|
if (read_csr(satp) != satp_value)
|
||||||
|
assert(!"unsupported satp mode");
|
||||||
|
|
||||||
|
// Set up PMPs if present, ignoring illegal instruction trap if not.
|
||||||
|
uintptr_t pmpc = PMP_NAPOT | PMP_R | PMP_W | PMP_X;
|
||||||
|
uintptr_t pmpa = ((uintptr_t)1 << (__riscv_xlen == 32 ? 31 : 53)) - 1;
|
||||||
|
asm volatile ("la t0, 1f\n\t"
|
||||||
|
"csrrw t0, mtvec, t0\n\t"
|
||||||
|
"csrw pmpaddr0, %1\n\t"
|
||||||
|
"csrw pmpcfg0, %0\n\t"
|
||||||
|
".align 2\n\t"
|
||||||
|
"1: csrw mtvec, t0"
|
||||||
|
: : "r" (pmpc), "r" (pmpa) : "t0");
|
||||||
|
|
||||||
|
// set up supervisor trap handling
|
||||||
|
write_csr(stvec, pa2kva(trap_entry));
|
||||||
|
write_csr(sscratch, pa2kva(read_csr(mscratch)));
|
||||||
|
write_csr(medeleg,
|
||||||
|
(1 << CAUSE_USER_ECALL) |
|
||||||
|
(1 << CAUSE_FETCH_PAGE_FAULT) |
|
||||||
|
(1 << CAUSE_LOAD_PAGE_FAULT) |
|
||||||
|
(1 << CAUSE_STORE_PAGE_FAULT));
|
||||||
|
// FPU on; accelerator on; vector unit on
|
||||||
|
write_csr(mstatus, MSTATUS_FS | MSTATUS_XS | MSTATUS_VS);
|
||||||
|
write_csr(mie, 0);
|
||||||
|
|
||||||
|
random = 1 + (random % MAX_TEST_PAGES);
|
||||||
|
freelist_head = pa2kva((void*)&freelist_nodes[0]);
|
||||||
|
freelist_tail = pa2kva(&freelist_nodes[MAX_TEST_PAGES-1]);
|
||||||
|
for (long i = 0; i < MAX_TEST_PAGES; i++)
|
||||||
|
{
|
||||||
|
freelist_nodes[i].addr = DRAM_BASE + (MAX_TEST_PAGES + random)*PGSIZE;
|
||||||
|
freelist_nodes[i].next = pa2kva(&freelist_nodes[i+1]);
|
||||||
|
random = LFSR_NEXT(random);
|
||||||
|
}
|
||||||
|
freelist_nodes[MAX_TEST_PAGES-1].next = 0;
|
||||||
|
|
||||||
|
trapframe_t tf;
|
||||||
|
memset(&tf, 0, sizeof(tf));
|
||||||
|
tf.epc = test_addr - DRAM_BASE;
|
||||||
|
pop_tf(&tf);
|
||||||
|
}
|
15
vendor/riscv_test_env.lock.hjson
vendored
Normal file
15
vendor/riscv_test_env.lock.hjson
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright lowRISC contributors.
|
||||||
|
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
// This file is generated by the util/vendor script. Please do not modify it
|
||||||
|
// manually.
|
||||||
|
|
||||||
|
{
|
||||||
|
upstream:
|
||||||
|
{
|
||||||
|
url: https://github.com/riscv/riscv-test-env
|
||||||
|
rev: 34a1175291f9531e85afdb89aaa77707f45fc8e4
|
||||||
|
}
|
||||||
|
patch_dir: "patches/riscv_test_env"
|
||||||
|
}
|
12
vendor/riscv_test_env.vendor.hjson
vendored
Normal file
12
vendor/riscv_test_env.vendor.hjson
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright lowRISC contributors.
|
||||||
|
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
{
|
||||||
|
name: "riscv-test-env",
|
||||||
|
target_dir: "riscv-test-env",
|
||||||
|
|
||||||
|
upstream: {
|
||||||
|
url: "https://github.com/riscv/riscv-test-env",
|
||||||
|
rev: "master",
|
||||||
|
},
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue