diff options
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | benchmarks/Makefile | 9 | ||||
-rw-r--r-- | benchmarks/rsort/rsort.c | 4 | ||||
-rwxr-xr-x | debug/gdbserver.py | 95 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike-1.cfg | 2 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike-2-hwthread.cfg | 2 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike-2.cfg | 2 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike-multi.cfg | 4 | ||||
-rwxr-xr-x | debug/targets/RISC-V/spike32.lds | 9 | ||||
-rwxr-xr-x | debug/targets/RISC-V/spike64.lds | 9 | ||||
-rw-r--r-- | debug/testlib.py | 17 | ||||
-rw-r--r-- | isa/rv64mi/illegal.S | 12 | ||||
-rw-r--r-- | isa/rv64mi/ma_addr.S | 2 | ||||
-rw-r--r-- | isa/rv64si/dirty.S | 2 | ||||
-rw-r--r-- | isa/rv64si/icache-alias.S | 2 | ||||
-rw-r--r-- | isa/rv64si/ma_fetch.S | 6 |
16 files changed, 119 insertions, 61 deletions
@@ -10,7 +10,8 @@ Building from repository ----------------------------- We assume that the RISCV environment variable is set to the RISC-V tools -install path, and that the riscv-gnu-toolchain package is installed. +install path, and that the [riscv-gnu-toolchain]( +https://github.com/riscv-collab/riscv-gnu-toolchain) package is installed. $ git clone https://github.com/riscv/riscv-tests $ cd riscv-tests diff --git a/benchmarks/Makefile b/benchmarks/Makefile index fde4f23..d38f8af 100644 --- a/benchmarks/Makefile +++ b/benchmarks/Makefile @@ -6,6 +6,13 @@ XLEN ?= 64 +ifeq ($(XLEN),32) +ABI ?= ilp32d +endif +ifeq ($(XLEN),64) +ABI ?= lp64d +endif + default: all src_dir = . @@ -43,7 +50,7 @@ bmarks = \ RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf- RISCV_GCC ?= $(RISCV_PREFIX)gcc -RISCV_GCC_OPTS ?= -DPREALLOCATE=1 -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf -fno-tree-loop-distribute-patterns -march=rv$(XLEN)gcv -mabi=lp64d +RISCV_GCC_OPTS ?= -DPREALLOCATE=1 -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf -fno-tree-loop-distribute-patterns -march=rv$(XLEN)gcv -mabi=$(ABI) RISCV_LINK ?= $(RISCV_GCC) -T $(src_dir)/common/test.ld $(incs) RISCV_LINK_OPTS ?= -static -nostdlib -nostartfiles -lm -lgcc -T $(src_dir)/common/test.ld RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data diff --git a/benchmarks/rsort/rsort.c b/benchmarks/rsort/rsort.c index 7ffc12a..c2788ca 100644 --- a/benchmarks/rsort/rsort.c +++ b/benchmarks/rsort/rsort.c @@ -1,10 +1,10 @@ // See LICENSE for license details. //************************************************************************** -// Quicksort benchmark +// Radix Sort benchmark //-------------------------------------------------------------------------- // -// This benchmark uses quicksort to sort an array of integers. The +// This benchmark uses radix sort to sort an array of integers. The // implementation is largely adapted from Numerical Recipes for C. The // input data (and reference data) should be generated using the // qsort_gendata.pl perl script and dumped to a file named diff --git a/debug/gdbserver.py b/debug/gdbserver.py index ba30b9b..2fd14a8 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -11,7 +11,6 @@ import os import re import itertools -from datetime import datetime import targets import testlib from testlib import assertEqual, assertNotEqual @@ -677,6 +676,47 @@ class HwbpManual(DebugTest): return self.target.support_manual_hwbp and \ self.hart.instruction_hardware_breakpoint_count >= 1 + # TODO: This can be removed once + # https://github.com/riscv-collab/riscv-openocd/pull/1111 + # is merged. + def check_reserve_trigger_support(self): + not_supp_msg = "RESERVE_TRIGGER_NOT_SUPPORTED" + if not_supp_msg in self.gdb.command( + "monitor if [catch {riscv reserve_trigger 0 on} e] {echo " + + not_supp_msg + "}").splitlines(): + raise TestNotApplicable + + def set_manual_trigger(self, tdata1, tdata2): + for tselect in itertools.count(0): + self.gdb.p(f"$tselect={tselect}") + if self.gdb.p("$tselect") != tselect: + raise TestNotApplicable + + self.gdb.command( + f"monitor riscv reserve_trigger {tselect} on") + + # Need to disable the trigger before writing tdata2 + self.gdb.p("$tdata1=0") + # Need to write a valid value to tdata2 before writing tdata1 + self.gdb.p(f"$tdata2=0x{tdata2:x}") + self.gdb.p(f"$tdata1=0x{tdata1:x}") + + tdata2_rb = self.gdb.p("$tdata2") + tdata1_rb = self.gdb.p("$tdata1") + if tdata1_rb == tdata1 and tdata2_rb == tdata2: + return tselect + + type_rb = tdata1_rb & MCONTROL_TYPE(self.hart.xlen) + type_none = set_field(0, MCONTROL_TYPE(self.hart.xlen), + MCONTROL_TYPE_NONE) + if type_rb == type_none: + raise TestNotApplicable + + self.gdb.p("$tdata1=0") + self.gdb.command( + f"monitor riscv reserve_trigger {tselect} off") + assert False + def test(self): if not self.hart.honors_tdata1_hmode: # Run to main before setting the breakpoint, because startup code @@ -685,6 +725,12 @@ class HwbpManual(DebugTest): self.gdb.c() self.gdb.command("delete") + + # TODO: This can be removed once + # https://github.com/riscv-collab/riscv-openocd/pull/1111 + # is merged. + self.check_reserve_trigger_support() + #self.gdb.hbreak("rot13") tdata1 = MCONTROL_DMODE(self.hart.xlen) tdata1 = set_field(tdata1, MCONTROL_TYPE(self.hart.xlen), @@ -693,24 +739,9 @@ class HwbpManual(DebugTest): tdata1 = set_field(tdata1, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL) tdata1 |= MCONTROL_M | MCONTROL_S | MCONTROL_U | MCONTROL_EXECUTE - tselect = 0 - while True: - self.gdb.p(f"$tselect={tselect}") - value = self.gdb.p("$tselect") - if value != tselect: - raise TestNotApplicable - # Need to disable the trigger before writing tdata2 - self.gdb.p("$tdata1=0") - # Need to write a valid value to tdata2 before writing tdata1 - self.gdb.p("$tdata2=&rot13") - self.gdb.p(f"$tdata1=0x{tdata1:x}") - value = self.gdb.p("$tdata1") - if value == tdata1: - break - if value & MCONTROL_TYPE(self.hart.xlen) == MCONTROL_TYPE_NONE: - raise TestNotApplicable - self.gdb.p("$tdata1=0") - tselect += 1 + tdata2 = self.gdb.p("&rot13") + + tselect = self.set_manual_trigger(tdata1, tdata2) # The breakpoint should be hit exactly 2 times. for _ in range(2): @@ -727,14 +758,22 @@ class HwbpManual(DebugTest): self.gdb.c() before = self.gdb.p("$pc") assertEqual(before, self.gdb.p("&crc32a")) + self.gdb.stepi() - after = self.gdb.p("$pc") - assertNotEqual(before, after) + assertEqual(before, self.gdb.p("$pc"), + "OpenOCD shouldn't disable a reserved trigger.") # Remove the manual HW breakpoint. assertEqual(tselect, self.gdb.p("$tselect")) self.gdb.p("$tdata1=0") + self.gdb.stepi() + assertNotEqual(before, self.gdb.p("$pc"), + "OpenOCD should be able to step from a removed BP.") + + self.gdb.command( + f"monitor riscv reserve_trigger {tselect} off") + self.gdb.b("_exit") self.exit() @@ -2126,8 +2165,10 @@ class EtriggerTest(DebugTest): def test(self): # Set trigger on Load access fault self.gdb.command("monitor riscv etrigger set m 0x20") - # Set fox to a null pointer so we'll get a load access exception later. - self.gdb.p("fox=(char*)0") + # Set fox to a bad pointer so we'll get a load access exception later. + # Use NULL if a known-bad address is not provided. + bad_address = self.hart.bad_address or 0 + self.gdb.p(f"fox=(char*)0x{bad_address:08x}") output = self.gdb.c() # We should not be at handle_trap assertNotIn("handle_trap", output) @@ -2213,14 +2254,6 @@ def main(): module = sys.modules[__name__] - # initialize PRNG - selected_seed = parsed.seed - if parsed.seed is None: - selected_seed = int(datetime.now().timestamp()) - print(f"PRNG seed for {target.name} is generated automatically") - print(f"PRNG seed for {target.name} is {selected_seed}") - random.seed(selected_seed) - return testlib.run_all_tests(module, target, parsed) # TROUBLESHOOTING TIPS diff --git a/debug/targets/RISC-V/spike-1.cfg b/debug/targets/RISC-V/spike-1.cfg index c6c7d2d..3fdae97 100644 --- a/debug/targets/RISC-V/spike-1.cfg +++ b/debug/targets/RISC-V/spike-1.cfg @@ -5,7 +5,7 @@ remote_bitbang host $::env(REMOTE_BITBANG_HOST) remote_bitbang port $::env(REMOTE_BITBANG_PORT) set _CHIPNAME riscv -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0xdeadbeef set _TARGETNAME $_CHIPNAME.cpu if {$::env(USE_FREERTOS)} { diff --git a/debug/targets/RISC-V/spike-2-hwthread.cfg b/debug/targets/RISC-V/spike-2-hwthread.cfg index c10ad8f..5a08ece 100644 --- a/debug/targets/RISC-V/spike-2-hwthread.cfg +++ b/debug/targets/RISC-V/spike-2-hwthread.cfg @@ -6,7 +6,7 @@ remote_bitbang host $::env(REMOTE_BITBANG_HOST) remote_bitbang port $::env(REMOTE_BITBANG_PORT) set _CHIPNAME riscv -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0xdeadbeef set _TARGETNAME_0 $_CHIPNAME.cpu0 set _TARGETNAME_1 $_CHIPNAME.cpu1 diff --git a/debug/targets/RISC-V/spike-2.cfg b/debug/targets/RISC-V/spike-2.cfg index ebf3c5a..2de4256 100644 --- a/debug/targets/RISC-V/spike-2.cfg +++ b/debug/targets/RISC-V/spike-2.cfg @@ -6,7 +6,7 @@ remote_bitbang host $::env(REMOTE_BITBANG_HOST) remote_bitbang port $::env(REMOTE_BITBANG_PORT) set _CHIPNAME riscv -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0xdeadbeef set _TARGETNAME_0 $_CHIPNAME.cpu0 set _TARGETNAME_1 $_CHIPNAME.cpu1 diff --git a/debug/targets/RISC-V/spike-multi.cfg b/debug/targets/RISC-V/spike-multi.cfg index 36d4328..dff325e 100644 --- a/debug/targets/RISC-V/spike-multi.cfg +++ b/debug/targets/RISC-V/spike-multi.cfg @@ -5,8 +5,8 @@ adapter driver remote_bitbang remote_bitbang host $::env(REMOTE_BITBANG_HOST) remote_bitbang port $::env(REMOTE_BITBANG_PORT) -jtag newtap riscv.0 cpu -irlen 5 -expected-id 0x10e31913 -jtag newtap riscv.1 cpu -irlen 5 -expected-id 0x10e31913 +jtag newtap riscv.0 cpu -irlen 5 -expected-id 0xdeadbeef +jtag newtap riscv.1 cpu -irlen 5 -expected-id 0xdeadbeef target create riscv.0.cpu0 riscv -chain-position riscv.0.cpu -coreid 0 target create riscv.0.cpu1 riscv -chain-position riscv.0.cpu -coreid 1 diff --git a/debug/targets/RISC-V/spike32.lds b/debug/targets/RISC-V/spike32.lds index 77bb1ba..1e3f34f 100755 --- a/debug/targets/RISC-V/spike32.lds +++ b/debug/targets/RISC-V/spike32.lds @@ -5,14 +5,17 @@ SECTIONS /* Leave some space for pk's data structures, which includes tohost/fromhost * which are special addresses we ought to leave alone. */ . = 0x10110000; - .text : + .text : { *(.text.entry) *(.text) + *(.text.*) } /* data segment */ - .data : { *(.data) } + .rodata : { *(.rodata .rodata.*) } + + .data : { *(.data .data.*) } .sdata : { __global_pointer$ = . + 0x800; @@ -27,7 +30,7 @@ SECTIONS *(.sbss .sbss.* .gnu.linkonce.sb.*) *(.scommon) } - .bss : { *(.bss) } + .bss : { *(.bss .bss.*) } __bss_end = .; __malloc_start = .; diff --git a/debug/targets/RISC-V/spike64.lds b/debug/targets/RISC-V/spike64.lds index 2e7d65d..9cbf36f 100755 --- a/debug/targets/RISC-V/spike64.lds +++ b/debug/targets/RISC-V/spike64.lds @@ -3,14 +3,17 @@ OUTPUT_ARCH( "riscv" ) SECTIONS { . = 0x1212340000; - .text : + .text : { *(.text.entry) *(.text) + *(.text.*) } /* data segment */ - .data : { *(.data) } + .rodata : { *(.rodata .rodata.*) } + + .data : { *(.data .data.*) } .sdata : { __global_pointer$ = . + 0x800; @@ -25,7 +28,7 @@ SECTIONS *(.sbss .sbss.* .gnu.linkonce.sb.*) *(.scommon) } - .bss : { *(.bss) } + .bss : { *(.bss .bss.*) } __bss_end = .; __malloc_start = .; diff --git a/debug/testlib.py b/debug/testlib.py index 1f107be..0279b08 100644 --- a/debug/testlib.py +++ b/debug/testlib.py @@ -1,6 +1,7 @@ import collections import os import os.path +import random import re import shlex import subprocess @@ -9,6 +10,8 @@ import tempfile import time import traceback +from datetime import datetime + import tty import pexpect import yaml @@ -134,6 +137,9 @@ class Spike: else: isa = f"RV{self.harts[0].xlen}G" + if 'V' in isa[2:]: + isa += f"_Zvl{self.vlen}b_Zve{self.elen}d" + cmd += ["--isa", isa] cmd += ["--dm-auth"] @@ -159,8 +165,6 @@ class Spike: if not self.support_haltgroups: cmd.append("--dm-no-halt-groups") - if 'V' in isa[2:]: - cmd.append(f"--varch=vlen:{self.vlen},elen:{self.elen}") assert len(set(t.ram for t in self.harts)) == 1, \ "All spike harts must have the same RAM layout" @@ -1160,6 +1164,14 @@ def run_all_tests(module, target, parsed): excluded_tests = load_excluded_tests(parsed.exclude_tests, target.name) target.skip_tests += excluded_tests + # initialize PRNG + selected_seed = parsed.seed + if parsed.seed is None: + selected_seed = int(datetime.now().timestamp()) + print(f"PRNG seed for {target.name} is generated automatically") + print(f"PRNG seed for {target.name} is {selected_seed}") + random.seed(selected_seed) + results, count = run_tests(parsed, target, todo) header(f"ran {count} tests in {time.time() - overall_start:.0f}s", dash=':') @@ -1292,7 +1304,6 @@ class BaseTest: if not hart is None: self.hart = hart else: - import random # pylint: disable=import-outside-toplevel self.hart = random.choice(target.harts) #self.hart = target.harts[-1] self.server = None diff --git a/isa/rv64mi/illegal.S b/isa/rv64mi/illegal.S index fb6643b..ca88307 100644 --- a/isa/rv64mi/illegal.S +++ b/isa/rv64mi/illegal.S @@ -72,19 +72,19 @@ msip: beqz t2, bare_s_1 csrc sstatus, t0 - # Make sure SFENCE.VMA and sptbr don't trap when TVM=0. + # Make sure SFENCE.VMA and satp don't trap when TVM=0. sfence.vma - csrr t0, sptbr + csrr t0, satp bad5: .word 0 j fail bad6: - # Make sure SFENCE.VMA and sptbr do trap when TVM=1. + # Make sure SFENCE.VMA and satp do trap when TVM=1. sfence.vma j fail bad7: - csrr t0, sptbr + csrr t0, satp j fail test_tsr: @@ -120,7 +120,7 @@ bare_s_2: j fail # And access to satp should not trap - csrr t0, sptbr + csrr t0, satp bare_s_3: .word 0 j fail @@ -156,7 +156,7 @@ synchronous_exception: csrr t0, mepc # Make sure mtval contains either 0 or the instruction word. - csrr t2, mbadaddr + csrr t2, mtval beqz t2, 1f lhu t1, 0(t0) xor t2, t2, t1 diff --git a/isa/rv64mi/ma_addr.S b/isa/rv64mi/ma_addr.S index 8579c01..0f7dc2e 100644 --- a/isa/rv64mi/ma_addr.S +++ b/isa/rv64mi/ma_addr.S @@ -103,7 +103,7 @@ mtvec_handler: j fail 1: - csrr t0, mbadaddr + csrr t0, mtval beqz t0, 1f bne t0, t1, fail diff --git a/isa/rv64si/dirty.S b/isa/rv64si/dirty.S index 15f3163..8a64e25 100644 --- a/isa/rv64si/dirty.S +++ b/isa/rv64si/dirty.S @@ -22,7 +22,7 @@ RVTEST_CODE_BEGIN la a1, page_table_1 srl a1, a1, RISCV_PGSHIFT or a1, a1, a0 - csrw sptbr, a1 + csrw satp, a1 sfence.vma # Set up MPRV with MPP=S, so loads and stores use S-mode diff --git a/isa/rv64si/icache-alias.S b/isa/rv64si/icache-alias.S index dbc934e..d2468eb 100644 --- a/isa/rv64si/icache-alias.S +++ b/isa/rv64si/icache-alias.S @@ -48,7 +48,7 @@ RVTEST_CODE_BEGIN la a1, page_table_1 srl a1, a1, RISCV_PGSHIFT or a1, a1, a0 - csrw sptbr, a1 + csrw satp, a1 sfence.vma # Enter supervisor mode and make sure correct page is accessed diff --git a/isa/rv64si/ma_fetch.S b/isa/rv64si/ma_fetch.S index b683b6f..31c7a23 100644 --- a/isa/rv64si/ma_fetch.S +++ b/isa/rv64si/ma_fetch.S @@ -17,7 +17,7 @@ RVTEST_CODE_BEGIN #define sscratch mscratch #define sstatus mstatus #define scause mcause - #define sbadaddr mbadaddr + #define stval mtval #define sepc mepc #define sret mret #define stvec_handler mtvec_handler @@ -205,8 +205,8 @@ stvec_handler: addi a1, a1, 4 bne t0, a1, fail - # verify that badaddr == 0 or badaddr == t0+2. - csrr a0, sbadaddr + # verify that tval == 0 or tval == t0+2. + csrr a0, stval beqz a0, 1f addi a0, a0, -2 bne a0, t0, fail |