/* * Copyright (c) 2023, Sönke Holz * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include VALIDATE_IS_RISCV64() namespace Kernel { namespace Memory { class PageDirectory; }; class Thread; class Processor; struct TrapFrame; enum class InterruptsState; template class ProcessorBase; // FIXME: Remove this once we support SMP in riscv64 extern Processor* g_current_processor; constexpr size_t MAX_CPU_COUNT = 1; class Processor final : public ProcessorBase { public: template Callback> static inline IterationDecision for_each(Callback callback) { // FIXME: Once we support SMP for riscv64, make sure to call the callback for every processor. if (callback(*g_current_processor) == IterationDecision::Break) return IterationDecision::Break; return IterationDecision::Continue; } template Callback> static inline IterationDecision for_each(Callback callback) { // FIXME: Once we support SMP for riscv64, make sure to call the callback for every processor. callback(*g_current_processor); return IterationDecision::Continue; } }; template ALWAYS_INLINE bool ProcessorBase::is_initialized() { return g_current_processor != nullptr; } template ALWAYS_INLINE Thread* ProcessorBase::idle_thread() { return current().m_idle_thread; } template ALWAYS_INLINE void ProcessorBase::set_current_thread(Thread& current_thread) { current().m_current_thread = ¤t_thread; } // FIXME: When riscv64 supports multiple cores, return the correct core id here. template ALWAYS_INLINE u32 ProcessorBase::current_id() { return 0; } template ALWAYS_INLINE u32 ProcessorBase::in_critical() { return current().m_in_critical; } template ALWAYS_INLINE void ProcessorBase::enter_critical() { auto& current_processor = current(); current_processor.m_in_critical += 1; } template ALWAYS_INLINE void ProcessorBase::restore_critical(u32 prev_critical) { current().m_in_critical = prev_critical; } template ALWAYS_INLINE T& ProcessorBase::current() { return *g_current_processor; } template void ProcessorBase::idle_begin() const { // FIXME: Implement this when SMP for riscv64 is supported. } template void ProcessorBase::idle_end() const { // FIXME: Implement this when SMP for riscv64 is supported. } template void ProcessorBase::smp_enable() { // FIXME: Implement this when SMP for riscv64 is supported. } template bool ProcessorBase::is_smp_enabled() { return false; } template ALWAYS_INLINE bool ProcessorBase::are_interrupts_enabled() { return RISCV64::CSR::SSTATUS::read().SIE == 1; } template ALWAYS_INLINE void ProcessorBase::enable_interrupts() { RISCV64::CSR::set_bits(RISCV64::CSR::Address::SSTATUS, 1 << to_underlying(RISCV64::CSR::SSTATUS::Offset::SIE)); } template ALWAYS_INLINE void ProcessorBase::disable_interrupts() { RISCV64::CSR::clear_bits(RISCV64::CSR::Address::SSTATUS, 1 << to_underlying(RISCV64::CSR::SSTATUS::Offset::SIE)); } template ALWAYS_INLINE bool ProcessorBase::is_kernel_mode() { // FIXME: Implement this correctly. return true; } template ALWAYS_INLINE bool ProcessorBase::current_in_scheduler() { return current().m_in_scheduler; } template ALWAYS_INLINE void ProcessorBase::set_current_in_scheduler(bool value) { current().m_in_scheduler = value; } template ALWAYS_INLINE bool ProcessorBase::has_nx() const { return true; } template ALWAYS_INLINE bool ProcessorBase::has_pat() const { return false; } template ALWAYS_INLINE FlatPtr ProcessorBase::current_in_irq() { return current().m_in_irq; } template ALWAYS_INLINE Thread* ProcessorBase::current_thread() { return current().m_current_thread; } template ALWAYS_INLINE void ProcessorBase::pause() { TODO_RISCV64(); } template ALWAYS_INLINE void ProcessorBase::wait_check() { Processor::pause(); // FIXME: Process SMP messages once we support SMP on riscv64; cf. x86_64 } template ALWAYS_INLINE u64 ProcessorBase::read_cpu_counter() { TODO_RISCV64(); } }