summaryrefslogtreecommitdiff
path: root/Kernel/Prekernel
diff options
context:
space:
mode:
authorJesse Buhagiar <jooster669@gmail.com>2021-10-13 22:19:49 +1100
committerBrian Gianforcaro <b.gianfo@gmail.com>2022-01-24 06:57:59 +0000
commit547322fb9507a4f8954db20bca4b0b2ce3f7e7ad (patch)
tree218f354ae94f0e98329a1eb44d551297f486499f /Kernel/Prekernel
parent28e36a70d6e13dab13cc45f7e352f9c2d29929e9 (diff)
downloadserenity-547322fb9507a4f8954db20bca4b0b2ce3f7e7ad.zip
Prekernel: Install EL1 vector table at boot on aarch64
We now have a function to install a (currently default) vector table, meaning that any exceptions (or interrupts for that matter) will be caught by the processor and routed to one of the vectors inside the table.
Diffstat (limited to 'Kernel/Prekernel')
-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