mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-29 16:13:27 +00:00
Rename aster-frame to ostd
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
fb59fa7a55
commit
59350a8578
93
ostd/src/arch/x86/kernel/apic/mod.rs
Normal file
93
ostd/src/arch/x86/kernel/apic/mod.rs
Normal file
@ -0,0 +1,93 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use log::info;
|
||||
use spin::Once;
|
||||
|
||||
use crate::sync::SpinLock;
|
||||
|
||||
pub mod ioapic;
|
||||
pub mod x2apic;
|
||||
pub mod xapic;
|
||||
|
||||
pub static APIC_INSTANCE: Once<Arc<SpinLock<dyn Apic + 'static>>> = Once::new();
|
||||
|
||||
pub trait Apic: ApicTimer + Sync + Send {
|
||||
fn id(&self) -> u32;
|
||||
|
||||
fn version(&self) -> u32;
|
||||
|
||||
/// End of Interrupt, this function will inform APIC that this interrupt has been processed.
|
||||
fn eoi(&mut self);
|
||||
}
|
||||
|
||||
pub trait ApicTimer: Sync + Send {
|
||||
/// Sets the initial timer count, the APIC timer will count down from this value.
|
||||
fn set_timer_init_count(&mut self, value: u64);
|
||||
|
||||
/// Gets the current count of the timer.
|
||||
/// The interval can be expressed by the expression: `init_count` - `current_count`.
|
||||
fn timer_current_count(&self) -> u64;
|
||||
|
||||
/// Sets the timer register in the APIC.
|
||||
/// Bit 0-7: The interrupt vector of timer interrupt.
|
||||
/// Bit 12: Delivery Status, 0 for Idle, 1 for Send Pending.
|
||||
/// Bit 16: Mask bit.
|
||||
/// Bit 17-18: Timer Mode, 0 for One-shot, 1 for Periodic, 2 for TSC-Deadline.
|
||||
fn set_lvt_timer(&mut self, value: u64);
|
||||
|
||||
/// Sets timer divide config register.
|
||||
fn set_timer_div_config(&mut self, div_config: DivideConfig);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ApicInitError {
|
||||
/// No x2APIC or xAPIC found.
|
||||
NoApic,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(u32)]
|
||||
pub enum DivideConfig {
|
||||
Divide1 = 0b1011,
|
||||
Divide2 = 0b0000,
|
||||
Divide4 = 0b0001,
|
||||
Divide8 = 0b0010,
|
||||
Divide16 = 0b0011,
|
||||
Divide32 = 0b1000,
|
||||
Divide64 = 0b1001,
|
||||
Divide128 = 0b1010,
|
||||
}
|
||||
|
||||
pub fn init() -> Result<(), ApicInitError> {
|
||||
crate::arch::x86::kernel::pic::disable_temp();
|
||||
if let Some(mut x2apic) = x2apic::X2Apic::new() {
|
||||
x2apic.enable();
|
||||
let version = x2apic.version();
|
||||
info!(
|
||||
"x2APIC ID:{:x}, Version:{:x}, Max LVT:{:x}",
|
||||
x2apic.id(),
|
||||
version & 0xff,
|
||||
(version >> 16) & 0xff
|
||||
);
|
||||
APIC_INSTANCE.call_once(|| Arc::new(SpinLock::new(x2apic)));
|
||||
Ok(())
|
||||
} else if let Some(mut xapic) = xapic::XApic::new() {
|
||||
xapic.enable();
|
||||
let version = xapic.version();
|
||||
info!(
|
||||
"xAPIC ID:{:x}, Version:{:x}, Max LVT:{:x}",
|
||||
xapic.id(),
|
||||
version & 0xff,
|
||||
(version >> 16) & 0xff
|
||||
);
|
||||
APIC_INSTANCE.call_once(|| Arc::new(SpinLock::new(xapic)));
|
||||
Ok(())
|
||||
} else {
|
||||
log::warn!("Not found x2APIC or xAPIC");
|
||||
Err(ApicInitError::NoApic)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user