diff --git a/src/arch/x86_64/idt.rs b/src/arch/x86_64/idt.rs index 1a04789..d60fe5c 100644 --- a/src/arch/x86_64/idt.rs +++ b/src/arch/x86_64/idt.rs @@ -3,6 +3,7 @@ use x86::current::irq::IdtEntry as X86IdtEntry; use x86::shared::dtables::{self, DescriptorTablePointer}; use interrupt::*; +use ipi::IpiKind; pub static mut INIT_IDTR: DescriptorTablePointer = DescriptorTablePointer { limit: 0, @@ -69,9 +70,10 @@ pub unsafe fn init_paging() { IDT[47].set_func(irq::ata2); // Set IPI handlers - IDT[0x40].set_func(ipi::wakeup); - IDT[0x41].set_func(ipi::tlb); - IDT[0x42].set_func(ipi::pit); + IDT[IpiKind::Wakeup as usize].set_func(ipi::wakeup); + IDT[IpiKind::Switch as usize].set_func(ipi::switch); + IDT[IpiKind::Tlb as usize].set_func(ipi::tlb); + IDT[IpiKind::Pit as usize].set_func(ipi::pit); // Set syscall function IDT[0x80].set_func(syscall::syscall); diff --git a/src/arch/x86_64/interrupt/ipi.rs b/src/arch/x86_64/interrupt/ipi.rs index a0ad189..bc370e9 100644 --- a/src/arch/x86_64/interrupt/ipi.rs +++ b/src/arch/x86_64/interrupt/ipi.rs @@ -8,6 +8,17 @@ interrupt!(wakeup, { LOCAL_APIC.eoi(); }); +interrupt!(tlb, { + LOCAL_APIC.eoi(); + //TODO +}); + +interrupt!(switch, { + LOCAL_APIC.eoi(); + + let _ = context::switch(); +}); + interrupt!(pit, { LOCAL_APIC.eoi(); @@ -15,7 +26,3 @@ interrupt!(pit, { let _ = context::switch(); } }); - -interrupt!(tlb, { - LOCAL_APIC.eoi(); -}); diff --git a/src/arch/x86_64/ipi.rs b/src/arch/x86_64/ipi.rs index 021fc82..97996dc 100644 --- a/src/arch/x86_64/ipi.rs +++ b/src/arch/x86_64/ipi.rs @@ -3,7 +3,8 @@ pub enum IpiKind { Wakeup = 0x40, Tlb = 0x41, - Pit = 0x42, + Switch = 0x42, + Pit = 0x43, } #[derive(Clone, Copy, Debug)] diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 5596e8f..813bff3 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -17,6 +17,7 @@ use context::{ContextId, WaitpidKey}; use context::file::FileDescriptor; #[cfg(not(feature="doc"))] use elf::{self, program_header}; +use ipi::{ipi, IpiKind, IpiTarget}; use scheme::FileHandle; use syscall; use syscall::data::{SigAction, Stat}; @@ -477,6 +478,9 @@ pub fn clone(flags: usize, stack_base: usize) -> Result { } } + // Race to pick up the new process! + ipi(IpiKind::Switch, IpiTarget::Other); + let _ = unsafe { context::switch() }; Ok(pid)