diff options
author | Jesse Buhagiar <jooster669@gmail.com> | 2021-10-13 22:19:49 +1100 |
---|---|---|
committer | Brian Gianforcaro <b.gianfo@gmail.com> | 2022-01-24 06:57:59 +0000 |
commit | 547322fb9507a4f8954db20bca4b0b2ce3f7e7ad (patch) | |
tree | 218f354ae94f0e98329a1eb44d551297f486499f /Kernel/Prekernel | |
parent | 28e36a70d6e13dab13cc45f7e352f9c2d29929e9 (diff) | |
download | serenity-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.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 |