diff options
-rw-r--r-- | Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.S | 14 | ||||
-rw-r--r-- | Kernel/Prekernel/Arch/aarch64/Aarch64_asm_utils.h | 1 | ||||
-rw-r--r-- | Kernel/Prekernel/Arch/aarch64/init.cpp | 8 | ||||
-rw-r--r-- | Kernel/Prekernel/Arch/aarch64/vector_table.S | 63 | ||||
-rw-r--r-- | Kernel/Prekernel/CMakeLists.txt | 1 |
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 |