summaryrefslogtreecommitdiff
path: root/kernel/src/interrupts/apic.rs
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src/interrupts/apic.rs')
-rw-r--r--kernel/src/interrupts/apic.rs45
1 files changed, 35 insertions, 10 deletions
diff --git a/kernel/src/interrupts/apic.rs b/kernel/src/interrupts/apic.rs
index 3d42ba9..dc1177b 100644
--- a/kernel/src/interrupts/apic.rs
+++ b/kernel/src/interrupts/apic.rs
@@ -84,7 +84,8 @@ pub enum TimerDivideConfig {
static mut LOCAL_APIC: Option<Apic> = None;
pub unsafe fn set_local_apic(apic: Apic) -> &'static mut Apic {
- LOCAL_APIC.get_or_insert(apic)
+ LOCAL_APIC = Some(apic);
+ LOCAL_APIC.as_mut().unwrap()
}
pub unsafe fn get_local_apic() -> Option<&'static mut Apic> {
@@ -100,18 +101,27 @@ impl Apic {
if !is_apic() { return None; }
Self::disable_pic();
let mut base_apic = unsafe { Msr::new(APIC_BASE_MSR).read() };
+ //panic!("msr{:x}", base_apic);
+ unsafe { Msr::new(APIC_BASE_MSR).write(base_apic) };
let mut apic = Self::from_base_apic(base_apic);
+ //panic!("msr{:08x}", apic.regs as usize);
- let spurious = apic.get(ApicRegister::SpuriousInterruptVec) | 0x1ff;
+ // let spurious = apic.get(ApicRegister::SpuriousInterruptVec) | 0x1ff;
- unsafe { Msr::new(APIC_BASE_MSR).write(base_apic | APIC_FLAG) };
-
- apic.set(ApicRegister::SpuriousInterruptVec, spurious);
+ apic.set(ApicRegister::LogicalDst, 0);
apic.set(ApicRegister::TaskPriority, 0);
+ apic.set(ApicRegister::LvtTimer, APIC_DISABLE);
apic.set(ApicRegister::LvtPerformanceMonitor, APIC_NMI);
apic.set(ApicRegister::LvtLint0, APIC_DISABLE);
apic.set(ApicRegister::LvtLint1, APIC_DISABLE);
+ apic.set(ApicRegister::DstFmt, 0x0FFFFFFF);
+ apic.set(ApicRegister::LvtError, super::InterruptType::ApicError.as_u8().into());
+ apic.set(ApicRegister::ErrorStatus, 0);
+
+ unsafe { Msr::new(APIC_BASE_MSR).write(base_apic | APIC_FLAG) };
+
+ apic.set(ApicRegister::SpuriousInterruptVec, 0x1ff);
Some(apic)
}
@@ -129,16 +139,18 @@ impl Apic {
}
}
- fn ptr(&self) -> *const u32 { self.regs as *const u32 }
+ pub fn ptr(&self) -> *const u32 { self.regs as *const u32 }
fn ptr_mut(&mut self) -> *mut u32 { self.regs as *mut u32 }
pub fn get(&self, register: ApicRegister) -> u32 {
- unsafe { self.ptr().offset(register as isize).read_volatile() }
+ unsafe { ((self.ptr() as usize + (register as usize) * 4) as *const u32).read_volatile() }
+ //unsafe { self.ptr().offset(register as isize).read_volatile() }
}
pub fn set(&mut self, register: ApicRegister, val: u32) {
- unsafe { self.ptr_mut().offset(register as isize).write_volatile(val) }
+ unsafe { ((self.ptr() as usize + (register as usize) * 4) as *mut u32).write_volatile(val) }
+ //unsafe { self.ptr_mut().offset(register as isize).write_volatile(val) }
}
pub fn set_interrupt_command(&mut self, dst: u8, v: u8) {
@@ -152,8 +164,21 @@ impl Apic {
}
pub fn set_timer_interrupt_handler(&mut self, divide: TimerDivideConfig, intr: super::InterruptType) {
- self.set(ApicRegister::LvtTimer, intr.as_u8().into());
+ self.set(ApicRegister::LvtTimer, intr.as_u8() as u32 | (1 << 17));
self.set(ApicRegister::TimerDivideConfig, divide as u32);
- self.set(ApicRegister::TimerInitialCount, 0xFFFFFFFF)
+ self.set(ApicRegister::TimerInitialCount, 2048);
+ self.set(ApicRegister::TimerCurrentCount, 2048)
+ }
+
+ pub fn get_timer_value(&self) -> u32 {
+ self.get(ApicRegister::TimerCurrentCount)
+ }
+
+ pub fn get_error_code(&self) -> u32 {
+ self.get(ApicRegister::ErrorStatus)
+ }
+
+ pub fn get_id(&self) -> u32 {
+ self.get(ApicRegister::ApicId)
}
}