/* * Copyright (c) 2018-2021, James Mintram * Copyright (c) 2022, Timon Kruiper * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include VALIDATE_IS_AARCH64() 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 aarch64 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 aarch64, 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 aarch64, 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 aarch64 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 = 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 aarch64 is supported. } template void ProcessorBase::idle_end() const { // FIXME: Implement this when SMP for aarch64 is supported. } template void ProcessorBase::smp_enable() { // FIXME: Implement this when SMP for aarch64 is supported. } template bool ProcessorBase::is_smp_enabled() { return false; } template ALWAYS_INLINE bool ProcessorBase::are_interrupts_enabled() { auto daif = Aarch64::DAIF::read(); return !daif.I; } template ALWAYS_INLINE void ProcessorBase::enable_interrupts() { Aarch64::DAIF::clear_I(); } template ALWAYS_INLINE void ProcessorBase::disable_interrupts() { Aarch64::DAIF::set_I(); } 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() { asm volatile("isb sy"); } template ALWAYS_INLINE void ProcessorBase::wait_check() { asm volatile("yield"); // FIXME: Process SMP messages once we support SMP on aarch64; cf. x86_64 } template ALWAYS_INLINE u64 ProcessorBase::read_cpu_counter() { TODO_AARCH64(); return 0; } }