Struct rstubs::arch::int::lapic::LApic

source ·
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.

See https://wiki.osdev.org/APIC

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

source

pub const BASE: usize = 4_276_092_928usize

Default base address for the memory-mapped registers.

source

pub const fn new() -> LApic

Creates a new instance that has to be initialized with Self::init.

source

pub fn init(&self, cpu_id: u8)

Initialize the LAPIC fo the given cpu_id.

source

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.

source

pub fn version(&self) -> u8

Get version number of local APIC.

source

pub fn id(&self) -> u8

Get the ID of the current core’s LAPIC.

This id is also used to identify the core.

source

pub fn timer(&self, us: usize, vector: u8, periodic: bool, masked: bool)

Setup the lapic timer

source

pub fn timer_enable(&self, enable: bool)

source

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:

  1. Disable Interrupts to ensure measurement is not disturbed
  2. 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.
  3. 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.
  4. Restore previous state (disable PIT, LAPIC timer, restore interrupts)
  5. Derive the ticks per millisecond (take care, the counter is counting towards zero)
source

pub fn ipi_delivered(&self) -> bool

Check if the previously sent IPI has reached its destination.

source

pub fn ipi_send(&self, destination: IPIDestination, vector: Vector)

Send an Inter-Processor Interrupt (IPI).

source

pub fn ipi_send_init(&self, core: u8)

Send an INIT request IPI to all other processors.

source

pub fn ipi_send_startup(&self, core: u8, vector: u8)

Send an Startup IPI to all other processors.

source

fn raw_timer( &self, counter: u32, divide: u32, vector: u8, periodic: bool, masked: bool )

source

fn update<T: IOMem>(&self, f: impl FnOnce(T) -> T)

source

fn update2<A: IOMem, B: IOMem>(&self, f: impl FnOnce(A, B) -> (A, B))

source

fn write<T: IOMem>(&self, value: T)

source

fn read<T: IOMem>(&self) -> T

Trait Implementations§

source§

impl Debug for LApic

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl RefUnwindSafe for LApic

§

impl Send for LApic

§

impl Sync for LApic

§

impl Unpin for LApic

§

impl UnwindSafe for LApic

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.