mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 19:36:47 +00:00
新的ipi功能&kick_cpu功能的重写 (#274)
This commit is contained in:
parent
bb24249faa
commit
aa0367d69e
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)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
pub mod ipi;
|
||||||
|
|
||||||
use core::{
|
use core::{
|
||||||
arch::asm,
|
arch::asm,
|
||||||
sync::atomic::{compiler_fence, Ordering},
|
sync::atomic::{compiler_fence, Ordering},
|
||||||
|
@ -9,10 +9,7 @@ use crate::{
|
|||||||
syscall::{Syscall, SystemError, SYS_EXECVE, SYS_FORK, SYS_RT_SIGRETURN, SYS_VFORK},
|
syscall::{Syscall, SystemError, SYS_EXECVE, SYS_FORK, SYS_RT_SIGRETURN, SYS_VFORK},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{asm::ptrace::user_mode, mm::barrier::mfence};
|
||||||
asm::{ptrace::user_mode},
|
|
||||||
mm::barrier::mfence,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn do_fork(regs: *mut pt_regs, clone_flags: u64, stack_start: u64, stack_size: u64) -> u64;
|
fn do_fork(regs: *mut pt_regs, clone_flags: u64, stack_start: u64, stack_size: u64) -> u64;
|
||||||
|
@ -147,6 +147,9 @@ void apic_init_ap_core_local_apic()
|
|||||||
__local_apic_x2apic_init();
|
__local_apic_x2apic_init();
|
||||||
else // 当前为xapic
|
else // 当前为xapic
|
||||||
__local_apic_xapic_init();
|
__local_apic_xapic_init();
|
||||||
|
barrier();
|
||||||
|
kdebug("AP-core's local apic initialized.");
|
||||||
|
barrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -160,15 +163,15 @@ static void __local_apic_xapic_init()
|
|||||||
uint64_t qword = *(uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR);
|
uint64_t qword = *(uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR);
|
||||||
|
|
||||||
qword |= (1 << 8);
|
qword |= (1 << 8);
|
||||||
*(uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR) = qword;
|
*(volatile uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR) = qword;
|
||||||
qword = *(uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR);
|
qword = *(volatile uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR);
|
||||||
if (qword & 0x100)
|
if (qword & 0x100)
|
||||||
kinfo("APIC Software Enabled.");
|
kinfo("APIC Software Enabled.");
|
||||||
if (qword & 0x1000)
|
if (qword & 0x1000)
|
||||||
kinfo("EOI-Broadcast Suppression Enabled.");
|
kinfo("EOI-Broadcast Suppression Enabled.");
|
||||||
|
barrier();
|
||||||
// 从 Local APIC Version register 获取Local APIC Version
|
// 从 Local APIC Version register 获取Local APIC Version
|
||||||
qword = *(uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_Version);
|
qword = *(volatile uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_Version);
|
||||||
qword &= 0xffffffff;
|
qword &= 0xffffffff;
|
||||||
|
|
||||||
local_apic_max_LVT_entries = ((qword >> 16) & 0xff) + 1;
|
local_apic_max_LVT_entries = ((qword >> 16) & 0xff) + 1;
|
||||||
@ -188,19 +191,19 @@ static void __local_apic_xapic_init()
|
|||||||
// 如果写入这里的话,在有的机器上面会报错
|
// 如果写入这里的话,在有的机器上面会报错
|
||||||
// *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI) = APIC_LVT_INT_MASKED;
|
// *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI) = APIC_LVT_INT_MASKED;
|
||||||
io_mfence();
|
io_mfence();
|
||||||
*(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER) = APIC_LVT_INT_MASKED;
|
*(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER) = APIC_LVT_INT_MASKED;
|
||||||
io_mfence();
|
io_mfence();
|
||||||
|
|
||||||
*(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL) = APIC_LVT_INT_MASKED;
|
*(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL) = APIC_LVT_INT_MASKED;
|
||||||
io_mfence();
|
io_mfence();
|
||||||
*(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_PERFORMANCE_MONITOR) =
|
*(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_PERFORMANCE_MONITOR) =
|
||||||
APIC_LVT_INT_MASKED;
|
APIC_LVT_INT_MASKED;
|
||||||
io_mfence();
|
io_mfence();
|
||||||
*(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT0) = APIC_LVT_INT_MASKED;
|
*(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT0) = APIC_LVT_INT_MASKED;
|
||||||
io_mfence();
|
io_mfence();
|
||||||
*(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT1) = APIC_LVT_INT_MASKED;
|
*(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT1) = APIC_LVT_INT_MASKED;
|
||||||
io_mfence();
|
io_mfence();
|
||||||
*(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_ERROR) = APIC_LVT_INT_MASKED;
|
*(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_ERROR) = APIC_LVT_INT_MASKED;
|
||||||
io_mfence();
|
io_mfence();
|
||||||
|
|
||||||
kdebug("All LVT Masked");
|
kdebug("All LVT Masked");
|
||||||
@ -692,4 +695,37 @@ uint32_t apic_get_local_apic_id()
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写入icr寄存器
|
||||||
|
*
|
||||||
|
* @param value 写入的值
|
||||||
|
*/
|
||||||
|
void apic_write_icr(uint64_t value)
|
||||||
|
{
|
||||||
|
if (flag_support_x2apic)
|
||||||
|
{
|
||||||
|
wrmsr(0x830, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// kdebug("to write icr: %#018lx", value);
|
||||||
|
const uint64_t PENDING = 1UL << 12;
|
||||||
|
while (*(volatile uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) & PENDING)
|
||||||
|
;
|
||||||
|
// kdebug("write icr: %#018lx", value);
|
||||||
|
*(volatile uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32) = (value >> 32) & 0xffffffff;
|
||||||
|
*(volatile uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) = value & 0xffffffff;
|
||||||
|
|
||||||
|
while (*(volatile uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) & PENDING)
|
||||||
|
;
|
||||||
|
// kdebug("write icr done");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询是否启用了x2APIC
|
||||||
|
bool apic_x2apic_enabled()
|
||||||
|
{
|
||||||
|
return flag_support_x2apic;
|
||||||
|
}
|
||||||
#pragma GCC pop_options
|
#pragma GCC pop_options
|
@ -8,7 +8,6 @@
|
|||||||
#pragma GCC push_options
|
#pragma GCC push_options
|
||||||
#pragma GCC optimize("O0")
|
#pragma GCC optimize("O0")
|
||||||
|
|
||||||
|
|
||||||
#define APIC_SUCCESS 0
|
#define APIC_SUCCESS 0
|
||||||
#define APIC_E_NOTFOUND 1
|
#define APIC_E_NOTFOUND 1
|
||||||
|
|
||||||
@ -19,7 +18,7 @@
|
|||||||
extern uint8_t __apic_enable_state;
|
extern uint8_t __apic_enable_state;
|
||||||
#define APIC_XAPIC_ENABLED 0
|
#define APIC_XAPIC_ENABLED 0
|
||||||
#define APIC_X2APIC_ENABLED 1
|
#define APIC_X2APIC_ENABLED 1
|
||||||
#define CURRENT_APIC_STATE (__apic_enable_state )
|
#define CURRENT_APIC_STATE (__apic_enable_state)
|
||||||
|
|
||||||
// ======== local apic 寄存器虚拟地址偏移量表 =======
|
// ======== local apic 寄存器虚拟地址偏移量表 =======
|
||||||
// 0x00~0x10 Reserved.
|
// 0x00~0x10 Reserved.
|
||||||
@ -331,4 +330,6 @@ void apic_make_rte_entry(struct apic_IO_APIC_RTE_entry *entry, uint8_t vector, u
|
|||||||
uint8_t deliver_status, uint8_t polarity, uint8_t irr, uint8_t trigger, uint8_t mask, uint8_t dest_apicID);
|
uint8_t deliver_status, uint8_t polarity, uint8_t irr, uint8_t trigger, uint8_t mask, uint8_t dest_apicID);
|
||||||
|
|
||||||
uint32_t apic_get_local_apic_id();
|
uint32_t apic_get_local_apic_id();
|
||||||
|
void apic_write_icr(uint64_t value);
|
||||||
|
bool apic_x2apic_enabled();
|
||||||
#pragma GCC pop_options
|
#pragma GCC pop_options
|
21
kernel/src/exception/ipi.rs
Normal file
21
kernel/src/exception/ipi.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum IpiKind {
|
||||||
|
KickCpu,
|
||||||
|
FlushTLB,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// IPI投递目标
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub enum IpiTarget {
|
||||||
|
/// 当前CPU
|
||||||
|
Current,
|
||||||
|
/// 所有CPU
|
||||||
|
All,
|
||||||
|
/// 除了当前CPU以外的所有CPU
|
||||||
|
Other,
|
||||||
|
/// 指定的CPU
|
||||||
|
Specified(usize),
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
use crate::arch::CurrentIrqArch;
|
use crate::arch::CurrentIrqArch;
|
||||||
|
|
||||||
|
pub mod ipi;
|
||||||
pub mod softirq;
|
pub mod softirq;
|
||||||
|
|
||||||
/// @brief 中断相关的操作
|
/// @brief 中断相关的操作
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
|
|
||||||
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::asm::{current::current_pcb},
|
arch::asm::current::current_pcb,
|
||||||
filesystem::vfs::file::FileDescriptorVec,
|
filesystem::vfs::file::FileDescriptorVec,
|
||||||
include::bindings::bindings::{
|
include::bindings::bindings::{verify_area, AT_REMOVEDIR, PAGE_4K_SIZE, PROC_MAX_FD_NUM},
|
||||||
verify_area, AT_REMOVEDIR, PAGE_4K_SIZE, PROC_MAX_FD_NUM,
|
|
||||||
},
|
|
||||||
io::SeekFrom,
|
io::SeekFrom,
|
||||||
kerror,
|
kerror,
|
||||||
syscall::{Syscall, SystemError},
|
syscall::{Syscall, SystemError},
|
||||||
|
@ -35,12 +35,10 @@ use crate::{
|
|||||||
use super::signal_types::{
|
use super::signal_types::{
|
||||||
si_code_val, sig_is_member, sigaction, sigaction__union_u, sigcontext, sigframe,
|
si_code_val, sig_is_member, sigaction, sigaction__union_u, sigcontext, sigframe,
|
||||||
sighand_struct, siginfo, signal_struct, sigpending, sigset_clear, sigset_del, sigset_delmask,
|
sighand_struct, siginfo, signal_struct, sigpending, sigset_clear, sigset_del, sigset_delmask,
|
||||||
sigset_equal, sigset_t, SigQueue, SignalNumber, MAX_SIG_NUM, SA_ALL_FLAGS,
|
sigset_equal, sigset_t, SigQueue, SignalNumber, MAX_SIG_NUM, SA_ALL_FLAGS, SA_FLAG_DFL,
|
||||||
SA_FLAG_DFL, SA_FLAG_IGN, SA_FLAG_IMMUTABLE, SA_FLAG_RESTORER, STACK_ALIGN, _NSIG_U64_CNT,
|
SA_FLAG_IGN, SA_FLAG_IMMUTABLE, SA_FLAG_RESTORER, STACK_ALIGN, _NSIG_U64_CNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位)
|
/// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位)
|
||||||
pub static DEFAULT_SIGACTION: sigaction = sigaction {
|
pub static DEFAULT_SIGACTION: sigaction = sigaction {
|
||||||
_u: sigaction__union_u {
|
_u: sigaction__union_u {
|
||||||
|
@ -55,7 +55,7 @@ macro_rules! int_like {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub const fn new(x: $new_type_name) -> Self {
|
pub const fn new(x: $new_type_name) -> Self {
|
||||||
$new_atomic_type_name {
|
$new_atomic_type_name {
|
||||||
container: $backing_atomic_type::new(x.into())
|
container: $backing_atomic_type::new(x.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -71,37 +71,60 @@ macro_rules! int_like {
|
|||||||
self.container.store(val.into(), order)
|
self.container.store(val.into(), order)
|
||||||
}
|
}
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn swap(&self, val: $new_type_name, order: ::core::sync::atomic::Ordering) -> $new_type_name {
|
pub fn swap(
|
||||||
|
&self,
|
||||||
|
val: $new_type_name,
|
||||||
|
order: ::core::sync::atomic::Ordering,
|
||||||
|
) -> $new_type_name {
|
||||||
$new_type_name::from(self.container.swap(val.into(), order))
|
$new_type_name::from(self.container.swap(val.into(), order))
|
||||||
}
|
}
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn compare_exchange(&self, current: $new_type_name, new: $new_type_name, success: ::core::sync::atomic::Ordering, failure: ::core::sync::atomic::Ordering) -> ::core::result::Result<$new_type_name, $new_type_name> {
|
pub fn compare_exchange(
|
||||||
match self.container.compare_exchange(current.into(), new.into(), success, failure) {
|
&self,
|
||||||
|
current: $new_type_name,
|
||||||
|
new: $new_type_name,
|
||||||
|
success: ::core::sync::atomic::Ordering,
|
||||||
|
failure: ::core::sync::atomic::Ordering,
|
||||||
|
) -> ::core::result::Result<$new_type_name, $new_type_name> {
|
||||||
|
match self
|
||||||
|
.container
|
||||||
|
.compare_exchange(current.into(), new.into(), success, failure)
|
||||||
|
{
|
||||||
Ok(result) => Ok($new_type_name::from(result)),
|
Ok(result) => Ok($new_type_name::from(result)),
|
||||||
Err(result) => Err($new_type_name::from(result))
|
Err(result) => Err($new_type_name::from(result)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn compare_exchange_weak(&self, current: $new_type_name, new: $new_type_name, success: ::core::sync::atomic::Ordering, failure: ::core::sync::atomic::Ordering) -> ::core::result::Result<$new_type_name, $new_type_name> {
|
pub fn compare_exchange_weak(
|
||||||
match self.container.compare_exchange_weak(current.into(), new.into(), success, failure) {
|
&self,
|
||||||
|
current: $new_type_name,
|
||||||
|
new: $new_type_name,
|
||||||
|
success: ::core::sync::atomic::Ordering,
|
||||||
|
failure: ::core::sync::atomic::Ordering,
|
||||||
|
) -> ::core::result::Result<$new_type_name, $new_type_name> {
|
||||||
|
match self.container.compare_exchange_weak(
|
||||||
|
current.into(),
|
||||||
|
new.into(),
|
||||||
|
success,
|
||||||
|
failure,
|
||||||
|
) {
|
||||||
Ok(result) => Ok($new_type_name::from(result)),
|
Ok(result) => Ok($new_type_name::from(result)),
|
||||||
Err(result) => Err($new_type_name::from(result))
|
Err(result) => Err($new_type_name::from(result)),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
use core::mem::size_of;
|
|
||||||
use ::core::sync::atomic::AtomicUsize;
|
use ::core::sync::atomic::AtomicUsize;
|
||||||
|
use core::mem::size_of;
|
||||||
|
|
||||||
// Generate type `usize_like`.
|
// Generate type `usize_like`.
|
||||||
int_like!(UsizeLike, usize);
|
int_like!(UsizeLike, usize);
|
||||||
assert_eq!(size_of::<UsizeLike>(), size_of::<usize>());
|
assert_eq!(size_of::<UsizeLike>(), size_of::<usize>());
|
||||||
|
|
||||||
|
|
||||||
// Generate types `usize_like` and `AtomicUsize`.
|
// Generate types `usize_like` and `AtomicUsize`.
|
||||||
int_like!(UsizeLike2, AtomicUsizeLike, usize, AtomicUsize);
|
int_like!(UsizeLike2, AtomicUsizeLike, usize, AtomicUsize);
|
||||||
assert_eq!(size_of::<UsizeLike2>(), size_of::<usize>());
|
assert_eq!(size_of::<UsizeLike2>(), size_of::<usize>());
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
@ -775,7 +775,7 @@ int process_wakeup_immediately(struct process_control_block *pcb)
|
|||||||
if (pcb->cpu_id == current_pcb->cpu_id)
|
if (pcb->cpu_id == current_pcb->cpu_id)
|
||||||
sched();
|
sched();
|
||||||
else
|
else
|
||||||
kick_cpu(pcb->cpu_id);
|
rs_kick_cpu(pcb->cpu_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1,21 @@
|
|||||||
|
use crate::{
|
||||||
|
arch::interrupt::ipi::send_ipi,
|
||||||
|
exception::ipi::{IpiKind, IpiTarget},
|
||||||
|
syscall::SystemError,
|
||||||
|
};
|
||||||
|
|
||||||
pub mod core;
|
pub mod core;
|
||||||
|
|
||||||
|
pub fn kick_cpu(cpu_id: usize) -> Result<(), SystemError> {
|
||||||
|
// todo: 增加对cpu_id的有效性检查
|
||||||
|
|
||||||
|
send_ipi(IpiKind::KickCpu, IpiTarget::Specified(cpu_id));
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn rs_kick_cpu(cpu_id: usize) -> usize {
|
||||||
|
return kick_cpu(cpu_id)
|
||||||
|
.map(|_| 0usize)
|
||||||
|
.unwrap_or_else(|e| e.to_posix_errno() as usize);
|
||||||
|
}
|
||||||
|
@ -222,21 +222,6 @@ static void __smp_kick_cpu_handler(uint64_t irq_num, uint64_t param, struct pt_r
|
|||||||
sched();
|
sched();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 使得指定的cpu核心立即运行调度
|
|
||||||
*
|
|
||||||
* @param cpu_id cpu核心号
|
|
||||||
*/
|
|
||||||
int kick_cpu(uint32_t cpu_id)
|
|
||||||
{
|
|
||||||
if (cpu_id >= MAX_CPU_NUM)
|
|
||||||
{
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, KICK_CPU_IRQ_NUM, ICR_APIC_FIXED,
|
|
||||||
ICR_ALL_EXCLUDE_Self, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 获取当前全部的cpu数目
|
* @brief 获取当前全部的cpu数目
|
||||||
|
@ -15,6 +15,6 @@ extern uchar _apu_boot_end[];
|
|||||||
*/
|
*/
|
||||||
void smp_init();
|
void smp_init();
|
||||||
|
|
||||||
int kick_cpu(uint32_t cpu_id);
|
extern int64_t rs_kick_cpu(uint32_t cpu_id);
|
||||||
|
|
||||||
uint32_t smp_get_total_cpu();
|
uint32_t smp_get_total_cpu();
|
@ -13,7 +13,8 @@ use crate::{
|
|||||||
MAX_PATHLEN,
|
MAX_PATHLEN,
|
||||||
},
|
},
|
||||||
include::bindings::bindings::{mm_stat_t, pid_t, verify_area, PAGE_2M_SIZE, PAGE_4K_SIZE},
|
include::bindings::bindings::{mm_stat_t, pid_t, verify_area, PAGE_2M_SIZE, PAGE_4K_SIZE},
|
||||||
io::SeekFrom, kinfo,
|
io::SeekFrom,
|
||||||
|
kinfo,
|
||||||
net::syscall::SockAddr,
|
net::syscall::SockAddr,
|
||||||
time::TimeSpec,
|
time::TimeSpec,
|
||||||
};
|
};
|
||||||
|
@ -3,11 +3,7 @@ use core::{arch::x86_64::_rdtsc, hint::spin_loop};
|
|||||||
use alloc::{boxed::Box, sync::Arc};
|
use alloc::{boxed::Box, sync::Arc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{
|
arch::{asm::current::current_pcb, sched::sched, CurrentIrqArch},
|
||||||
asm::current::current_pcb,
|
|
||||||
sched::sched,
|
|
||||||
CurrentIrqArch,
|
|
||||||
},
|
|
||||||
exception::InterruptArch,
|
exception::InterruptArch,
|
||||||
include::bindings::bindings::{useconds_t, Cpu_tsc_freq},
|
include::bindings::bindings::{useconds_t, Cpu_tsc_freq},
|
||||||
syscall::SystemError,
|
syscall::SystemError,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user