pub struct LApic {
pub base: AtomicPtr<u32>,
timer_ticks: AtomicUsize,
}
Expand description
Abstracts the local APICs (which is integrated into every CPU core)
In modern (x86) PCs, every CPU core has its own Local APIC (LAPIC). The LAPIC is the link between the local CPU core and the I/O APIC (that takes care about external interrupt sources. Interrupt messages received by the LAPIC will be passed to the corresponding CPU core and trigger the interrupt handler on this core.
Fields§
§base: AtomicPtr<u32>
Base of the memory mapped lapic registers
timer_ticks: AtomicUsize
Latency of the lapic timer. This is measured an set when the first timer is created.
Implementations§
source§impl LApic
impl LApic
sourcepub const BASE: usize = 4_276_092_928usize
pub const BASE: usize = 4_276_092_928usize
Default base address for the memory-mapped registers.
sourcepub const fn new() -> LApic
pub const fn new() -> LApic
Creates a new instance that has to be initialized with Self::init.
sourcepub fn eoi(&self)
pub fn eoi(&self)
Signalizes the LAPIC that the handling of the current interrupt finished. This function must be called at the end of interrupt handling before ireting.
sourcepub fn id(&self) -> u8
pub fn id(&self) -> u8
Get the ID of the current core’s LAPIC.
This id is also used to identify the core.
pub fn timer_enable(&self, enable: bool)
sourcefn calculate_ticks(&self) -> usize
fn calculate_ticks(&self) -> usize
Determines the LAPIC timer divider.
This function will calculate the number of LAPIC-timer ticks passing in the course of one millisecond. To do so, this function will rely on PIT timer functionality and measure the tick delta between start and end of waiting for a predefined period.
For measurement, the LAPIC-timer single-shot mode (without interrupts) is used; after measurement, the timer is disabled again.
Steps taken for precise measurement of LAPIC-timer ticks per ms:
- Disable Interrupts to ensure measurement is not disturbed
- Configure a timeout of 50 ms (nearly PIT’s maximum possible delay) Using a “large” value decreases the overhead induced by measurement and thereby increases the accuracy.
- Now measure the number of passed LAPIC-timer ticks while waiting for the PIT Note that configuring the PIT takes quite some time and therefore should be done prior to starting LAPIC-timer measurement.
- Restore previous state (disable PIT, LAPIC timer, restore interrupts)
- Derive the ticks per millisecond (take care, the counter is counting towards zero)
sourcepub fn ipi_delivered(&self) -> bool
pub fn ipi_delivered(&self) -> bool
Check if the previously sent IPI has reached its destination.
sourcepub fn ipi_send(&self, destination: IPIDestination, vector: Vector)
pub fn ipi_send(&self, destination: IPIDestination, vector: Vector)
Send an Inter-Processor Interrupt (IPI).
sourcepub fn ipi_send_init(&self, core: u8)
pub fn ipi_send_init(&self, core: u8)
Send an INIT request IPI to all other processors.
sourcepub fn ipi_send_startup(&self, core: u8, vector: u8)
pub fn ipi_send_startup(&self, core: u8, vector: u8)
Send an Startup IPI to all other processors.