diff options
-rwxr-xr-x | debug/gdbserver.py | 122 | ||||
-rw-r--r-- | debug/targets.py | 7 | ||||
-rwxr-xr-x | debug/targets/RISC-V/spike32.lds | 9 | ||||
-rwxr-xr-x | debug/targets/RISC-V/spike64.lds | 9 | ||||
-rwxr-xr-x | debug/test | bin | 17704 -> 0 bytes | |||
-rw-r--r-- | debug/testlib.py | 26 | ||||
-rw-r--r-- | isa/Makefile | 4 | ||||
-rw-r--r-- | isa/hypervisor/2-stage_translation.S | 136 | ||||
-rw-r--r-- | isa/hypervisor/Makefrag | 8 | ||||
-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 |
14 files changed, 300 insertions, 45 deletions
diff --git a/debug/gdbserver.py b/debug/gdbserver.py index 235814a..92f7ce3 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -66,6 +66,20 @@ def srec_parse(line): if typ == b'S0': # header return 0, 0, 0 + elif typ == b'S1': + # data with 16-bit address + address = int(line[4:8], 16) + for i in range(4, count+1): + data += f"{int(line[2 * i:2 * i + 2], 16):c}" + # Ignore the checksum. + return 1, address, data + elif typ == b'S2': + # data with 24-bit address + address = int(line[4:10], 16) + for i in range(5, count+1): + data += f"{int(line[2 * i:2 * i + 2], 16):c}" + # Ignore the checksum. + return 2, address, data elif typ == b'S3': # data with 32-bit address # Any higher bits were chopped off. @@ -74,9 +88,9 @@ def srec_parse(line): data += f"{int(line[2 * i:2 * i + 2], 16):c}" # Ignore the checksum. return 3, address, data - elif typ == b'S7': + elif typ in (b'S7', b'S8', b'S9'): # ignore execution start field - return 7, 0, 0 + return int(typ[-1]), 0, 0 else: raise TestFailed(f"Unsupported SREC type {typ!r}.") @@ -264,6 +278,9 @@ class MemTest64(SimpleMemoryTest): class MemTestReadInvalid(SimpleMemoryTest): def test(self): bad_address = self.hart.bad_address + if self.target.support_set_pmp_deny: + self.set_pmp_deny(bad_address) + self.gdb.command("monitor riscv set_mem_access progbuf abstract") good_address = self.hart.ram + 0x80 self.write_nop_program(2) @@ -279,6 +296,10 @@ class MemTestReadInvalid(SimpleMemoryTest): self.gdb.stepi() # Don't let gdb cache register read assertEqual(self.gdb.p(f"*((int*)0x{good_address:x})"), 0xabcdef) assertEqual(self.gdb.p("$s0"), 0x12345678) + if self.target.support_set_pmp_deny: + self.reset_pmp_deny() + self.gdb.command("monitor riscv set_mem_access progbuf sysbus " + "abstract") #class MemTestWriteInvalid(SimpleMemoryTest): # def test(self): @@ -389,7 +410,7 @@ class MemTestBlock(GdbTest): highest_seen = 0 for line in b: record_type, address, line_data = srec_parse(line) - if record_type == 3: + if record_type in (1, 2, 3): offset = address - (self.hart.ram & 0xffffffff) written_data = data[offset:offset+len(line_data)] highest_seen += len(line_data) @@ -676,6 +697,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 @@ -684,6 +746,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), @@ -692,24 +760,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): @@ -726,14 +779,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() @@ -1056,9 +1117,9 @@ class InterruptTest(GdbSingleHartTest): self.disable_timer() return - self.disable_timer() assertGreater(interrupt_count, 1000) assertGreater(local, 1000) + self.disable_timer() def postMortem(self): GdbSingleHartTest.postMortem(self) @@ -2125,8 +2186,13 @@ 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 + if self.target.support_set_pmp_deny: + self.set_pmp_deny(bad_address) + self.gdb.command("monitor riscv set_mem_access progbuf abstract") + 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) @@ -2134,6 +2200,10 @@ class EtriggerTest(DebugTest): # actual exception handler. assertIn("breakpoint", output) assertIn("trap_entry", self.gdb.where()) + if self.target.support_set_pmp_deny: + self.reset_pmp_deny() + self.gdb.command("monitor riscv set_mem_access progbuf sysbus " + "abstract") class IcountTest(DebugTest): compile_args = ("programs/infinite_loop.S", ) diff --git a/debug/targets.py b/debug/targets.py index bb7a5cf..eca0231 100644 --- a/debug/targets.py +++ b/debug/targets.py @@ -141,6 +141,13 @@ class Target: # Instruction count limit icount_limit = 4 + # Implements page-based virtual memory. So when PMP changes execute an + # SFENCE.VMA + implements_page_virtual_memory = True + + # Support set_pmp_deny to create invalid addresses. + support_set_pmp_deny = False + # Internal variables: directory = None temporary_files = [] 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/test b/debug/test Binary files differdeleted file mode 100755 index 9b72737..0000000 --- a/debug/test +++ /dev/null diff --git a/debug/testlib.py b/debug/testlib.py index 0279b08..82fe3fb 100644 --- a/debug/testlib.py +++ b/debug/testlib.py @@ -65,6 +65,7 @@ def compile(args): # pylint: disable=redefined-builtin class Spike: # pylint: disable=too-many-instance-attributes # pylint: disable=too-many-locals + # pylint: disable=too-many-positional-arguments def __init__(self, target, halted=False, timeout=None, with_jtag_gdb=True, isa=None, progbufsize=None, dmi_rti=None, abstract_rti=None, support_hasel=True, support_abstract_csr=True, @@ -300,6 +301,8 @@ class VcsSim: class Openocd: # pylint: disable=too-many-instance-attributes # pylint: disable-next=consider-using-with + # pylint: disable=too-many-positional-arguments + # pylint: disable=consider-using-with logfile = tempfile.NamedTemporaryFile(prefix='openocd', suffix='.log') logname = logfile.name @@ -717,6 +720,7 @@ class Gdb: 11, 149, 107, 163, 73, 47, 43, 173, 7, 109, 101, 103, 191, 2, 139, 97, 193, 157, 3, 29, 79, 113, 5, 89, 19, 37, 71, 179, 59, 137, 53) + # pylint: disable=too-many-positional-arguments def __init__(self, target, ports, cmd=None, timeout=60, binaries=None, logremote=False): assert ports @@ -1481,6 +1485,22 @@ class GdbTest(BaseTest): self.gdb.select_hart(self.hart) self.gdb.command(f"monitor targets {self.hart.id}") + def set_pmp_deny(self, address, size=4 * 1024): + # Enable physical memory protection, no permission to access specific + # address range (default 4KB). + self.gdb.p("$mseccfg=0x4") # RLB + self.gdb.p("$pmpcfg0=0x98") # L, NAPOT, !R, !W, !X + self.gdb.p("$pmpaddr0=" + f"0x{((address >> 2) | ((size - 1) >> 3)):x}") + # PMP changes require an sfence.vma, 0x12000073 is sfence.vma + self.gdb.command("monitor riscv exec_progbuf 0x12000073") + + def reset_pmp_deny(self): + self.gdb.p("$pmpcfg0=0") + self.gdb.p("$pmpaddr0=0") + # PMP changes require an sfence.vma, 0x12000073 is sfence.vma + self.gdb.command("monitor riscv exec_progbuf 0x12000073") + def disable_pmp(self): # Disable physical memory protection by allowing U mode access to all # memory. @@ -1494,6 +1514,9 @@ class GdbTest(BaseTest): # pmcfg0 readback matches write, so TOR is supported. self.gdb.p("$pmpaddr0=" f"0x{(self.hart.ram + self.hart.ram_size) >> 2:x}") + if self.target.implements_page_virtual_memory: + # PMP changes require an sfence.vma, 0x12000073 is sfence.vma + self.gdb.command("monitor riscv exec_progbuf 0x12000073") except CouldNotFetch: # PMP registers are optional pass @@ -1504,6 +1527,9 @@ class GdbTest(BaseTest): if interrupt: self.gdb.interrupt() self.gdb.p("$mie=$mie & ~0x80") + self.gdb.p("$mstatus=$mstatus & ~0x8") + self.gdb.p(f"*((long long*) 0x{self.target.clint_addr + 0x4000:x})\ + =0x" + "f" * (self.hart.xlen // 4)) def exit(self, expected_result=10): self.gdb.command("delete") diff --git a/isa/Makefile b/isa/Makefile index bf85e1f..e3b6719 100644 --- a/isa/Makefile +++ b/isa/Makefile @@ -22,6 +22,7 @@ include $(src_dir)/rv64si/Makefrag include $(src_dir)/rv64ssvnapot/Makefrag include $(src_dir)/rv64mi/Makefrag include $(src_dir)/rv64mzicbo/Makefrag +include $(src_dir)/hypervisor/Makefrag endif include $(src_dir)/rv32ui/Makefrag include $(src_dir)/rv32uc/Makefrag @@ -58,7 +59,7 @@ vpath %.S $(src_dir) $(RISCV_OBJDUMP) $< > $@ %.out: % - $(RISCV_SIM) --isa=rv64gc_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@ + $(RISCV_SIM) --isa=rv64gch_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@ %.out32: % $(RISCV_SIM) --isa=rv32gc_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@ @@ -116,6 +117,7 @@ $(eval $(call compile_template,rv64mzicbo,-march=rv64g_zicboz -mabi=lp64)) $(eval $(call compile_template,rv64si,-march=rv64g -mabi=lp64)) $(eval $(call compile_template,rv64ssvnapot,-march=rv64g -mabi=lp64)) $(eval $(call compile_template,rv64mi,-march=rv64g -mabi=lp64)) +$(eval $(call compile_template,hypervisor,-march=rv64gh -mabi=lp64)) endif tests_dump = $(addsuffix .dump, $(tests)) diff --git a/isa/hypervisor/2-stage_translation.S b/isa/hypervisor/2-stage_translation.S new file mode 100644 index 0000000..93b4340 --- /dev/null +++ b/isa/hypervisor/2-stage_translation.S @@ -0,0 +1,136 @@ +# See LICENSE for license details. + +#***************************************************************************** +# 2-stage_translation.S +#----------------------------------------------------------------------------- +# +# Set 2 stage translation, do a simple load store. +# + +#include "riscv_test.h" +#include "test_macros.h" + +#define vspt0_gpa 0x0 +#define vspt1_gpa 0x1000 +#define vspt2_gpa 0x2000 +#define GPA 0x200000 + +RVTEST_RV64M +RVTEST_CODE_BEGIN + + li TESTNUM, 2 + +# map GVA 0x0~0xfff to GPA 0x200000~0x200fff +vs_pt_init: + li t0, vspt1_gpa + srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT + ori t0, t0, PTE_V + sd t0, vspt_0, t1 + + li t0, vspt2_gpa + srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT + ori t0, t0, PTE_V + sd t0, vspt_1, t1 + + li t0, GPA + srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT + ori t0, t0, PTE_V | PTE_X | PTE_A | PTE_D | PTE_R | PTE_W + sd t0, vspt_2, t1 + +init_vsatp: + li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39 + la a1, vspt0_gpa + srl a1, a1, RISCV_PGSHIFT + or a1, a1, a0 + csrw vsatp, a1 + hfence.vvma + + +# map GPA 0x200000~0x200fff to data_page +guest_pt_init: + la t0, gpt_1 + srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT + ori t0, t0, PTE_V + sd t0, gpt_0, t1 + + la t0, gpt_2 + srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT + ori t0, t0, PTE_V + sd t0, gpt_1, t1 + + la t0, gpt_3 + srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT + ori t0, t0, PTE_V + sd t0, gpt_1 + 8, t1 + + la t0, vspt_0 + srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT + ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U + sd t0, gpt_2, t1 + + la t0, vspt_1 + srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT + ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U + sd t0, gpt_2 + 8, t1 + + la t0, vspt_2 + srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT + ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U + sd t0, gpt_2 + 16, t1 + + la t0, data_page + srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT + ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U + sd t0, gpt_3, t1 + +init_hgatp: + li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39 + la a1, gpt_0 + srl a1, a1, RISCV_PGSHIFT + or a1, a1, a0 + csrw hgatp, a1 + hfence.gvma + +hstatus_init: + li a0, HSTATUS_SPVP + csrs hstatus, a0 + + la a0, data_page + li a1, 0x12345678 + sw a1, 0(a0) + + li t0, 0x0 + hlv.w t2, 0(t0) # should be 0x12345678 + hsv.w t2, 0(t0) + bne t2, a1, fail + + RVTEST_PASS + + TEST_PASSFAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +.align 12 +vspt_0: .dword 0 +.align 12 +vspt_1: .dword 0 +.align 12 +vspt_2: .dword 0 + +.align 14 +gpt_0: .dword 0 +.align 14 +gpt_1: .dword 0 +.align 12 +gpt_2: .dword 0 +.align 12 +gpt_3: .dword 0 +.align 12 +data_page: .dword 0 + +RVTEST_DATA_END diff --git a/isa/hypervisor/Makefrag b/isa/hypervisor/Makefrag new file mode 100644 index 0000000..ed483df --- /dev/null +++ b/isa/hypervisor/Makefrag @@ -0,0 +1,8 @@ +#======================================================================= +# Makefrag for hypervisor tests +#----------------------------------------------------------------------- + +hypervisor_sc_tests = \ + 2-stage-translation \ + +hypervisor_p_tests = $(addprefix hypervisor-p-, $(hypervisor_sc_tests)) 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 |