mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-24 09:03:23 +00:00
新的ipi功能&kick_cpu功能的重写 (#274)
This commit is contained in:
127
kernel/src/arch/x86_64/interrupt/ipi.rs
Normal file
127
kernel/src/arch/x86_64/interrupt/ipi.rs
Normal file
@ -0,0 +1,127 @@
|
||||
use crate::exception::ipi::{IpiKind, IpiTarget};
|
||||
|
||||
extern "C" {
|
||||
pub fn apic_write_icr(value: u64);
|
||||
pub fn apic_x2apic_enabled() -> bool;
|
||||
}
|
||||
|
||||
/// IPI的种类(架构相关,指定了向量号)
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum ArchIpiKind {
|
||||
KickCpu = 200,
|
||||
FlushTLB = 201,
|
||||
}
|
||||
|
||||
impl From<IpiKind> for ArchIpiKind {
|
||||
fn from(kind: IpiKind) -> Self {
|
||||
match kind {
|
||||
IpiKind::KickCpu => ArchIpiKind::KickCpu,
|
||||
IpiKind::FlushTLB => ArchIpiKind::FlushTLB,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// IPI投递目标
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum ArchIpiTarget {
|
||||
/// 当前CPU
|
||||
Current,
|
||||
/// 所有CPU
|
||||
All,
|
||||
/// 除了当前CPU以外的所有CPU
|
||||
Other,
|
||||
/// 指定的CPU
|
||||
Specified(usize),
|
||||
}
|
||||
|
||||
impl From<IpiTarget> for ArchIpiTarget {
|
||||
fn from(target: IpiTarget) -> Self {
|
||||
match target {
|
||||
IpiTarget::Current => ArchIpiTarget::Current,
|
||||
IpiTarget::All => ArchIpiTarget::All,
|
||||
IpiTarget::Other => ArchIpiTarget::Other,
|
||||
IpiTarget::Specified(cpu_id) => ArchIpiTarget::Specified(cpu_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ArchIpiTarget {
|
||||
pub fn shorthand(&self) -> u8 {
|
||||
match self {
|
||||
ArchIpiTarget::Specified(_) => 0,
|
||||
ArchIpiTarget::Current => 1,
|
||||
ArchIpiTarget::All => 2,
|
||||
ArchIpiTarget::Other => 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<x86::apic::DestinationShorthand> for ArchIpiTarget {
|
||||
fn into(self) -> x86::apic::DestinationShorthand {
|
||||
match self {
|
||||
ArchIpiTarget::Specified(_) => x86::apic::DestinationShorthand::NoShorthand,
|
||||
ArchIpiTarget::Current => x86::apic::DestinationShorthand::Myself,
|
||||
ArchIpiTarget::All => x86::apic::DestinationShorthand::AllIncludingSelf,
|
||||
ArchIpiTarget::Other => x86::apic::DestinationShorthand::AllExcludingSelf,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<x86::apic::ApicId> for ArchIpiTarget {
|
||||
fn into(self) -> x86::apic::ApicId {
|
||||
let id = match self {
|
||||
ArchIpiTarget::Specified(cpu_id) => cpu_id,
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
if unsafe { apic_x2apic_enabled() } {
|
||||
return x86::apic::ApicId::X2Apic(id as u32);
|
||||
} else {
|
||||
return x86::apic::ApicId::XApic(id as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
|
||||
// kdebug!("send_ipi: {:?} {:?}", kind, target);
|
||||
|
||||
let ipi_vec = ArchIpiKind::from(kind) as u8;
|
||||
let target = ArchIpiTarget::from(target);
|
||||
let shorthand: x86::apic::DestinationShorthand = target.into();
|
||||
let destination: x86::apic::ApicId = target.into();
|
||||
if unsafe { apic_x2apic_enabled() } {
|
||||
// kdebug!("send_ipi: x2apic");
|
||||
let icr = x86::apic::Icr::for_x2apic(
|
||||
ipi_vec,
|
||||
destination,
|
||||
shorthand,
|
||||
x86::apic::DeliveryMode::Fixed,
|
||||
x86::apic::DestinationMode::Physical,
|
||||
x86::apic::DeliveryStatus::Idle,
|
||||
x86::apic::Level::Assert,
|
||||
x86::apic::TriggerMode::Edge,
|
||||
);
|
||||
|
||||
unsafe {
|
||||
apic_write_icr(((icr.upper() as u64) << 32) | icr.lower() as u64);
|
||||
}
|
||||
} else {
|
||||
// kdebug!("send_ipi: xapic");
|
||||
let icr = x86::apic::Icr::for_xapic(
|
||||
ipi_vec,
|
||||
destination,
|
||||
shorthand,
|
||||
x86::apic::DeliveryMode::Fixed,
|
||||
x86::apic::DestinationMode::Physical,
|
||||
x86::apic::DeliveryStatus::Idle,
|
||||
x86::apic::Level::Assert,
|
||||
x86::apic::TriggerMode::Edge,
|
||||
);
|
||||
|
||||
unsafe {
|
||||
apic_write_icr(((icr.upper() as u64) << 32) | icr.lower() as u64);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,7 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub mod ipi;
|
||||
|
||||
use core::{
|
||||
arch::asm,
|
||||
sync::atomic::{compiler_fence, Ordering},
|
||||
|
Reference in New Issue
Block a user