Add executables that trigger faults.

Three are added: an illegal instruction fault, executing past the
instruction window, and writing data past the data window. The latter
doesn't yet work as the length of the data window is the entire DTCM.

Change-Id: Idf6d8998dc54e9238cf9edf1040ca4d5a80141ef
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 96a4313..9acd853 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,6 +37,7 @@
 
 add_subdirectory(springbok)
 add_subdirectory(hello_vec)
+add_subdirectory(faults)
 
 add_subdirectory(vector_tests)
 add_subdirectory(vector_load_store_tests)
diff --git a/faults/CMakeLists.txt b/faults/CMakeLists.txt
new file mode 100644
index 0000000..37301f2
--- /dev/null
+++ b/faults/CMakeLists.txt
@@ -0,0 +1,30 @@
+if(${BUILD_SIMPLIFIED_CORE})
+  return()
+endif()
+
+vec_cc_binary(
+    NAME
+      illegal_instruction
+    SRCS
+      illegal_instruction.c
+  LINKOPTS
+    -Xlinker --defsym=__itcm_length__=128K
+)
+
+vec_cc_binary(
+    NAME
+      write_past_data_window
+    SRCS
+      write_past_data_window.c
+  LINKOPTS
+    -Xlinker --defsym=__itcm_length__=128K
+)
+
+vec_cc_binary(
+    NAME
+      execute_past_inst_window
+    SRCS
+      execute_past_inst_window.c
+  LINKOPTS
+    -Xlinker --defsym=__itcm_length__=128K
+)
diff --git a/faults/execute_past_inst_window.c b/faults/execute_past_inst_window.c
new file mode 100644
index 0000000..beadb60
--- /dev/null
+++ b/faults/execute_past_inst_window.c
@@ -0,0 +1,8 @@
+#include "layout.h"
+
+int main() {
+  // The end of the virtual window will be outside our allocated window.
+  int* i = (int*)(IMMU_RANGE_START + IMMU_WINDOW_SIZE - sizeof(int));
+  ((void (*)())i)();
+  return 0;
+}
diff --git a/faults/illegal_instruction.c b/faults/illegal_instruction.c
new file mode 100644
index 0000000..dd46448
--- /dev/null
+++ b/faults/illegal_instruction.c
@@ -0,0 +1,6 @@
+int main() {
+  // It is an illegal setting in elen=32.
+  __asm__ volatile("vsetivli t0, 8, e8, mf8, ta, mu");
+  __asm__ volatile("vmv.v.i v0, 0");
+  return 0;
+}
diff --git a/faults/layout.h b/faults/layout.h
new file mode 100644
index 0000000..d8c6a80
--- /dev/null
+++ b/faults/layout.h
@@ -0,0 +1,11 @@
+#ifndef LAYOUT_H_
+#define LAYOUT_H_
+
+#define IMMU_NUM_WINDOWS 2
+#define IMMU_WINDOW_SIZE 0x100000
+#define IMMU_RANGE_START 0x32000000
+#define DMMU_NUM_WINDOWS 4
+#define DMMU_WINDOW_SIZE 0x400000
+#define DMMU_RANGE_START 0x34000000
+
+#endif
diff --git a/faults/write_past_data_window.c b/faults/write_past_data_window.c
new file mode 100644
index 0000000..b143126
--- /dev/null
+++ b/faults/write_past_data_window.c
@@ -0,0 +1,10 @@
+#include "layout.h"
+
+// TODO(jesionowski): This program won't work until we change the way the DMEM
+// is allocated: currently the remaning memory after data is consumed by .heap.
+
+int main() {
+  int* i = (int*)(DMMU_RANGE_START + 0x4000 - sizeof(int));
+  *i = 0;
+  return 0;
+}