fix: cleanup
This commit is contained in:
+20
-124
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
|
||||
///
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use core::arch::asm;
|
||||
|
||||
use crate::arch::port::write_u8;
|
||||
|
||||
const PIT_CHANNEL_0: u16 = 0x40;
|
||||
|
||||
+1
-6
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,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};
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user