diff --git a/precompiled/self.bin b/precompiled/self.bin index 344ae73..d80139b 100755 Binary files a/precompiled/self.bin and b/precompiled/self.bin differ diff --git a/test/Makefile b/test/Makefile index 3d2dae1..5f31482 100644 --- a/test/Makefile +++ b/test/Makefile @@ -6,7 +6,8 @@ TESTS = \ meter \ extram \ badcode \ - invalid_opcodes + invalid_opcodes \ + minirv32_internal RUNCMD = $(foreach TEST,${TESTS},make -C ${TEST} &&) CLEANCMD = $(foreach TEST,${TESTS},make -C ${TEST} clean &&) @@ -14,7 +15,7 @@ CLEANCMD = $(foreach TEST,${TESTS},make -C ${TEST} clean &&) ifeq (,$(shell which gcovr)) GCOVRCMD=echo Install gcovr for code coverage reports else - GCOVRCMD=gcovr -r ../ --filter ".*uvm32.c" + GCOVRCMD=gcovr -r ../ --filter ".*uvm32.c" --filter ".*mini.*" PERC=$(shell gcovr -r ../ --filter ".*uvm32.c" | grep uvm | awk '{print $$4}') endif diff --git a/test/minirv32_internal/Makefile b/test/minirv32_internal/Makefile new file mode 100644 index 0000000..dc44dd1 --- /dev/null +++ b/test/minirv32_internal/Makefile @@ -0,0 +1,2 @@ +TOPDIR=../.. +include ${TOPDIR}/test/common/makefile.common diff --git a/test/minirv32_internal/rom/Makefile b/test/minirv32_internal/rom/Makefile new file mode 100644 index 0000000..4cd3f50 --- /dev/null +++ b/test/minirv32_internal/rom/Makefile @@ -0,0 +1,2 @@ +TOPDIR=../../.. +include ${TOPDIR}/test/common/makefile-rom.common diff --git a/test/minirv32_internal/rom/rom.c b/test/minirv32_internal/rom/rom.c new file mode 100644 index 0000000..072ab1d --- /dev/null +++ b/test/minirv32_internal/rom/rom.c @@ -0,0 +1,6 @@ +#include "uvm32_target.h" + +void main(void) { + println("Hello world"); +} + diff --git a/test/minirv32_internal/test/tests.c b/test/minirv32_internal/test/tests.c new file mode 100644 index 0000000..0b1ee7d --- /dev/null +++ b/test/minirv32_internal/test/tests.c @@ -0,0 +1,55 @@ +#include +#include "unity.h" +#include "uvm32.h" +#include "../common/uvm32_common_custom.h" + +#include "rom-header.h" + +static uvm32_state_t vmst; +static uvm32_evt_t evt; + +void setUp(void) { + // runs before each test + uvm32_init(&vmst); + uvm32_load(&vmst, rom_bin, rom_bin_len); +} + +void tearDown(void) { +} + +void test_pc_too_big(void) { + // No code should be doing this, but... + TEST_ASSERT_EQUAL(0x80000000, uvm32_getProgramCounter(&vmst)); + vmst._core.pc = 0x80000000 + 1024 * 16 * 4; // off end + uvm32_run(&vmst, &evt, 1); + TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_ERR); + TEST_ASSERT_EQUAL(evt.data.err.errcode, UVM32_ERR_INTERNAL_CORE); +} + +void test_pc_unaligned_1(void) { + // No code should be doing this, but... + TEST_ASSERT_EQUAL(0x80000000, uvm32_getProgramCounter(&vmst)); + vmst._core.pc = 0x80000000 + 1; + uvm32_run(&vmst, &evt, 1); + TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_ERR); + TEST_ASSERT_EQUAL(evt.data.err.errcode, UVM32_ERR_INTERNAL_CORE); +} + +void test_pc_unaligned_2(void) { + // No code should be doing this, but... + TEST_ASSERT_EQUAL(0x80000000, uvm32_getProgramCounter(&vmst)); + vmst._core.pc = 0x80000000 + 2; + uvm32_run(&vmst, &evt, 1); + TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_ERR); + TEST_ASSERT_EQUAL(evt.data.err.errcode, UVM32_ERR_INTERNAL_CORE); +} + +void test_pc_unaligned_3(void) { + // No code should be doing this, but... + TEST_ASSERT_EQUAL(0x80000000, uvm32_getProgramCounter(&vmst)); + vmst._core.pc = 0x80000000 + 3; + uvm32_run(&vmst, &evt, 1); + TEST_ASSERT_EQUAL(evt.typ, UVM32_EVT_ERR); + TEST_ASSERT_EQUAL(evt.data.err.errcode, UVM32_ERR_INTERNAL_CORE); +} + diff --git a/uvm32/mini-rv32ima.h b/uvm32/mini-rv32ima.h index 531648e..e33c52c 100644 --- a/uvm32/mini-rv32ima.h +++ b/uvm32/mini-rv32ima.h @@ -501,6 +501,7 @@ MINIRV32_STEPPROTO // Handle traps and interrupts. if( trap ) { +#ifndef MINIRV32_RETURN_TRAP if( trap & 0x80000000 ) // If prefixed with 1 in MSB, it's an interrupt, not a trap. { SETCSR( mcause, trap ); @@ -520,9 +521,13 @@ MINIRV32_STEPPROTO // If trapping, always enter machine mode. CSR( extraflags ) |= 3; - trap = 0; pc += 4; +#else + if (trap > 0) { + return trap; + } +#endif } if( CSR( cyclel ) > cycle ) CSR( cycleh )++; diff --git a/uvm32/uvm32.h b/uvm32/uvm32.h index ceb92d2..d397ba5 100644 --- a/uvm32/uvm32.h +++ b/uvm32/uvm32.h @@ -40,6 +40,7 @@ SOFTWARE. // Setup and hooks for mini-rv32ima emulator core #define MINIRV32_DECORATE static +#define MINIRV32_RETURN_TRAP #define MINI_RV32_RAM_SIZE UVM32_MEMORY_SIZE #define MINIRV32_POSTEXEC(pc, ir, retval) {if (retval > 0) return retval;} uint32_t _uvm32_extramLoad(void *userdata, uint32_t addr, uint32_t accessTyp);