fix: cleanup

This commit is contained in:
Zoe
2026-08-27 13:18:57 -05:00
parent 7dcf244ee6
commit 8a71cdfcc5
11 changed files with 52 additions and 201 deletions
+20 -124
View File
@@ -2,16 +2,11 @@ use core::sync::atomic::{AtomicU32, AtomicUsize, Ordering};
use crate::{
arch::{
disable_interrupts,
port::write_u8,
x86_64::{
cpu::{read_msr, write_msr},
interrupts::{
apic_vectors::{
APIC_ERROR_VECTOR, APIC_SELF_IPI_VECTOR, APIC_SPURIOUS_VECTOR,
APIC_TIMER_VECTOR,
},
enable_interrupts,
interrupts::apic_vectors::{
APIC_ERROR_VECTOR, APIC_SPURIOUS_VECTOR, APIC_TIMER_VECTOR,
},
},
},
@@ -22,7 +17,6 @@ use crate::{
};
const APIC_ID: u32 = 0x20;
const APIC_VERSION: u32 = 0x30;
// End Of Interrupt
const APIC_EOI: u32 = 0xB0;
// Task Priority Register
@@ -38,10 +32,6 @@ const APIC_LVT_TIMER_MODE_PERIODIC: u64 = 1 << 17;
pub const LOCAL_APIC_VIRTUAL_ADDRESS: VirtualAddr = VirtualAddr::new(0xFFFF_FFFD_0000_0000);
const APIC_ICR1: u32 = 0x300;
const APIC_ICR2: u32 = 0x310;
const X2APIC_SELF_IPI: u32 = 0x3F0;
const APIC_LVT_TIMER: u32 = 0x320;
const APIC_TIMER_INITIAL_COUNT: u32 = 0x380;
const APIC_TIMER_CURRENT_COUNT: u32 = 0x390;
@@ -86,29 +76,6 @@ impl LocalApicAccess {
}
}
fn send_self_ipi(&self, vector: u8) -> Result<(), LocalApicError> {
match self {
Self::X2Apic => {
unsafe { write_msr(0x800 + X2APIC_SELF_IPI / 16, vector as u64) };
}
Self::XApic => {
unsafe {
// bit 18 = destination type. 1 = self
let interrupt_command = vector as u32 | (1 << 18);
core::ptr::write_volatile(
LOCAL_APIC_VIRTUAL_ADDRESS
.as_mut_ptr::<u8>()
.add(APIC_ICR1 as usize)
.cast::<u32>(),
interrupt_command,
);
};
}
};
Ok(())
}
fn end_of_interrupt(&self) {
self.write(APIC_EOI, 0);
}
@@ -118,9 +85,7 @@ impl LocalApicAccess {
pub enum LocalApicError {
AddressMismatch,
ApicDisabled,
TimerTestFailed,
FailedToMapApic,
FailedToSendSelfIpi,
NotBootSystemProcessor,
}
@@ -138,8 +103,6 @@ const APIC_BASE_GLOBAL_ENABLE: u64 = 1 << 11;
// TODO: use MAXPHYADDR
const APIC_BASE_ADDRESS_MASK: u64 = 0x000F_FFFF_FFFF_F000;
static SELF_IPI_COUNTER: AtomicUsize = AtomicUsize::new(0);
impl LocalApic {
pub fn init(
local_apic_address: PhysicalAddr,
@@ -196,10 +159,7 @@ impl LocalApic {
LocalApicAccess::X2Apic => raw_id as u32,
};
let version = access.read(APIC_VERSION);
let max_lvt_entries = ((version >> 16) & 0xFF) + 1;
let version = version & 0xFF;
// ensure legacy PIC is disabled
unsafe {
write_u8(0x21, 0xFF);
write_u8(0xA1, 0xFF);
@@ -214,42 +174,6 @@ impl LocalApic {
Ok(Self { id, access })
}
pub fn test_timer_interrupt(&self) -> Result<(), LocalApicError> {
self.access
.write(APIC_LVT_TIMER, APIC_TIMER_VECTOR as u64 | APIC_LVT_MASKED);
// Divide by 16
self.access.write(APIC_TIMER_DIVIDE_CONFIG, 0b11);
APIC_TIMER_COUNT.store(0, Ordering::SeqCst);
self.access.write(APIC_TIMER_INITIAL_COUNT, 123456);
self.access.write(APIC_LVT_TIMER, APIC_TIMER_VECTOR as u64);
enable_interrupts();
for _ in 0..10_000_000 {
if APIC_TIMER_COUNT.load(Ordering::SeqCst) != 0 {
break;
}
core::hint::spin_loop();
}
disable_interrupts();
self.access
.write(APIC_LVT_TIMER, APIC_TIMER_VECTOR as u64 | APIC_LVT_MASKED);
self.access.write(APIC_TIMER_INITIAL_COUNT, 0);
if APIC_TIMER_COUNT.load(Ordering::SeqCst) != 1 {
return Err(LocalApicError::TimerTestFailed);
}
Ok(())
}
pub fn start_timer(&self) {
self.access.write(APIC_LVT_TIMER, APIC_TIMER_VECTOR as u64);
}
@@ -268,51 +192,27 @@ impl LocalApic {
self.access.write(APIC_TIMER_INITIAL_COUNT, 0);
}
pub fn send_self_ipi(&self) -> Result<(), LocalApicError> {
SELF_IPI_COUNTER.store(0, Ordering::SeqCst);
// pub fn delay_ticks(&self, count: u32) {
// if count == 0 {
// return;
// }
self.access.send_self_ipi(APIC_SELF_IPI_VECTOR)?;
// APIC_TIMER_COUNT.store(0, Ordering::SeqCst);
enable_interrupts();
// self.access
// .write(APIC_LVT_TIMER, APIC_TIMER_VECTOR as u64 | APIC_LVT_MASKED);
// self.access.write(APIC_TIMER_DIVIDE_CONFIG, 0b11);
// self.access.write(APIC_TIMER_INITIAL_COUNT, count as u64);
// self.access.write(APIC_LVT_TIMER, APIC_TIMER_VECTOR as u64);
for _ in 0..10_000_000 {
if SELF_IPI_COUNTER.load(Ordering::SeqCst) != 0 {
break;
}
// while APIC_TIMER_COUNT.load(Ordering::SeqCst) == 0 {
// unsafe {
// core::arch::asm!("sti", "hlt", "cli", options(nomem, nostack));
// }
// }
core::hint::spin_loop();
}
disable_interrupts();
if SELF_IPI_COUNTER.load(Ordering::SeqCst) != 1 {
return Err(LocalApicError::FailedToSendSelfIpi);
}
Ok(())
}
pub fn delay_ticks(&self, count: u32) {
if count == 0 {
return;
}
APIC_TIMER_COUNT.store(0, Ordering::SeqCst);
self.access
.write(APIC_LVT_TIMER, APIC_TIMER_VECTOR as u64 | APIC_LVT_MASKED);
self.access.write(APIC_TIMER_DIVIDE_CONFIG, 0b11);
self.access.write(APIC_TIMER_INITIAL_COUNT, count as u64);
self.access.write(APIC_LVT_TIMER, APIC_TIMER_VECTOR as u64);
while APIC_TIMER_COUNT.load(Ordering::SeqCst) == 0 {
unsafe {
core::arch::asm!("sti", "hlt", "cli", options(nomem, nostack));
}
}
self.stop_timer();
}
// self.stop_timer();
// }
pub fn id(&self) -> u32 {
self.id
@@ -337,10 +237,6 @@ pub(super) fn end_of_interrupt() {
current_access().end_of_interrupt();
}
pub(super) fn record_self_ipi() {
SELF_IPI_COUNTER.fetch_add(1, Ordering::SeqCst);
}
static APIC_ERROR_COUNT: AtomicUsize = AtomicUsize::new(0);
static LAST_APIC_ERROR: AtomicU32 = AtomicU32::new(0);
@@ -3,17 +3,11 @@ use crate::arch::{
x86_64::interrupts::idt::{self, InterruptStackFrame},
};
pub const APIC_SELF_IPI_VECTOR: u8 = 0xF0;
pub const PIT_CALIBRATION_VECTOR: u8 = 0xF1;
pub const APIC_TIMER_VECTOR: u8 = 0xFD;
pub const APIC_ERROR_VECTOR: u8 = 0xFE;
pub const APIC_SPURIOUS_VECTOR: u8 = 0xFF;
extern "x86-interrupt" fn self_ipi_handler(_frame: InterruptStackFrame) {
apic::record_self_ipi();
apic::end_of_interrupt();
}
extern "x86-interrupt" fn error_handler(_frame: InterruptStackFrame) {
apic::record_error();
apic::end_of_interrupt();
@@ -34,7 +28,6 @@ extern "x86-interrupt" fn spurious_handler(_frame: InterruptStackFrame) {
}
pub(super) fn install(idt: &mut idt::Idt) {
idt.set_handler(APIC_SELF_IPI_VECTOR, self_ipi_handler, 0);
idt.set_handler(PIT_CALIBRATION_VECTOR, pit_calibration_handler, 0);
idt.set_handler(APIC_ERROR_VECTOR, error_handler, 0);
idt.set_handler(APIC_TIMER_VECTOR, timer_handler, 0);
+1 -13
View File
@@ -2,11 +2,10 @@ use crate::{
memory::{
AddressSpace, CachePolicy, FrameAllocator, PagePermissions, PhysicalAddr, VirtualAddr,
},
platform::acpi::{InterruptPolarity, IoApicInfo, TriggerMode},
platform::acpi::{InterruptPolarity, TriggerMode},
println,
};
const IOREGSEL: usize = 0x00;
const IOWIN: usize = 0x10;
const IOAPIC_ID: u8 = 0x00;
@@ -132,17 +131,6 @@ impl IoApic {
}
}
fn read_redirection(&mut self, gsi: u32) -> Result<u64, IoApicError> {
let index = self.redirection_index(gsi)?;
let register = u8::try_from(IOAPIC_REDIRECTION_BASE as u32 + index * 2)
.map_err(|_| IoApicError::InvalidRedirectionIndex)?;
let low = self.read(register);
let high = self.read(register + 1);
Ok((high as u64) << 32 | low as u64)
}
fn redirection_registers(&mut self, gsi: u32) -> Result<(u8, u8), IoApicError> {
let index = self.redirection_index(gsi)?;
let low_register = u8::try_from(IOAPIC_REDIRECTION_BASE as u32 + index * 2)
+24 -32
View File
@@ -76,14 +76,6 @@ pub fn init_interrupt_controller(
let mut local_apic = apic::LocalApic::init(local_apic_address, allocator, address_space)
.map_err(|err| InterruptInitError::LocalApicError(err))?;
local_apic
.send_self_ipi()
.map_err(|err| InterruptInitError::LocalApicError(err))?;
local_apic
.test_timer_interrupt()
.map_err(|err| InterruptInitError::LocalApicError(err))?;
let io_apic_info = madt
.sole_io_apic()
.map_err(|_| InterruptInitError::FailedToGetIoApic)?;
@@ -133,36 +125,36 @@ pub fn init_interrupt_controller(
})
}
#[derive(Debug)]
pub enum TimerError {
DurationOverflow,
}
// #[derive(Debug)]
// pub enum TimerError {
// DurationOverflow,
// }
impl InterruptController {
pub fn delay(&self, duration: core::time::Duration) -> Result<(), TimerError> {
let nanoseconds = duration.as_nanos();
// impl InterruptController {
// pub fn delay(&self, duration: core::time::Duration) -> Result<(), TimerError> {
// let nanoseconds = duration.as_nanos();
let ticks = (nanoseconds
.checked_mul(self.local_timer_frequency as u128)
.ok_or(TimerError::DurationOverflow)?
+ 999_999_999)
/ 1_000_000_000;
// let ticks = (nanoseconds
// .checked_mul(self.local_timer_frequency as u128)
// .ok_or(TimerError::DurationOverflow)?
// + 999_999_999)
// / 1_000_000_000;
if ticks == 0 {
return Ok(());
}
// if ticks == 0 {
// return Ok(());
// }
let mut remaining = ticks;
// let mut remaining = ticks;
while remaining > 0 {
let chunk = remaining.min(u32::MAX as u128) as u32;
self.local_apic.delay_ticks(chunk);
remaining -= chunk as u128;
}
// while remaining > 0 {
// let chunk = remaining.min(u32::MAX as u128) as u32;
// self.local_apic.delay_ticks(chunk);
// remaining -= chunk as u128;
// }
Ok(())
}
}
// Ok(())
// }
// }
/// # Safety
///
+1 -1
View File
@@ -123,7 +123,7 @@ impl PageTableEntry {
const WRITE_THROUGH: u64 = 1 << 3;
const CACHE_DISABLED: u64 = 1 << 4;
const PAT: u64 = 1 << 7;
// const PAT: u64 = 1 << 7;
const fn new(
physical_address: PhysicalAddr,
-2
View File
@@ -1,5 +1,3 @@
use core::arch::asm;
use crate::arch::port::write_u8;
const PIT_CHANNEL_0: u16 = 0x40;
+1 -6
View File
@@ -15,6 +15,7 @@ use crate::{
};
#[derive(Debug)]
#[allow(unused)]
enum KernelStackCreateError {
AddressOverflow,
OutOfFrames,
@@ -194,12 +195,6 @@ pub unsafe extern "C" fn kernel_main(handoff: *mut KernelHandoff) -> ! {
println!("interrupt controller: {:?}", interrupt_controller);
println!("delaying 5 seconds...");
interrupt_controller
.delay(core::time::Duration::from_secs(5))
.unwrap();
println!("done!");
hcf();
}
+1 -3
View File
@@ -4,7 +4,6 @@ use crate::{
CachePolicy, DirectMap, FRAME_SIZE, FrameAddr, FrameAllocator, KernelMemoryLayout,
MemoryRegion, MemoryRegionKind, PagePermissions, PhysicalAddr, VirtualAddr,
},
println,
};
#[derive(Debug)]
@@ -18,7 +17,6 @@ pub enum MapError {
AlreadyMapped,
MappingConflict,
UnsupportedPermissions,
OutsideAddressSpace,
OutOfMemory,
PageTableUnavailable,
CorruptedPageTable,
@@ -46,7 +44,6 @@ pub enum UnmapError {
VirtualAddressUnaligned,
NotMapped,
MappingConflict,
OutsideAddressSpace,
PageTableUnavailable,
CorruptedPageTable,
}
@@ -65,6 +62,7 @@ impl From<PageTableUnmapError> for UnmapError {
}
#[derive(Debug)]
#[allow(unused)]
pub enum AddressSpaceCreateError {
AddressOutsideDirectMap,
PhysicalAddressTooLarge,
-8
View File
@@ -283,14 +283,6 @@ impl FrameAllocator {
};
}
pub const fn free_frames(&self) -> usize {
self.free_frames
}
pub const fn allocatable_frames(&self) -> usize {
self.allocatable_frames
}
fn usable_frame_range(
region: MemoryRegion,
) -> Result<core::ops::Range<usize>, FrameAllocatorInitError> {
+1
View File
@@ -1,6 +1,7 @@
mod address_space;
mod frame;
#[allow(unused)]
pub use address_space::{AddressSpace, AddressSpaceCreateError, MapError, UnmapError};
pub use frame::{FRAME_SIZE, FrameAddr, FrameAllocator, OwnedFrame};
+3 -5
View File
@@ -1,6 +1,4 @@
use crate::memory::{
AddressSpace, CachePolicy, DirectMap, FrameAllocator, PhysicalAddr, VirtualAddr,
};
use crate::memory::{DirectMap, PhysicalAddr, VirtualAddr};
#[derive(Debug)]
pub enum AcpiError {
@@ -10,9 +8,7 @@ pub enum AcpiError {
InvalidRootTableLength,
MalformedAcpiTable,
MalformedMadt,
MissingMadt,
MissingIoApic,
MissingIsaIrqRoute,
MultipleIoApicsUnsupported,
}
@@ -296,6 +292,7 @@ pub struct Sdt {
}
#[derive(Debug)]
#[allow(unused)]
pub struct Madt<'a> {
acpi: &'a AcpiTables,
table: Sdt,
@@ -638,6 +635,7 @@ pub struct LocalX2ApicEntry {
}
#[derive(Clone, Copy, Debug)]
#[allow(unused)]
pub enum MadtEntry {
LocalApic(LocalApicEntry),
IoApic(IoApicEntry),