From e7c5fd978b7af3a94eafaec0d4160e0218f0ab69 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Mon, 9 May 2022 23:09:44 +0200 Subject: [PATCH] Kernel: Move Prekernel assembly utils to aarch64/ASM_wrapper.h By moving these functions to the ASM_wrapper.h file, we can get rid of another Prekernel file. --- Kernel/Arch/aarch64/ASM_wrapper.h | 37 ++++++++++++++ .../aarch64/Prekernel/Aarch64_asm_utils.S | 48 ------------------- .../aarch64/Prekernel/Aarch64_asm_utils.h | 14 ------ .../aarch64/Prekernel/PrekernelExceptions.cpp | 9 ++-- Kernel/Arch/aarch64/Processor.cpp | 3 +- Kernel/Arch/aarch64/RPi/GPIO.cpp | 7 ++- Kernel/Arch/aarch64/init.cpp | 2 - Kernel/CMakeLists.txt | 1 - 8 files changed, 44 insertions(+), 77 deletions(-) delete mode 100644 Kernel/Arch/aarch64/Prekernel/Aarch64_asm_utils.S delete mode 100644 Kernel/Arch/aarch64/Prekernel/Aarch64_asm_utils.h diff --git a/Kernel/Arch/aarch64/ASM_wrapper.h b/Kernel/Arch/aarch64/ASM_wrapper.h index b4d530ec3e..580f9ad016 100644 --- a/Kernel/Arch/aarch64/ASM_wrapper.h +++ b/Kernel/Arch/aarch64/ASM_wrapper.h @@ -1,5 +1,8 @@ /* * Copyright (c) 2021, James Mintram + * Copyright (c) 2021, Nico Weber + * Copyright (c) 2021, Marcin Undak + * Copyright (c) 2021, Jesse Buhagiar * * SPDX-License-Identifier: BSD-2-Clause */ @@ -51,4 +54,38 @@ inline ExceptionLevel get_current_exception_level() return static_cast(current_exception_level); } +inline void wait_cycles(int n) +{ + // This is probably too fast when caching and branch prediction is turned on. + // FIXME: Make timer-based. + asm("mov x0, %[value]\n" + "0:\n" + " subs x0, x0, #1\n" + " bne 0b" ::[value] "r"(n) + : "x0"); +} + +inline void el1_vector_table_install(void* vector_table) +{ + asm("msr VBAR_EL1, %[value]" ::[value] "r"(vector_table)); +} + +inline void enter_el2_from_el3() +{ + asm volatile(" adr x0, entered_el2\n" + " msr elr_el3, x0\n" + " eret\n" + "entered_el2:" :: + : "x0"); +} + +inline void enter_el1_from_el2() +{ + asm volatile(" adr x0, entered_el1\n" + " msr elr_el2, x0\n" + " eret\n" + "entered_el1:" :: + : "x0"); +} + } diff --git a/Kernel/Arch/aarch64/Prekernel/Aarch64_asm_utils.S b/Kernel/Arch/aarch64/Prekernel/Aarch64_asm_utils.S deleted file mode 100644 index 33f2d4de7f..0000000000 --- a/Kernel/Arch/aarch64/Prekernel/Aarch64_asm_utils.S +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2021, Nico Weber - * Copyright (c) 2021, Marcin Undak - * Copyright (c) 2021, Jesse Buhagiar - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -.global wait_cycles -.type wait_cycles, @function -wait_cycles: -Lstart: - // This is probably too fast when caching and branch prediction is turned on. - // FIXME: Make timer-based. - subs x0, x0, #1 - bne Lstart - ret - -.global enter_el2_from_el3 -.type enter_el2_from_el3, @function -enter_el2_from_el3: - adr x0, entered_el2 - msr elr_el3, x0 - eret -entered_el2: - ret - -.global enter_el1_from_el2 -.type enter_el1_from_el2, @function -enter_el1_from_el2: - adr x0, entered_el1 - msr elr_el2, x0 - 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/Arch/aarch64/Prekernel/Aarch64_asm_utils.h b/Kernel/Arch/aarch64/Prekernel/Aarch64_asm_utils.h deleted file mode 100644 index 5536904b2b..0000000000 --- a/Kernel/Arch/aarch64/Prekernel/Aarch64_asm_utils.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2021, Marcin Undak - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#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(); -extern "C" [[noreturn]] void return_from_el3(); diff --git a/Kernel/Arch/aarch64/Prekernel/PrekernelExceptions.cpp b/Kernel/Arch/aarch64/Prekernel/PrekernelExceptions.cpp index e8b7d0e702..61c394fda0 100644 --- a/Kernel/Arch/aarch64/Prekernel/PrekernelExceptions.cpp +++ b/Kernel/Arch/aarch64/Prekernel/PrekernelExceptions.cpp @@ -5,14 +5,10 @@ */ #include -#include #include #include #include -extern "C" void enter_el2_from_el3(); -extern "C" void enter_el1_from_el2(); - using namespace Kernel; namespace Prekernel { @@ -43,8 +39,9 @@ static void drop_to_el2() Aarch64::SPSR_EL3::write(saved_program_status_register_el3); // This will jump into os_start() below - enter_el2_from_el3(); + Aarch64::Asm::enter_el2_from_el3(); } + static void drop_to_el1() { Aarch64::HCR_EL2 hypervisor_configuration_register_el2 = {}; @@ -62,7 +59,7 @@ static void drop_to_el1() saved_program_status_register_el2.M = Aarch64::SPSR_EL2::Mode::EL1t; Aarch64::SPSR_EL2::write(saved_program_status_register_el2); - enter_el1_from_el2(); + Aarch64::Asm::enter_el1_from_el2(); } static void set_up_el1() diff --git a/Kernel/Arch/aarch64/Processor.cpp b/Kernel/Arch/aarch64/Processor.cpp index 85d15037f9..36a3df87d7 100644 --- a/Kernel/Arch/aarch64/Processor.cpp +++ b/Kernel/Arch/aarch64/Processor.cpp @@ -8,7 +8,6 @@ #include #include -#include #include extern "C" uintptr_t vector_table_el1; @@ -28,7 +27,7 @@ void Processor::initialize(u32 cpu) Prekernel::drop_to_exception_level_1(); // Load EL1 vector table - el1_vector_table_install(&vector_table_el1); + Kernel::Aarch64::Asm::el1_vector_table_install(&vector_table_el1); g_current_processor = this; } diff --git a/Kernel/Arch/aarch64/RPi/GPIO.cpp b/Kernel/Arch/aarch64/RPi/GPIO.cpp index fec673aca3..23b47e5898 100644 --- a/Kernel/Arch/aarch64/RPi/GPIO.cpp +++ b/Kernel/Arch/aarch64/RPi/GPIO.cpp @@ -4,11 +4,10 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include -extern "C" void wait_cycles(int n); - namespace Prekernel { // See BCM2835-ARM-Peripherals.pdf section "6 General Purpose I/O" or bcm2711-peripherals.pdf "Chapter 5. General Purpose I/O". @@ -73,7 +72,7 @@ void GPIO::internal_enable_pins(u32 enable[2], PullUpDownState state) m_registers->pull_up_down_enable = static_cast(state); // 2. Wait 150 cycles – this provides the required set-up time for the control signal - wait_cycles(150); + Kernel::Aarch64::Asm::wait_cycles(150); // 3. Write to GPPUDCLK0/1 to clock the control signal into the GPIO pads you wish to // modify – NOTE only the pads which receive a clock will be modified, all others will @@ -82,7 +81,7 @@ void GPIO::internal_enable_pins(u32 enable[2], PullUpDownState state) m_registers->pull_up_down_enable_clock.bits[1] = enable[1]; // 4. Wait 150 cycles – this provides the required hold time for the control signal - wait_cycles(150); + Kernel::Aarch64::Asm::wait_cycles(150); // 5. Write to GPPUD to remove the control signal m_registers->pull_up_down_enable = 0; diff --git a/Kernel/Arch/aarch64/init.cpp b/Kernel/Arch/aarch64/init.cpp index 9049ac3b37..3d01268af3 100644 --- a/Kernel/Arch/aarch64/init.cpp +++ b/Kernel/Arch/aarch64/init.cpp @@ -23,8 +23,6 @@ static void draw_logo(); static u32 query_firmware_version(); -extern "C" void wait_cycles(int n); - struct TrapFrame { u64 x[31]; // Saved general purpose registers u64 spsr_el1; // Save Processor Status Register, EL1 diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 4a5d5720f8..f7429cc5d1 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -398,7 +398,6 @@ if (NOT "${SERENITY_ARCH}" STREQUAL "aarch64") ) else() set(PREKERNEL_SOURCES - Arch/aarch64/Prekernel/Aarch64_asm_utils.S Arch/aarch64/Prekernel/boot.S Arch/aarch64/Prekernel/PrekernelExceptions.cpp Arch/aarch64/Prekernel/PrekernelMMU.cpp