Make multi-core support the default
Make IPIs less architecture specific
This commit is contained in:
@@ -27,7 +27,7 @@ version = "0.9.0"
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = ["acpi", "multi_core"]
|
||||
acpi = []
|
||||
doc = []
|
||||
graphical_debug = []
|
||||
|
||||
@@ -68,9 +68,10 @@ pub unsafe fn init_paging() {
|
||||
IDT[46].set_func(irq::ata1);
|
||||
IDT[47].set_func(irq::ata2);
|
||||
|
||||
// Set IPI handler (null)
|
||||
IDT[0x40].set_func(ipi::ipi);
|
||||
IDT[0x41].set_func(ipi::pit);
|
||||
// Set IPI handlers
|
||||
IDT[0x40].set_func(ipi::wakeup);
|
||||
IDT[0x41].set_func(ipi::tlb);
|
||||
IDT[0x42].set_func(ipi::pit);
|
||||
|
||||
// Set syscall function
|
||||
IDT[0x80].set_func(syscall::syscall);
|
||||
|
||||
@@ -4,7 +4,7 @@ use context;
|
||||
use device::local_apic::LOCAL_APIC;
|
||||
use super::irq::PIT_TICKS;
|
||||
|
||||
interrupt!(ipi, {
|
||||
interrupt!(wakeup, {
|
||||
LOCAL_APIC.eoi();
|
||||
});
|
||||
|
||||
@@ -15,3 +15,7 @@ interrupt!(pit, {
|
||||
let _ = context::switch();
|
||||
}
|
||||
});
|
||||
|
||||
interrupt!(tlb, {
|
||||
LOCAL_APIC.eoi();
|
||||
});
|
||||
|
||||
@@ -2,8 +2,9 @@ use core::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
|
||||
|
||||
use context;
|
||||
use context::timeout;
|
||||
use device::{local_apic, pic};
|
||||
use device::pic;
|
||||
use device::serial::{COM1, COM2};
|
||||
use ipi::{ipi, IpiKind, IpiTarget};
|
||||
use time;
|
||||
|
||||
//resets to 0 in context::switch()
|
||||
@@ -40,9 +41,7 @@ pub unsafe fn acknowledge(irq: usize) {
|
||||
|
||||
interrupt!(pit, {
|
||||
// Wake up other CPUs
|
||||
if cfg!(feature = "multi_core") {
|
||||
local_apic::LOCAL_APIC.set_icr(3 << 18 | 1 << 14 | 0x41);
|
||||
}
|
||||
ipi(IpiKind::Pit, IpiTarget::Other);
|
||||
|
||||
// Saves CPU time by not sending IRQ event irq_trigger(0);
|
||||
|
||||
|
||||
28
src/arch/x86_64/ipi.rs
Normal file
28
src/arch/x86_64/ipi.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(u8)]
|
||||
pub enum IpiKind {
|
||||
Wakeup = 0x40,
|
||||
Tlb = 0x41,
|
||||
Pit = 0x42,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(u8)]
|
||||
pub enum IpiTarget {
|
||||
Current = 1,
|
||||
All = 2,
|
||||
Other = 3,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "multi_core"))]
|
||||
#[inline(always)]
|
||||
pub fn ipi(_kind: IpiKind, _target: IpiTarget) {}
|
||||
|
||||
#[cfg(feature = "multi_core")]
|
||||
#[inline(always)]
|
||||
pub fn ipi(kind: IpiKind, target: IpiTarget) {
|
||||
use device::local_apic::LOCAL_APIC;
|
||||
|
||||
let icr = (target as u64) << 18 | 1 << 14 | (kind as u64);
|
||||
unsafe { LOCAL_APIC.set_icr(icr) };
|
||||
}
|
||||
@@ -20,6 +20,9 @@ pub mod idt;
|
||||
/// Interrupt instructions
|
||||
pub mod interrupt;
|
||||
|
||||
/// Inter-processor interrupts
|
||||
pub mod ipi;
|
||||
|
||||
/// Paging
|
||||
pub mod paging;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ use core::{mem, ptr};
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use x86::shared::{control_regs, msr, tlb};
|
||||
|
||||
use ipi::{ipi, IpiKind, IpiTarget};
|
||||
use memory::{allocate_frames, Frame};
|
||||
|
||||
use self::entry::EntryFlags;
|
||||
|
||||
@@ -8,7 +8,7 @@ use spin::Mutex;
|
||||
use context::arch;
|
||||
use context::file::FileDescriptor;
|
||||
use context::memory::{Grant, Memory, SharedMemory, Tls};
|
||||
use device;
|
||||
use ipi::{ipi, IpiKind, IpiTarget};
|
||||
use scheme::{SchemeNamespace, FileHandle};
|
||||
use syscall::data::SigAction;
|
||||
use syscall::flag::SIG_DFL;
|
||||
@@ -284,15 +284,14 @@ impl Context {
|
||||
pub fn unblock(&mut self) -> bool {
|
||||
if self.status == Status::Blocked {
|
||||
self.status = Status::Runnable;
|
||||
if cfg!(feature = "multi_core") {
|
||||
if let Some(cpu_id) = self.cpu_id {
|
||||
if cpu_id != ::cpu_id() {
|
||||
// Send IPI if not on current CPU
|
||||
// TODO: Make this more architecture independent
|
||||
unsafe { device::local_apic::LOCAL_APIC.set_icr(3 << 18 | 1 << 14 | 0x40) };
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(cpu_id) = self.cpu_id {
|
||||
if cpu_id != ::cpu_id() {
|
||||
// Send IPI if not on current CPU
|
||||
ipi(IpiKind::Wakeup, IpiTarget::Other);
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
||||
Reference in New Issue
Block a user