When a trap occurs in mini-rv32ima, always pass to the host rather than allowing running code to handle it. This would be important for a real OS, but the aim of uvm32 is embeddable logic - not full emulation.

As all traps are caught by host, begin testing mini-rv32ima internals by checking PC oob and PC alignment.
This commit is contained in:
Toby Jaffey 2025-12-14 11:00:45 +00:00
parent be5dbbfa44
commit 5dc9acdf3d
8 changed files with 75 additions and 3 deletions

View file

@ -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

View file

@ -0,0 +1,2 @@
TOPDIR=../..
include ${TOPDIR}/test/common/makefile.common

View file

@ -0,0 +1,2 @@
TOPDIR=../../..
include ${TOPDIR}/test/common/makefile-rom.common

View file

@ -0,0 +1,6 @@
#include "uvm32_target.h"
void main(void) {
println("Hello world");
}

View file

@ -0,0 +1,55 @@
#include <string.h>
#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);
}