diff --git a/Kernel/Arch/init.cpp b/Kernel/Arch/init.cpp index 5068370f38e..2317b4c6ad8 100644 --- a/Kernel/Arch/init.cpp +++ b/Kernel/Arch/init.cpp @@ -68,6 +68,8 @@ # include # include # include +#elif ARCH(RISCV64) +# include #endif // Defined in the linker script @@ -295,6 +297,8 @@ extern "C" [[noreturn]] UNMAP_AFTER_INIT void init([[maybe_unused]] BootInfo con if (kernel_command_line().contains("dump_fdt"sv)) dump_fdt(); + + init_delay_loop(); #endif // Initialize TimeManagement before using randomness! diff --git a/Kernel/Arch/riscv64/Delay.cpp b/Kernel/Arch/riscv64/Delay.cpp index 1afbbd87e81..b40d94fe187 100644 --- a/Kernel/Arch/riscv64/Delay.cpp +++ b/Kernel/Arch/riscv64/Delay.cpp @@ -5,13 +5,29 @@ */ #include -#include +#include +#include +#include +#include namespace Kernel { -void microseconds_delay(u32) +static u32 s_timebase_frequency = 0; + +void microseconds_delay(u32 microseconds) { - TODO_RISCV64(); + VERIFY(s_timebase_frequency != 0); + + u64 const start = RISCV64::CSR::read(RISCV64::CSR::Address::TIME); + u64 const delta = (static_cast(microseconds) * s_timebase_frequency) / 1'000'000ull; + + while ((RISCV64::CSR::read(RISCV64::CSR::Address::TIME) - start) < delta) + Processor::pause(); +} + +void init_delay_loop() +{ + s_timebase_frequency = DeviceTree::get().resolve_property("/cpus/timebase-frequency"sv).value().as(); } } diff --git a/Kernel/Arch/riscv64/Delay.h b/Kernel/Arch/riscv64/Delay.h new file mode 100644 index 00000000000..e96dcbce7a6 --- /dev/null +++ b/Kernel/Arch/riscv64/Delay.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2024, Sönke Holz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Kernel { + +void init_delay_loop(); + +}