mirror of
https://github.com/RGBCube/serenity
synced 2025-07-09 04:07:35 +00:00

About half of the Processor code is common across architectures, so let's share it with a templated base class. Also, other code that can be shared in some ways, like FPUState and TrapFrame functions, is adjusted here. Functions which cannot be shared trivially (without internal refactoring) are left alone for now.
219 lines
4.7 KiB
C++
219 lines
4.7 KiB
C++
/*
|
|
* Copyright (c) 2018-2021, James Mintram <me@jamesrm.com>
|
|
* Copyright (c) 2022, Timon Kruiper <timonkruiper@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/Concepts.h>
|
|
#include <AK/Function.h>
|
|
#include <AK/Types.h>
|
|
|
|
#include <Kernel/Arch/DeferredCallEntry.h>
|
|
#include <Kernel/Arch/DeferredCallPool.h>
|
|
#include <Kernel/Arch/ProcessorSpecificDataID.h>
|
|
#include <Kernel/Arch/aarch64/CPUID.h>
|
|
#include <Kernel/Arch/aarch64/Registers.h>
|
|
#include <Kernel/Memory/VirtualAddress.h>
|
|
|
|
#include <AK/Platform.h>
|
|
VALIDATE_IS_AARCH64()
|
|
|
|
namespace Kernel {
|
|
|
|
namespace Memory {
|
|
class PageDirectory;
|
|
};
|
|
|
|
class Thread;
|
|
class Processor;
|
|
struct TrapFrame;
|
|
enum class InterruptsState;
|
|
|
|
template<typename ProcessorT>
|
|
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<Processor> {
|
|
public:
|
|
template<IteratorFunction<Processor&> 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<VoidFunction<Processor&> 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<typename T>
|
|
ALWAYS_INLINE bool ProcessorBase<T>::is_initialized()
|
|
{
|
|
return g_current_processor != nullptr;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE Thread* ProcessorBase<T>::idle_thread()
|
|
{
|
|
return current().m_idle_thread;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE void ProcessorBase<T>::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<typename T>
|
|
ALWAYS_INLINE u32 ProcessorBase<T>::current_id()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE u32 ProcessorBase<T>::in_critical()
|
|
{
|
|
return current().m_in_critical;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE void ProcessorBase<T>::enter_critical()
|
|
{
|
|
auto& current_processor = current();
|
|
current_processor.m_in_critical = current_processor.m_in_critical + 1;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE void ProcessorBase<T>::restore_critical(u32 prev_critical)
|
|
{
|
|
current().m_in_critical = prev_critical;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE T& ProcessorBase<T>::current()
|
|
{
|
|
return *g_current_processor;
|
|
}
|
|
|
|
template<typename T>
|
|
void ProcessorBase<T>::idle_begin() const
|
|
{
|
|
// FIXME: Implement this when SMP for aarch64 is supported.
|
|
}
|
|
|
|
template<typename T>
|
|
void ProcessorBase<T>::idle_end() const
|
|
{
|
|
// FIXME: Implement this when SMP for aarch64 is supported.
|
|
}
|
|
|
|
template<typename T>
|
|
void ProcessorBase<T>::smp_enable()
|
|
{
|
|
// FIXME: Implement this when SMP for aarch64 is supported.
|
|
}
|
|
|
|
template<typename T>
|
|
bool ProcessorBase<T>::is_smp_enabled()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE bool ProcessorBase<T>::are_interrupts_enabled()
|
|
{
|
|
auto daif = Aarch64::DAIF::read();
|
|
return !daif.I;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE void ProcessorBase<T>::enable_interrupts()
|
|
{
|
|
Aarch64::DAIF::clear_I();
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE void ProcessorBase<T>::disable_interrupts()
|
|
{
|
|
Aarch64::DAIF::set_I();
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE bool ProcessorBase<T>::is_kernel_mode()
|
|
{
|
|
// FIXME: Implement this correctly.
|
|
return true;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE bool ProcessorBase<T>::current_in_scheduler()
|
|
{
|
|
return current().m_in_scheduler;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE void ProcessorBase<T>::set_current_in_scheduler(bool value)
|
|
{
|
|
current().m_in_scheduler = value;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE bool ProcessorBase<T>::has_nx() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE bool ProcessorBase<T>::has_pat() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE FlatPtr ProcessorBase<T>::current_in_irq()
|
|
{
|
|
return current().m_in_irq;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE Thread* ProcessorBase<T>::current_thread()
|
|
{
|
|
return current().m_current_thread;
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE void ProcessorBase<T>::pause()
|
|
{
|
|
asm volatile("isb sy");
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE void ProcessorBase<T>::wait_check()
|
|
{
|
|
asm volatile("yield");
|
|
// FIXME: Process SMP messages once we support SMP on aarch64; cf. x86_64
|
|
}
|
|
|
|
template<typename T>
|
|
ALWAYS_INLINE u64 ProcessorBase<T>::read_cpu_counter()
|
|
{
|
|
TODO_AARCH64();
|
|
return 0;
|
|
}
|
|
|
|
}
|