Skip to content

Commit

Permalink
Make accessing !RV32E registers trap, not crash
Browse files Browse the repository at this point in the history
  • Loading branch information
nwf-msr committed Jan 22, 2024
1 parent a79815b commit 0c38f6b
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 63 deletions.

This file was deleted.

157 changes: 157 additions & 0 deletions riscv_patches/0003-Trap-if-reading-or-writing-upper-16-registers.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
From 5ec8de4794c67ab98dd13603bd0e88d9c80d2f95 Mon Sep 17 00:00:00 2001
From: Robert Norton <[email protected]>
Date: Mon, 31 Oct 2022 14:49:45 +0000
Subject: [PATCH 3/9] Trap if reading or writing upper 16 registers

---
model/riscv_regs.sail | 70 ++----------------------------------------
model/riscv_step.sail | 9 ++++++
model/riscv_types.sail | 12 ++++++--
3 files changed, 22 insertions(+), 69 deletions(-)

diff --git a/model/riscv_regs.sail b/model/riscv_regs.sail
index 15e7613..28bc0c3 100644
--- a/model/riscv_regs.sail
+++ b/model/riscv_regs.sail
@@ -93,22 +93,6 @@ register x12 : regtype
register x13 : regtype
register x14 : regtype
register x15 : regtype
-register x16 : regtype
-register x17 : regtype
-register x18 : regtype
-register x19 : regtype
-register x20 : regtype
-register x21 : regtype
-register x22 : regtype
-register x23 : regtype
-register x24 : regtype
-register x25 : regtype
-register x26 : regtype
-register x27 : regtype
-register x28 : regtype
-register x29 : regtype
-register x30 : regtype
-register x31 : regtype

val rX : forall 'n, 0 <= 'n < 32. regno('n) -> xlenbits
function rX r = {
@@ -130,23 +114,7 @@ function rX r = {
13 => x13,
14 => x14,
15 => x15,
- 16 => x16,
- 17 => x17,
- 18 => x18,
- 19 => x19,
- 20 => x20,
- 21 => x21,
- 22 => x22,
- 23 => x23,
- 24 => x24,
- 25 => x25,
- 26 => x26,
- 27 => x27,
- 28 => x28,
- 29 => x29,
- 30 => x30,
- 31 => x31,
- _ => {assert(false, "invalid register number"); zero_reg}
+ _ => throw Error_not_rv32e_register()
};
regval_from_reg(v)
}
@@ -183,23 +151,7 @@ function wX (r, in_v) = {
13 => x13 = v,
14 => x14 = v,
15 => x15 = v,
- 16 => x16 = v,
- 17 => x17 = v,
- 18 => x18 = v,
- 19 => x19 = v,
- 20 => x20 = v,
- 21 => x21 = v,
- 22 => x22 = v,
- 23 => x23 = v,
- 24 => x24 = v,
- 25 => x25 = v,
- 26 => x26 = v,
- 27 => x27 = v,
- 28 => x28 = v,
- 29 => x29 = v,
- 30 => x30 = v,
- 31 => x31 = v,
- _ => assert(false, "invalid register number")
+ _ => throw Error_not_rv32e_register()
};
if (r != 0) then {
rvfi_wX(r, in_v);
@@ -324,21 +276,5 @@ function init_base_regs () = {
x12 = zero_reg;
x13 = zero_reg;
x14 = zero_reg;
- x15 = zero_reg;
- x16 = zero_reg;
- x17 = zero_reg;
- x18 = zero_reg;
- x19 = zero_reg;
- x20 = zero_reg;
- x21 = zero_reg;
- x22 = zero_reg;
- x23 = zero_reg;
- x24 = zero_reg;
- x25 = zero_reg;
- x26 = zero_reg;
- x27 = zero_reg;
- x28 = zero_reg;
- x29 = zero_reg;
- x30 = zero_reg;
- x31 = zero_reg
+ x15 = zero_reg
}
diff --git a/model/riscv_step.sail b/model/riscv_step.sail
index 550f11a..25e0ca9 100644
--- a/model/riscv_step.sail
+++ b/model/riscv_step.sail
@@ -68,6 +68,15 @@
/* SUCH DAMAGE. */
/*=======================================================================================*/

+function try_execute (x : ast) -> Retired = {
+ try {
+ execute(x)
+ } catch {
+ Error_not_rv32e_register() => { handle_illegal(); RETIRE_FAIL },
+ e => throw e /* Rethrow other execptions */
+ }
+}
+
/* The emulator fetch-execute-interrupt dispatch loop. */

/* returns whether to increment the step count in the trace */
diff --git a/model/riscv_types.sail b/model/riscv_types.sail
index 14916c7..5152ef8 100644
--- a/model/riscv_types.sail
+++ b/model/riscv_types.sail
@@ -134,8 +134,16 @@ function arch_to_bits(a : Architecture) -> arch_xlen =
/* model-internal exceptions */

union exception = {
- Error_not_implemented : string,
- Error_internal_error : unit
+ /*
+ * This is not the proper way to do this, but it is surely the simplest: we
+ * we allow instructions to object to their operands rather than patching the
+ * encdec mapping to do the right thing. (That would be extensive, because
+ * the `ast` type does not have an encapsulated notion of a register selector
+ * distinct from the underlying bit slice of the instruction.)
+ */
+ Error_not_rv32e_register : unit,
+ Error_not_implemented : string,
+ Error_internal_error : unit
}

val not_implemented : forall ('a : Type). string -> 'a
--
2.39.2

0 comments on commit 0c38f6b

Please sign in to comment.