feat: base PM scheduller
This commit is contained in:
52
kernel/src/cpu/lapic.rs
Normal file
52
kernel/src/cpu/lapic.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
// src/cpu/lapic.rs
|
||||
|
||||
use core::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
pub const LAPIC_DEFAULT_BASE: u64 = 0xFEE00_000;
|
||||
const LAPIC_EOI: u64 = 0x0B0;
|
||||
const LAPIC_ICR_LOW: u64 = 0x300;
|
||||
|
||||
static LAPIC_VIRT_BASE: AtomicU64 = AtomicU64::new(0);
|
||||
|
||||
pub fn init(hhdm_offset: u64) {
|
||||
LAPIC_VIRT_BASE.store(LAPIC_DEFAULT_BASE + hhdm_offset, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn current_core_id() -> u32 {
|
||||
let mut ebx: u32;
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"mov {tmp:r}, rbx",
|
||||
"mov eax, 1",
|
||||
"cpuid",
|
||||
"mov {out:e}, ebx",
|
||||
"mov rbx, {tmp:r}",
|
||||
tmp = out(reg) _,
|
||||
out = out(reg) ebx,
|
||||
out("eax") _, out("ecx") _, out("edx") _,
|
||||
options(nostack, preserves_flags)
|
||||
);
|
||||
}
|
||||
ebx >> 24
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_lapic_reg(offset: u64, value: u32) {
|
||||
let base = LAPIC_VIRT_BASE.load(Ordering::Relaxed);
|
||||
if base == 0 { return; }
|
||||
unsafe { core::ptr::write_volatile((base + offset) as *mut u32, value) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn send_eoi() {
|
||||
write_lapic_reg(LAPIC_EOI, 0);
|
||||
}
|
||||
|
||||
pub fn broadcast_ipi_exclude_self(vector: u8) {
|
||||
// Destination Shorthand = 10b (All excluding self)
|
||||
// Level = 1 (Assert)
|
||||
// Delivery Mode = 000b
|
||||
let icr_low = (2 << 18) | (1 << 14) | (vector as u32);
|
||||
write_lapic_reg(LAPIC_ICR_LOW, icr_low);
|
||||
}
|
||||
Reference in New Issue
Block a user