Merge "Add trap handlers to exception tests"
diff --git a/tests/kelvin_isa/BUILD b/tests/kelvin_isa/BUILD
index b606fad..004da08 100644
--- a/tests/kelvin_isa/BUILD
+++ b/tests/kelvin_isa/BUILD
@@ -51,20 +51,6 @@
)
kelvin_test(
- name = "mret_fault",
- srcs = [
- "mret_fault.cc",
- ],
- hw_test_size = "small",
- deps = [
- ":kelvin_test",
- ],
- iss = False,
- expect_success = False,
- tags = ["intentional_failure"],
-)
-
-kelvin_test(
name = "instr_fault",
srcs = [
"instr_fault.cc",
@@ -74,8 +60,7 @@
":kelvin_test",
],
iss = False,
- expect_success = False,
- tags = ["intentional_failure"],
+ tags = ["exceptions"],
)
kelvin_test(
@@ -88,8 +73,7 @@
":kelvin_test",
],
iss = False,
- expect_success = False,
- tags = ["intentional_failure"],
+ tags = ["exceptions"],
)
kelvin_test(
@@ -102,8 +86,7 @@
":kelvin_test",
],
iss = False,
- expect_success = False,
- tags = ["intentional_failure"],
+ tags = ["exceptions"],
)
kelvin_test(
@@ -116,8 +99,7 @@
":kelvin_test",
],
iss = False,
- expect_success = False,
- tags = ["intentional_failure"],
+ tags = ["exceptions"],
)
kelvin_test(
@@ -130,8 +112,7 @@
":kelvin_test",
],
iss = False,
- expect_success = False,
- tags = ["intentional_failure"],
+ tags = ["exceptions"],
)
kelvin_test(
@@ -144,8 +125,7 @@
":kelvin_test",
],
iss = False,
- expect_success = False,
- tags = ["intentional_failure"],
+ tags = ["exceptions"],
)
kelvin_test(
@@ -158,8 +138,7 @@
":kelvin_test",
],
iss = False,
- expect_success = False,
- tags = ["intentional_failure"],
+ tags = ["exceptions"],
)
kelvin_test(
@@ -172,8 +151,9 @@
":kelvin_test",
],
iss = False,
- # This passes on core_sim, but should fail on core_mini_sim.
- # expect_success = False,
+ # This fails on core_sim, but should pass on core_mini_sim.
+ expect_success = False,
+ tags = ["exceptions"],
)
kelvin_test(
@@ -186,8 +166,7 @@
":kelvin_test",
],
iss = False,
- expect_success = False,
- tags = ["intentional_failure"],
+ tags = ["exceptions"],
)
kelvin_test(
diff --git a/tests/kelvin_isa/illegal.cc b/tests/kelvin_isa/illegal.cc
index 418ee00..b476450 100644
--- a/tests/kelvin_isa/illegal.cc
+++ b/tests/kelvin_isa/illegal.cc
@@ -14,7 +14,28 @@
#include <cstdint>
+extern "C" {
+void isr_wrapper(void);
+__attribute__((naked)) void isr_wrapper(void) {
+ asm volatile(
+ "csrr t0, mepc \n"
+ "addi t0, t0, 4 \n"
+ "csrw mepc, t0 \n"
+ "csrr t0, mcause \n"
+ "li t1, 2 \n"
+ "beq t0, t1, 0f \n"
+ "csrr t0, mtval \n"
+ "la t1, 0x02007043 \n"
+ "beq t0, t1, 0f \n"
+ "ebreak \n"
+ "0: mpause \n"
+ );
+}
+
+} // extern "C"
+
int main(int argc, char** argv) {
+ asm volatile("csrw mtvec, %0" :: "rK"((uint32_t)(&isr_wrapper)));
asm volatile(".word 0x02007043"); // fmadd.d f0, f0, f0, f0
return 0;
diff --git a/tests/kelvin_isa/instr_align_0.cc b/tests/kelvin_isa/instr_align_0.cc
index 303e279..375b48d 100644
--- a/tests/kelvin_isa/instr_align_0.cc
+++ b/tests/kelvin_isa/instr_align_0.cc
@@ -14,9 +14,27 @@
#include <cstdint>
+extern "C" {
+void isr_wrapper(void);
+__attribute__((naked)) void isr_wrapper(void) {
+ asm volatile(
+ "csrr t0, mepc \n"
+ "addi t0, t0, 4 \n"
+ "csrw mepc, t0 \n"
+ "csrr t0, mcause \n"
+ "li t1, 0 \n"
+ "beq t0, t1, 0f \n"
+ "ebreak \n"
+ "0: mpause \n"
+ );
+}
+
+} // extern "C"
+
int main(int argc, char** argv) {
// Instruction address misaligned
- asm volatile("la ra, 0x3; jalr ra,ra");
+ asm volatile("csrw mtvec, %0" :: "rK"((uint32_t)(&isr_wrapper)));
+ asm volatile("la ra, 0x3; nop; nop; nop; nop; jalr ra,ra");
return 0;
}
diff --git a/tests/kelvin_isa/instr_align_1.cc b/tests/kelvin_isa/instr_align_1.cc
index 1ee81d1..a99c8f7 100644
--- a/tests/kelvin_isa/instr_align_1.cc
+++ b/tests/kelvin_isa/instr_align_1.cc
@@ -14,9 +14,28 @@
#include <cstdint>
+extern "C" {
+void isr_wrapper(void);
+__attribute__((naked)) void isr_wrapper(void) {
+ asm volatile(
+ "csrr t0, mepc \n"
+ "addi t0, t0, 4 \n"
+ "csrw mepc, t0 \n"
+ "csrr t0, mcause \n"
+ "li t1, 0 \n"
+ "beq t0, t1, 0f \n"
+ "ebreak \n"
+ "0: mpause \n"
+ );
+}
+
+} // extern "C"
+
int main(int argc, char** argv) {
// Instruction address misaligned
- asm volatile("jal x0, .+2");
+ // // TODO(atv): Make multiple versions of this for slot utilization purposes.
+ asm volatile("csrw mtvec, %0" :: "rK"((uint32_t)(&isr_wrapper)));
+ asm volatile("nop; jal x0, .+2");
return 0;
}
diff --git a/tests/kelvin_isa/instr_align_2.cc b/tests/kelvin_isa/instr_align_2.cc
index 21aa0b7..a6a9507 100644
--- a/tests/kelvin_isa/instr_align_2.cc
+++ b/tests/kelvin_isa/instr_align_2.cc
@@ -14,8 +14,26 @@
#include <cstdint>
+extern "C" {
+void isr_wrapper(void);
+__attribute__((naked)) void isr_wrapper(void) {
+ asm volatile(
+ "csrr t0, mepc \n"
+ "addi t0, t0, 4 \n"
+ "csrw mepc, t0 \n"
+ "csrr t0, mcause \n"
+ "li t1, 0 \n"
+ "beq t0, t1, 0f \n"
+ "ebreak \n"
+ "0: mpause \n"
+ );
+}
+
+} // extern "C"
+
int main(int argc, char** argv) {
// Instruction address misaligned
+ asm volatile("csrw mtvec, %0" :: "rK"((uint32_t)(&isr_wrapper)));
asm volatile("beqz x0, .+2");
return 0;
diff --git a/tests/kelvin_isa/instr_fault.cc b/tests/kelvin_isa/instr_fault.cc
index c3e974f..f7981b2 100644
--- a/tests/kelvin_isa/instr_fault.cc
+++ b/tests/kelvin_isa/instr_fault.cc
@@ -12,7 +12,27 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cstdint>
+
+extern "C" {
+void isr_wrapper(void);
+__attribute__((naked)) void isr_wrapper(void) {
+ asm volatile(
+ "csrr t0, mepc \n"
+ "addi t0, t0, 4 \n"
+ "csrw mepc, t0 \n"
+ "csrr t0, mcause \n"
+ "li t1, 1 \n"
+ "beq t0, t1, 0f \n"
+ "ebreak \n"
+ "0: mpause \n"
+ );
+}
+
+} // extern "C"
+ //
int main(int argc, char** argv) {
+ asm volatile("csrw mtvec, %0" :: "rK"((uint32_t)(&isr_wrapper)));
asm volatile("la ra, 0x40000000; jalr ra, ra");
return 0;
diff --git a/tests/kelvin_isa/load_fault_0.cc b/tests/kelvin_isa/load_fault_0.cc
index c3e974f..1a60889 100644
--- a/tests/kelvin_isa/load_fault_0.cc
+++ b/tests/kelvin_isa/load_fault_0.cc
@@ -12,8 +12,28 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-int main(int argc, char** argv) {
- asm volatile("la ra, 0x40000000; jalr ra, ra");
+#include <cstdint>
+extern "C" {
+void isr_wrapper(void);
+__attribute__((naked)) void isr_wrapper(void) {
+ asm volatile(
+ "csrr t0, mepc \n"
+ "addi t0, t0, 4 \n"
+ "csrw mepc, t0 \n"
+ "csrr t0, mcause \n"
+ "li t1, 1 \n"
+ "beq t0, t1, 0f \n"
+ "ebreak \n"
+ "0: mpause \n"
+ );
+}
+
+} // extern "C"
+
+int main(int argc, char** argv) {
+ asm volatile("csrw mtvec, %0" :: "rK"((uint32_t)(&isr_wrapper)));
+ asm volatile("la ra, 0x40000000; jalr ra, ra");
+ asm volatile("ebreak");
return 0;
}
diff --git a/tests/kelvin_isa/load_fault_1.cc b/tests/kelvin_isa/load_fault_1.cc
index 78f7beb..48a93cb 100644
--- a/tests/kelvin_isa/load_fault_1.cc
+++ b/tests/kelvin_isa/load_fault_1.cc
@@ -14,10 +14,32 @@
#include <cstdint>
+extern "C" {
+void isr_wrapper(void);
+__attribute__((naked)) void isr_wrapper(void) {
+ asm volatile(
+ "csrr t0, mepc \n"
+ "addi t0, t0, 4 \n"
+ "csrw mepc, t0 \n"
+ "csrr t0, mcause \n"
+ "li t1, 5 \n"
+ "bne t0, t1, 0f \n"
+ "csrr t0, mtval \n"
+ "la t1, 0xA0000000 \n"
+ "bne t0, t1, 0f \n"
+ "mpause \n"
+ "0: ebreak \n"
+ );
+}
+
+} // extern "C"
+
int main(int argc, char** argv) {
+ asm volatile("csrw mtvec, %0" :: "rK"((uint32_t)(&isr_wrapper)));
volatile uint32_t* load_bad_addr = (uint32_t*)0xA0000000;
volatile uint32_t foo = *load_bad_addr;
(void)foo;
+ asm volatile("ebreak");
return 0;
}
diff --git a/tests/kelvin_isa/mret_fault.cc b/tests/kelvin_isa/mret_fault.cc
deleted file mode 100644
index 3a16b5e..0000000
--- a/tests/kelvin_isa/mret_fault.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2025 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include <cstdint>
-
-extern "C" {
-
-void isr_wrapper(void);
-__attribute__((naked)) void isr_wrapper() {
- asm volatile(
- "csrr t0, mepc \n"
- "addi t0, t0, 2 \n"
- "csrw mepc, t0 \n"
- "mret \n");
-}
-void bad_isr(void);
-__attribute__((naked)) void bad_isr() { asm volatile("ebreak \n"); }
-
-__attribute__((naked, aligned(256))) void isr_vector_table() {
- asm volatile(
- "j isr_wrapper \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n"
- "j bad_isr \n");
-}
-
-int main(int argc, char** argv) {
- asm volatile("csrw mtvec, %0" ::"rK"((uint32_t)(&isr_vector_table)));
- asm volatile("ecall");
- return 0;
-}
-
-} // extern "C"
\ No newline at end of file
diff --git a/tests/kelvin_isa/store_fault_0.cc b/tests/kelvin_isa/store_fault_0.cc
index 68c5094..04051f7 100644
--- a/tests/kelvin_isa/store_fault_0.cc
+++ b/tests/kelvin_isa/store_fault_0.cc
@@ -14,10 +14,32 @@
#include <cstdint>
+extern "C" {
+void isr_wrapper(void);
+__attribute__((naked)) void isr_wrapper(void) {
+ asm volatile(
+ "csrr t0, mepc \n"
+ "addi t0, t0, 4 \n"
+ "csrw mepc, t0 \n"
+ "csrr t0, mcause \n"
+ "li t1, 7 \n"
+ "beq t0, t1, 0f \n"
+ "csrr t0, mtval \n"
+ "li t1, 0x4 \n"
+ "beq t0, t1, 0f \n"
+ "ebreak \n"
+ "0: mpause \n"
+ );
+}
+
+} // extern "C"
+
int main(int argc, char** argv) {
// Store Fault (internal)
+ asm volatile("csrw mtvec, %0" :: "rK"((uint32_t)(&isr_wrapper)));
volatile uint32_t* store_bad_addr = (uint32_t*)4L;
*store_bad_addr = 0xdeadbeef;
+ asm volatile("ebreak");
return 0;
}
diff --git a/tests/kelvin_isa/store_fault_1.cc b/tests/kelvin_isa/store_fault_1.cc
index bb5d2fc..e646ccd 100644
--- a/tests/kelvin_isa/store_fault_1.cc
+++ b/tests/kelvin_isa/store_fault_1.cc
@@ -14,8 +14,29 @@
#include <cstdint>
+extern "C" {
+void isr_wrapper(void);
+__attribute__((naked)) void isr_wrapper(void) {
+ asm volatile(
+ "csrr t0, mepc \n"
+ "addi t0, t0, 4 \n"
+ "csrw mepc, t0 \n"
+ "csrr t0, mcause \n"
+ "li t1, 7 \n"
+ "beq t0, t1, 0f \n"
+ "csrr t0, mtval \n"
+ "li t1, 0xA0000000 \n"
+ "beq t0, t1, 0f \n"
+ "ebreak \n"
+ "0: mpause \n"
+ );
+}
+
+} // extern "C"
+
int main(int argc, char** argv) {
// Store Fault (external)
+ asm volatile("csrw mtvec, %0" :: "rK"((uint32_t)(&isr_wrapper)));
volatile uint32_t* store_bad_addr = (uint32_t*)0xA0000000;
*store_bad_addr = 0xdeadbeef;
diff --git a/tests/riscv-tests/BUILD b/tests/riscv-tests/BUILD
index b224702..d152f21 100644
--- a/tests/riscv-tests/BUILD
+++ b/tests/riscv-tests/BUILD
@@ -223,6 +223,25 @@
],
)
+# kelvin_test(
+# name = "rv32mi_illegal",
+# srcs = [
+# "@riscv-tests//:isa/rv64mi/illegal.S",
+# ],
+# copts = [
+# "-Itests/riscv-tests",
+# "-Iexternal/riscv-tests/isa/macros/scalar",
+# "-Wno-variadic-macros",
+# ],
+# defines = [
+# "RVTEST_RV64M=RVTEST_RV32M",
+# ],
+# hw_test_size = "small",
+# deps = [
+# ":riscv_tests_base",
+# ],
+# )
+
kelvin_test(
name = "rv32mi_csr",
srcs = [