use crate::{
irq::{irq_enter, irq_exit, irqflags::local_daif_mask},
println,
processor::{cpu_relax, this_processor_id},
sched::schedule::schedule_ipi,
smp::{CPU_ONLINE, smp_call::smp_call_function_in_interrupt},
};
pub(crate) const IPI_RESCHEDULE: u32 = 0;
pub(crate) const IPI_CALL_FUNC: u32 = 1;
pub(crate) const IPI_CPU_STOP: u32 = 2;
fn ipi_cpu_stop(cpu: usize) {
CPU_ONLINE.clear(cpu);
local_daif_mask();
loop {
cpu_relax();
}
}
pub(crate) fn handle_ipi(ipirn: u32) {
let cpu = this_processor_id();
match ipirn {
IPI_RESCHEDULE => {
schedule_ipi();
},
IPI_CALL_FUNC => {
irq_enter();
smp_call_function_in_interrupt();
irq_exit();
},
IPI_CPU_STOP => {
irq_enter();
ipi_cpu_stop(cpu);
irq_exit();
},
_ => {
println!("CPU{}: Unknown IPI message {:#x}", cpu, ipirn);
},
}
}