More SMP fixes
All checks were successful
Build / build (push) Successful in 1m8s

This commit is contained in:
Mathieu Strypsteen 2024-12-12 20:13:00 +01:00
parent 0bd69ce363
commit 08b4900b96
4 changed files with 52 additions and 25 deletions

View file

@ -8,7 +8,7 @@ use core::{
arch::global_asm,
panic::PanicInfo,
ptr::null_mut,
sync::atomic::{AtomicU64, Ordering},
sync::atomic::{AtomicBool, AtomicU64, Ordering},
};
use acpi::AcpiTables;
@ -29,7 +29,7 @@ use sys::{
acpica_osl::AE_OK,
early_acpi::EarlyACPIHandler,
hpet::setup_hpet,
lapic::{get_current_lapic_id, setup_lapic_timer, start_aps},
lapic::{get_current_lapic_id, setup_lapic_timer, smp_broadcast_panic, start_aps},
madt::parse_madt,
pic::disable_pic,
sync::LOCKS_HELD,
@ -57,6 +57,7 @@ static LOADER_STRUCT: Mutex<LoaderStruct> = Mutex::new(LoaderStruct {
stride: 0,
},
});
pub static BROADCASTED_PANIC: AtomicBool = AtomicBool::new(false);
global_asm!(include_str!("cpu/boot.s"), options(att_syntax));
global_asm!(include_str!("cpu/trampoline.s"), options(att_syntax));
@ -106,10 +107,13 @@ fn main() {
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
cli();
if !BROADCASTED_PANIC.load(Ordering::SeqCst) {
smp_broadcast_panic();
LOCKS_HELD[get_current_lapic_id()].fetch_add(1, Ordering::SeqCst);
error!("{}", info);
let str = format!("{}", info);
display_print(&str);
}
loop {
hlt();
}

View file

@ -1,19 +1,25 @@
use core::{
arch::asm,
ptr::{copy, null_mut},
sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering},
};
use alloc::{vec, vec::Vec};
use kernel_common::{instructions::pause, paging::PageTable};
use kernel_common::{
instructions::{get_rflags, pause},
paging::PageTable,
};
use crate::cpu::{
use crate::{
cpu::{
isr::{ISR_INVALIDATE_TLB, ISR_SCHEDULER},
paging::{map_physical, map_range, unmap, virt_to_phys, CURRENT_PML4},
},
BROADCASTED_PANIC,
};
use super::{
hpet::sleep,
sync::Spinlock,
task::{ALL_APS_STARTED, STACK_SIZE, STARTING_AP_ID},
};
@ -37,6 +43,7 @@ const REGISTER_TIMER_LVT: usize = 0xc8;
const REGISTER_TIMER_INITIAL_COUNT: usize = 0xe0;
const REGISTER_TIMER_CURRENT_COUNT: usize = 0xe4;
const REGISTER_TIMER_DIVIDE: usize = 0xf8;
const IPI_NMI: u32 = 0x400;
const IPI_INIT: u32 = 0x500;
const IPI_STARTUP: u32 = 0x600;
@ -50,6 +57,7 @@ static LAPICS: [LAPIC; 256] = [const {
}; 256];
static TICKS_PER_MS: AtomicUsize = AtomicUsize::new(0);
pub static NEXT_LAPIC_ID: AtomicUsize = AtomicUsize::new(0);
static INVALIDATE_TLB_LOCK: Spinlock = Spinlock::new();
pub fn send_eoi() {
let address = ADDRESS.load(Ordering::SeqCst);
@ -60,10 +68,7 @@ pub fn send_eoi() {
pub fn get_current_lapic_id() -> usize {
let address = ADDRESS.load(Ordering::SeqCst);
let lapic_id = unsafe { address.add(REGISTER_ID).read_volatile() as usize >> 24 };
let rflags: u64;
unsafe {
asm!("pushfq; pop {};", out(reg) rflags);
}
let rflags = get_rflags();
assert!(rflags & (1 << 9) == 0);
lapic_id
}
@ -164,11 +169,28 @@ pub fn smp_invalidate_tlb() {
if !ALL_APS_STARTED.load(Ordering::SeqCst) {
return;
}
INVALIDATE_TLB_LOCK.lock();
let current_lapic_id = get_current_lapic_id();
for i in 0..NEXT_LAPIC_ID.load(Ordering::SeqCst) {
let lapic_id = LAPICS[i].lapic_id.load(Ordering::SeqCst);
if lapic_id == BSP_LAPIC_ID.load(Ordering::SeqCst) {
if lapic_id == current_lapic_id {
continue;
}
send_ipi(lapic_id, ISR_INVALIDATE_TLB as u32);
}
INVALIDATE_TLB_LOCK.unlock();
}
pub fn smp_broadcast_panic() {
BROADCASTED_PANIC.store(true, Ordering::SeqCst);
if !ALL_APS_STARTED.load(Ordering::SeqCst) {
return;
}
let current_lapic_id = get_current_lapic_id();
for i in 0..NEXT_LAPIC_ID.load(Ordering::SeqCst) {
let lapic_id = LAPICS[i].lapic_id.load(Ordering::SeqCst);
if lapic_id == current_lapic_id {
continue;
}
send_ipi(lapic_id, IPI_NMI);
}
}

View file

@ -1,11 +1,8 @@
use core::{
arch::asm,
sync::atomic::{AtomicBool, AtomicI64, AtomicU64, AtomicUsize, Ordering},
};
use core::sync::atomic::{AtomicBool, AtomicI64, AtomicU64, AtomicUsize, Ordering};
use alloc::{sync::Arc, vec, vec::Vec};
use hashbrown::HashMap;
use kernel_common::instructions::{cli, hlt, pause, sti};
use kernel_common::instructions::{cli, get_rflags, hlt, pause, sti};
use spin::{Lazy, Mutex};
use crate::{
@ -156,10 +153,7 @@ fn idle_main() {
}
}
pub fn setup_multitasking() -> ! {
let mut rflags;
unsafe {
asm!("pushf; pop {0:r}", out(reg) rflags);
}
let rflags = get_rflags();
RFLAGS.store(rflags, core::sync::atomic::Ordering::SeqCst);
for _ in 0..NEXT_LAPIC_ID.load(Ordering::SeqCst) {
create_idle_task();

View file

@ -20,3 +20,10 @@ pub fn hlt() {
asm!("hlt");
}
}
pub fn get_rflags() -> u64 {
let rflags;
unsafe {
asm!("pushf; pop {}", out(reg) rflags);
}
rflags
}