90 lines
2.1 KiB
Rust
90 lines
2.1 KiB
Rust
use core::ops::{Deref, DerefMut};
|
|
|
|
use device_api::interrupt::IpiMessage;
|
|
use kernel_arch::{Architecture, ArchitectureImpl, CpuImpl, LocalCpuImpl};
|
|
use libk_util::sync::IrqGuard;
|
|
|
|
use crate::task::sched::CpuQueue;
|
|
|
|
/// Kernel wrapper for local CPU info structure. See [kernel_arch::LocalCpuImpl].
|
|
#[repr(transparent)]
|
|
pub struct LocalCpu<'a>(LocalCpuImpl<'a, CpuQueue>);
|
|
/// Kernel wrapper for per-CPU info structure. See [kernel_arch::LocalCpuImpl].
|
|
#[repr(transparent)]
|
|
pub struct Cpu(CpuImpl<CpuQueue>);
|
|
|
|
impl Cpu {
|
|
/// # Safety
|
|
///
|
|
/// Precondition: this function has not yet been called on the local CPU.
|
|
pub unsafe fn init_local(
|
|
id: Option<u32>,
|
|
data: <ArchitectureImpl as Architecture>::PerCpuData,
|
|
) {
|
|
ArchitectureImpl::init_local_cpu::<CpuQueue>(id, data)
|
|
}
|
|
|
|
/// Returns local CPU reference
|
|
#[inline]
|
|
pub fn local<'a>() -> LocalCpu<'a> {
|
|
LocalCpu(CpuImpl::local())
|
|
}
|
|
|
|
/// Returns local CPU reference or None if it hasn't yet been initialized
|
|
#[inline]
|
|
pub fn try_local<'a>() -> Option<LocalCpu<'a>> {
|
|
CpuImpl::try_local().map(LocalCpu)
|
|
}
|
|
|
|
/// Pushes a message to the IPI queue
|
|
#[inline]
|
|
pub fn push_ipi_queue(cpu_id: u32, msg: IpiMessage) {
|
|
CpuImpl::<CpuQueue>::push_ipi_queue(cpu_id, msg)
|
|
}
|
|
|
|
/// Initialize the IPI queues for all present CPUs
|
|
#[inline]
|
|
pub fn init_ipi_queues(cpu_count: usize) {
|
|
CpuImpl::<CpuQueue>::init_ipi_queues(cpu_count)
|
|
}
|
|
}
|
|
|
|
impl Deref for Cpu {
|
|
type Target = CpuImpl<CpuQueue>;
|
|
|
|
#[inline]
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl DerefMut for Cpu {
|
|
#[inline]
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.0
|
|
}
|
|
}
|
|
|
|
impl LocalCpu<'_> {
|
|
/// Converts the local CPU handle into its IRQ guard
|
|
pub fn into_guard(self) -> IrqGuard {
|
|
self.0.into_guard()
|
|
}
|
|
}
|
|
|
|
impl Deref for LocalCpu<'_> {
|
|
type Target = CpuImpl<CpuQueue>;
|
|
|
|
#[inline]
|
|
fn deref(&self) -> &Self::Target {
|
|
self.0.deref()
|
|
}
|
|
}
|
|
|
|
impl DerefMut for LocalCpu<'_> {
|
|
#[inline]
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
self.0.deref_mut()
|
|
}
|
|
}
|