mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 11:16: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)]
|
||||
|
||||
pub mod ipi;
|
||||
|
||||
use core::{
|
||||
arch::asm,
|
||||
sync::atomic::{compiler_fence, Ordering},
|
||||
|
@ -9,10 +9,7 @@ use crate::{
|
||||
syscall::{Syscall, SystemError, SYS_EXECVE, SYS_FORK, SYS_RT_SIGRETURN, SYS_VFORK},
|
||||
};
|
||||
|
||||
use super::{
|
||||
asm::{ptrace::user_mode},
|
||||
mm::barrier::mfence,
|
||||
};
|
||||
use super::{asm::ptrace::user_mode, mm::barrier::mfence};
|
||||
|
||||
extern "C" {
|
||||
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();
|
||||
else // 当前为xapic
|
||||
__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);
|
||||
|
||||
qword |= (1 << 8);
|
||||
*(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);
|
||||
*(volatile uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR) = qword;
|
||||
qword = *(volatile uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR);
|
||||
if (qword & 0x100)
|
||||
kinfo("APIC Software Enabled.");
|
||||
if (qword & 0x1000)
|
||||
kinfo("EOI-Broadcast Suppression Enabled.");
|
||||
|
||||
barrier();
|
||||
// 从 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;
|
||||
|
||||
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;
|
||||
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();
|
||||
|
||||
*(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();
|
||||
*(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;
|
||||
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();
|
||||
*(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();
|
||||
*(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();
|
||||
|
||||
kdebug("All LVT Masked");
|
||||
@ -692,4 +695,37 @@ uint32_t apic_get_local_apic_id()
|
||||
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
|
@ -8,7 +8,6 @@
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
|
||||
|
||||
#define APIC_SUCCESS 0
|
||||
#define APIC_E_NOTFOUND 1
|
||||
|
||||
@ -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);
|
||||
|
||||
uint32_t apic_get_local_apic_id();
|
||||
void apic_write_icr(uint64_t value);
|
||||
bool apic_x2apic_enabled();
|
||||
#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;
|
||||
|
||||
pub mod ipi;
|
||||
pub mod softirq;
|
||||
|
||||
/// @brief 中断相关的操作
|
||||
|
@ -1,12 +1,9 @@
|
||||
|
||||
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||
|
||||
use crate::{
|
||||
arch::asm::{current::current_pcb},
|
||||
arch::asm::current::current_pcb,
|
||||
filesystem::vfs::file::FileDescriptorVec,
|
||||
include::bindings::bindings::{
|
||||
verify_area, AT_REMOVEDIR, PAGE_4K_SIZE, PROC_MAX_FD_NUM,
|
||||
},
|
||||
include::bindings::bindings::{verify_area, AT_REMOVEDIR, PAGE_4K_SIZE, PROC_MAX_FD_NUM},
|
||||
io::SeekFrom,
|
||||
kerror,
|
||||
syscall::{Syscall, SystemError},
|
||||
|
@ -35,12 +35,10 @@ use crate::{
|
||||
use super::signal_types::{
|
||||
si_code_val, sig_is_member, sigaction, sigaction__union_u, sigcontext, sigframe,
|
||||
sighand_struct, siginfo, signal_struct, sigpending, sigset_clear, sigset_del, sigset_delmask,
|
||||
sigset_equal, sigset_t, SigQueue, SignalNumber, MAX_SIG_NUM, SA_ALL_FLAGS,
|
||||
SA_FLAG_DFL, SA_FLAG_IGN, SA_FLAG_IMMUTABLE, SA_FLAG_RESTORER, STACK_ALIGN, _NSIG_U64_CNT,
|
||||
sigset_equal, sigset_t, SigQueue, SignalNumber, MAX_SIG_NUM, SA_ALL_FLAGS, SA_FLAG_DFL,
|
||||
SA_FLAG_IGN, SA_FLAG_IMMUTABLE, SA_FLAG_RESTORER, STACK_ALIGN, _NSIG_U64_CNT,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位)
|
||||
pub static DEFAULT_SIGACTION: sigaction = sigaction {
|
||||
_u: sigaction__union_u {
|
||||
|
@ -55,7 +55,7 @@ macro_rules! int_like {
|
||||
#[allow(dead_code)]
|
||||
pub const fn new(x: $new_type_name) -> Self {
|
||||
$new_atomic_type_name {
|
||||
container: $backing_atomic_type::new(x.into())
|
||||
container: $backing_atomic_type::new(x.into()),
|
||||
}
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
@ -71,37 +71,60 @@ macro_rules! int_like {
|
||||
self.container.store(val.into(), order)
|
||||
}
|
||||
#[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))
|
||||
}
|
||||
#[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> {
|
||||
match self.container.compare_exchange(current.into(), new.into(), success, failure) {
|
||||
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> {
|
||||
match self
|
||||
.container
|
||||
.compare_exchange(current.into(), new.into(), success, failure)
|
||||
{
|
||||
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)]
|
||||
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> {
|
||||
match self.container.compare_exchange_weak(current.into(), new.into(), success, failure) {
|
||||
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> {
|
||||
match self.container.compare_exchange_weak(
|
||||
current.into(),
|
||||
new.into(),
|
||||
success,
|
||||
failure,
|
||||
) {
|
||||
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]
|
||||
fn test() {
|
||||
use core::mem::size_of;
|
||||
use ::core::sync::atomic::AtomicUsize;
|
||||
use core::mem::size_of;
|
||||
|
||||
// Generate type `usize_like`.
|
||||
int_like!(UsizeLike, usize);
|
||||
assert_eq!(size_of::<UsizeLike>(), size_of::<usize>());
|
||||
|
||||
|
||||
// Generate types `usize_like` and `AtomicUsize`.
|
||||
int_like!(UsizeLike2, AtomicUsizeLike, usize, AtomicUsize);
|
||||
assert_eq!(size_of::<UsizeLike2>(), size_of::<usize>());
|
||||
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
|
@ -775,7 +775,7 @@ int process_wakeup_immediately(struct process_control_block *pcb)
|
||||
if (pcb->cpu_id == current_pcb->cpu_id)
|
||||
sched();
|
||||
else
|
||||
kick_cpu(pcb->cpu_id);
|
||||
rs_kick_cpu(pcb->cpu_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1 +1,21 @@
|
||||
use crate::{
|
||||
arch::interrupt::ipi::send_ipi,
|
||||
exception::ipi::{IpiKind, IpiTarget},
|
||||
syscall::SystemError,
|
||||
};
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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数目
|
||||
|
@ -15,6 +15,6 @@ extern uchar _apu_boot_end[];
|
||||
*/
|
||||
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();
|
@ -13,7 +13,8 @@ use crate::{
|
||||
MAX_PATHLEN,
|
||||
},
|
||||
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,
|
||||
time::TimeSpec,
|
||||
};
|
||||
|
@ -3,11 +3,7 @@ use core::{arch::x86_64::_rdtsc, hint::spin_loop};
|
||||
use alloc::{boxed::Box, sync::Arc};
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
asm::current::current_pcb,
|
||||
sched::sched,
|
||||
CurrentIrqArch,
|
||||
},
|
||||
arch::{asm::current::current_pcb, sched::sched, CurrentIrqArch},
|
||||
exception::InterruptArch,
|
||||
include::bindings::bindings::{useconds_t, Cpu_tsc_freq},
|
||||
syscall::SystemError,
|
||||
|
Loading…
x
Reference in New Issue
Block a user