This commit is contained in:
parent
0bd69ce363
commit
08b4900b96
4 changed files with 52 additions and 25 deletions
|
@ -8,7 +8,7 @@ use core::{
|
||||||
arch::global_asm,
|
arch::global_asm,
|
||||||
panic::PanicInfo,
|
panic::PanicInfo,
|
||||||
ptr::null_mut,
|
ptr::null_mut,
|
||||||
sync::atomic::{AtomicU64, Ordering},
|
sync::atomic::{AtomicBool, AtomicU64, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
use acpi::AcpiTables;
|
use acpi::AcpiTables;
|
||||||
|
@ -29,7 +29,7 @@ use sys::{
|
||||||
acpica_osl::AE_OK,
|
acpica_osl::AE_OK,
|
||||||
early_acpi::EarlyACPIHandler,
|
early_acpi::EarlyACPIHandler,
|
||||||
hpet::setup_hpet,
|
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,
|
madt::parse_madt,
|
||||||
pic::disable_pic,
|
pic::disable_pic,
|
||||||
sync::LOCKS_HELD,
|
sync::LOCKS_HELD,
|
||||||
|
@ -57,6 +57,7 @@ static LOADER_STRUCT: Mutex<LoaderStruct> = Mutex::new(LoaderStruct {
|
||||||
stride: 0,
|
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/boot.s"), options(att_syntax));
|
||||||
global_asm!(include_str!("cpu/trampoline.s"), options(att_syntax));
|
global_asm!(include_str!("cpu/trampoline.s"), options(att_syntax));
|
||||||
|
@ -106,10 +107,13 @@ fn main() {
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic(info: &PanicInfo) -> ! {
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
cli();
|
cli();
|
||||||
LOCKS_HELD[get_current_lapic_id()].fetch_add(1, Ordering::SeqCst);
|
if !BROADCASTED_PANIC.load(Ordering::SeqCst) {
|
||||||
error!("{}", info);
|
smp_broadcast_panic();
|
||||||
let str = format!("{}", info);
|
LOCKS_HELD[get_current_lapic_id()].fetch_add(1, Ordering::SeqCst);
|
||||||
display_print(&str);
|
error!("{}", info);
|
||||||
|
let str = format!("{}", info);
|
||||||
|
display_print(&str);
|
||||||
|
}
|
||||||
loop {
|
loop {
|
||||||
hlt();
|
hlt();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,25 @@
|
||||||
use core::{
|
use core::{
|
||||||
arch::asm,
|
|
||||||
ptr::{copy, null_mut},
|
ptr::{copy, null_mut},
|
||||||
sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering},
|
sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
use alloc::{vec, vec::Vec};
|
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::{
|
||||||
isr::{ISR_INVALIDATE_TLB, ISR_SCHEDULER},
|
cpu::{
|
||||||
paging::{map_physical, map_range, unmap, virt_to_phys, CURRENT_PML4},
|
isr::{ISR_INVALIDATE_TLB, ISR_SCHEDULER},
|
||||||
|
paging::{map_physical, map_range, unmap, virt_to_phys, CURRENT_PML4},
|
||||||
|
},
|
||||||
|
BROADCASTED_PANIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
hpet::sleep,
|
hpet::sleep,
|
||||||
|
sync::Spinlock,
|
||||||
task::{ALL_APS_STARTED, STACK_SIZE, STARTING_AP_ID},
|
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_INITIAL_COUNT: usize = 0xe0;
|
||||||
const REGISTER_TIMER_CURRENT_COUNT: usize = 0xe4;
|
const REGISTER_TIMER_CURRENT_COUNT: usize = 0xe4;
|
||||||
const REGISTER_TIMER_DIVIDE: usize = 0xf8;
|
const REGISTER_TIMER_DIVIDE: usize = 0xf8;
|
||||||
|
const IPI_NMI: u32 = 0x400;
|
||||||
const IPI_INIT: u32 = 0x500;
|
const IPI_INIT: u32 = 0x500;
|
||||||
const IPI_STARTUP: u32 = 0x600;
|
const IPI_STARTUP: u32 = 0x600;
|
||||||
|
|
||||||
|
@ -50,6 +57,7 @@ static LAPICS: [LAPIC; 256] = [const {
|
||||||
}; 256];
|
}; 256];
|
||||||
static TICKS_PER_MS: AtomicUsize = AtomicUsize::new(0);
|
static TICKS_PER_MS: AtomicUsize = AtomicUsize::new(0);
|
||||||
pub static NEXT_LAPIC_ID: AtomicUsize = AtomicUsize::new(0);
|
pub static NEXT_LAPIC_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
static INVALIDATE_TLB_LOCK: Spinlock = Spinlock::new();
|
||||||
|
|
||||||
pub fn send_eoi() {
|
pub fn send_eoi() {
|
||||||
let address = ADDRESS.load(Ordering::SeqCst);
|
let address = ADDRESS.load(Ordering::SeqCst);
|
||||||
|
@ -60,10 +68,7 @@ pub fn send_eoi() {
|
||||||
pub fn get_current_lapic_id() -> usize {
|
pub fn get_current_lapic_id() -> usize {
|
||||||
let address = ADDRESS.load(Ordering::SeqCst);
|
let address = ADDRESS.load(Ordering::SeqCst);
|
||||||
let lapic_id = unsafe { address.add(REGISTER_ID).read_volatile() as usize >> 24 };
|
let lapic_id = unsafe { address.add(REGISTER_ID).read_volatile() as usize >> 24 };
|
||||||
let rflags: u64;
|
let rflags = get_rflags();
|
||||||
unsafe {
|
|
||||||
asm!("pushfq; pop {};", out(reg) rflags);
|
|
||||||
}
|
|
||||||
assert!(rflags & (1 << 9) == 0);
|
assert!(rflags & (1 << 9) == 0);
|
||||||
lapic_id
|
lapic_id
|
||||||
}
|
}
|
||||||
|
@ -164,11 +169,28 @@ pub fn smp_invalidate_tlb() {
|
||||||
if !ALL_APS_STARTED.load(Ordering::SeqCst) {
|
if !ALL_APS_STARTED.load(Ordering::SeqCst) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
INVALIDATE_TLB_LOCK.lock();
|
||||||
|
let current_lapic_id = get_current_lapic_id();
|
||||||
for i in 0..NEXT_LAPIC_ID.load(Ordering::SeqCst) {
|
for i in 0..NEXT_LAPIC_ID.load(Ordering::SeqCst) {
|
||||||
let lapic_id = LAPICS[i].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;
|
continue;
|
||||||
}
|
}
|
||||||
send_ipi(lapic_id, ISR_INVALIDATE_TLB as u32);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
use core::{
|
use core::sync::atomic::{AtomicBool, AtomicI64, AtomicU64, AtomicUsize, Ordering};
|
||||||
arch::asm,
|
|
||||||
sync::atomic::{AtomicBool, AtomicI64, AtomicU64, AtomicUsize, Ordering},
|
|
||||||
};
|
|
||||||
|
|
||||||
use alloc::{sync::Arc, vec, vec::Vec};
|
use alloc::{sync::Arc, vec, vec::Vec};
|
||||||
use hashbrown::HashMap;
|
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 spin::{Lazy, Mutex};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -156,10 +153,7 @@ fn idle_main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn setup_multitasking() -> ! {
|
pub fn setup_multitasking() -> ! {
|
||||||
let mut rflags;
|
let rflags = get_rflags();
|
||||||
unsafe {
|
|
||||||
asm!("pushf; pop {0:r}", out(reg) rflags);
|
|
||||||
}
|
|
||||||
RFLAGS.store(rflags, core::sync::atomic::Ordering::SeqCst);
|
RFLAGS.store(rflags, core::sync::atomic::Ordering::SeqCst);
|
||||||
for _ in 0..NEXT_LAPIC_ID.load(Ordering::SeqCst) {
|
for _ in 0..NEXT_LAPIC_ID.load(Ordering::SeqCst) {
|
||||||
create_idle_task();
|
create_idle_task();
|
||||||
|
|
|
@ -20,3 +20,10 @@ pub fn hlt() {
|
||||||
asm!("hlt");
|
asm!("hlt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn get_rflags() -> u64 {
|
||||||
|
let rflags;
|
||||||
|
unsafe {
|
||||||
|
asm!("pushf; pop {}", out(reg) rflags);
|
||||||
|
}
|
||||||
|
rflags
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue