summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.S14
-rw-r--r--Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.h1
-rw-r--r--Kernel/Prekernel/Arch/aarch64/init.cpp8
-rw-r--r--Kernel/Prekernel/Arch/aarch64/vector_table.S63
-rw-r--r--Kernel/Prekernel/CMakeLists.txt1
5 files changed, 87 insertions, 0 deletions
diff --git a/Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.S b/Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.S
index 026d5c625f..33f2d4de7f 100644
--- a/Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.S
+++ b/Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.S
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2021, Nico Weber <thakis@chromium.org>
* Copyright (c) 2021, Marcin Undak <mcinek@gmail.com>
+ * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -32,3 +33,16 @@ enter_el1_from_el2:
eret
entered_el1:
ret
+
+//
+// Installs the EL1 vector table
+// Args:
+// x0 - Address of vector table
+//
+// This function doesn't return a value
+//
+.global el1_vector_table_install
+.type el1_vector_table_install, @function
+el1_vector_table_install:
+ msr VBAR_EL1, x0
+ ret
diff --git a/Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.h b/Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.h
index 5bae046bfe..5536904b2b 100644
--- a/Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.h
+++ b/Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.h
@@ -7,6 +7,7 @@
#pragma once
extern "C" void wait_cycles(int n);
+extern "C" void el1_vector_table_install(void* vector_table);
// CPU initialization functions
extern "C" [[noreturn]] void return_from_el2();
diff --git a/Kernel/Prekernel/Arch/aarch64/init.cpp b/Kernel/Prekernel/Arch/aarch64/init.cpp
index 6d2d91a481..e031e57c3c 100644
--- a/Kernel/Prekernel/Arch/aarch64/init.cpp
+++ b/Kernel/Prekernel/Arch/aarch64/init.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2021, Nico Weber <thakis@chromium.org>
* Copyright (c) 2021, Marcin Undak <mcinek@gmail.com>
+ * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -45,6 +46,13 @@ extern "C" [[noreturn]] void init()
uart.print_str("Drop CPU to EL1\r\n");
Prekernel::drop_to_exception_level_1();
+ // Load EL1 vector table
+ extern uintptr_t vector_table_el1;
+ el1_vector_table_install(&vector_table_el1);
+
+ // Set the register
+ asm("msr sctlr_el1, %[value]" ::[value] "r"(system_control_register_el1));
+
uart.print_str("Initialize MMU\r\n");
Prekernel::init_prekernel_page_tables();
diff --git a/Kernel/Prekernel/Arch/aarch64/vector_table.S b/Kernel/Prekernel/Arch/aarch64/vector_table.S
new file mode 100644
index 0000000000..92886818d8
--- /dev/null
+++ b/Kernel/Prekernel/Arch/aarch64/vector_table.S
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+.section .text.vector_table
+
+// Vector Table Entry macro. Each entry is aligned at 128 bytes, meaning we have
+// at most that many instructions.
+.macro table_entry label
+ .align 7
+ b \label
+.endm
+
+.macro unimplemented_entry
+ .align 7
+ wfe
+ b .
+.endm
+
+.global vector_table_el1
+.weak vector_table_el1 // Vector table is weak in case someone wants to hook us in C++ land :^)
+.type vector_table_el1, @object
+
+// Vector table is 2KiB aligned (2^11)
+.align 11
+vector_table_el1:
+ // Exceptions taken from Current EL, with SP_EL0
+ unimplemented_entry
+ unimplemented_entry
+ unimplemented_entry
+ unimplemented_entry
+
+ // Exceptions taken from Current EL, with SP_ELx, x>0
+ table_entry synchronous_current_elsp_elx
+ table_entry irq_current_elsp_elx
+ table_entry fiq_current_elsp_elx
+ table_entry system_error_current_elsp_elx
+
+ // Exceptions from Lower EL, where causing application is in AArch64 mode
+ unimplemented_entry
+ unimplemented_entry
+ unimplemented_entry
+ unimplemented_entry
+
+ // Exceptions from Lower EL, where causing application is in AArch32 mode
+ unimplemented_entry
+ unimplemented_entry
+ unimplemented_entry
+ unimplemented_entry
+
+synchronous_current_elsp_elx:
+ b .
+
+irq_current_elsp_elx:
+ b .
+
+fiq_current_elsp_elx:
+ b .
+
+system_error_current_elsp_elx:
+ b .
diff --git a/Kernel/Prekernel/CMakeLists.txt b/Kernel/Prekernel/CMakeLists.txt
index dbf1d8be8f..5b3e1d3528 100644
--- a/Kernel/Prekernel/CMakeLists.txt
+++ b/Kernel/Prekernel/CMakeLists.txt
@@ -24,6 +24,7 @@ if ("${SERENITY_ARCH}" STREQUAL "aarch64")
# Assembly
Arch/aarch64/boot.S
Arch/aarch64/Aarch64_asm_utils.S
+ Arch/aarch64/vector_table.S
)
else()
set(SOURCES