Add ecall/mret test
Change-Id: I5c1bfa67843f3ef03bcfe308db564dadfb8b713f
diff --git a/tests/kelvin_isa/BUILD b/tests/kelvin_isa/BUILD
index 1584d83..5861d6a 100644
--- a/tests/kelvin_isa/BUILD
+++ b/tests/kelvin_isa/BUILD
@@ -36,6 +36,17 @@
)
kelvin_test(
+ name = "ecall",
+ srcs = [
+ "ecall.cc",
+ ],
+ hw_test_size = "small",
+ deps = [
+ ":kelvin_test",
+ ],
+)
+
+kelvin_test(
name = "acset",
srcs = [
"acset.cc",
diff --git a/tests/kelvin_isa/ecall.cc b/tests/kelvin_isa/ecall.cc
new file mode 100644
index 0000000..55ba750
--- /dev/null
+++ b/tests/kelvin_isa/ecall.cc
@@ -0,0 +1,86 @@
+// Copyright 2024 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>
+
+static volatile uint32_t isr_ok = 0;
+
+extern "C" {
+
+void isr_wrapper(void);
+__attribute__((naked)) void isr_wrapper() {
+ asm volatile(
+ "csrr t0, mepc \n"
+ "addi t0, t0, 4 \n"
+ "csrw mepc, t0 \n"
+ "csrr t0, mcause \n"
+ "li t1, 11 \n"
+ "bne t0, t1, 0f \n"
+ "lw t0, 0(%[isr_ok]) \n"
+ "addi t0, t0, 1 \n"
+ "sw t0, 0(%[isr_ok]) \n"
+ "0: mret \n"
+ : /* outputs */
+ : /* inputs */[isr_ok] "r"(&isr_ok));
+}
+
+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");
+ if (isr_ok == 0) {
+ asm volatile("ebreak");
+ }
+
+ return 0;
+}
+}