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

The number of ticks the timer does per millisecond.

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() -> Self

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.

source

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

Setup the LAPIC timer.

source

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

Setup the LAPIC timer with a raw counter and divider.

source

pub fn timer_enable(&self, enable: bool)

Enable or disable the LAPIC timer.

source

fn measure_timer_ticks(&self) -> usize

Determines the LAPIC timer frequency.

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 delivered(&self) -> bool

Check if the previously sent IPI has reached its destination.

source

pub fn send(&self, destination: Destination, vector: Vector)

Send an Inter-Processor Interrupt (IPI).

source

pub fn send_init(&self, core: u8)

Send an Init request IPI to another processor.

source

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

Send a Startup IPI to another processor.

source

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

Read-modify-write a memory mapped register.

source

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

Read-modify-write two memory mapped registers.

source

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

Write a memory mapped register.

source

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

Read a memory mapped register.

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 !Freeze for LApic

§

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
source§

impl<T> Az for T

source§

fn az<Dst>(self) -> Dst
where T: Cast<Dst>,

Casts the value.
§

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
source§

impl<Src, Dst> CastFrom<Src> for Dst
where Src: Cast<Dst>,

source§

fn cast_from(src: Src) -> Dst

Casts the value.
source§

impl<T> CheckedAs for T

source§

fn checked_as<Dst>(self) -> Option<Dst>
where T: CheckedCast<Dst>,

Casts the value.
source§

impl<Src, Dst> CheckedCastFrom<Src> for Dst
where Src: CheckedCast<Dst>,

source§

fn checked_cast_from(src: Src) -> Option<Dst>

Casts the value.
§

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.

source§

impl<T> OverflowingAs for T

source§

fn overflowing_as<Dst>(self) -> (Dst, bool)
where T: OverflowingCast<Dst>,

Casts the value.
source§

impl<Src, Dst> OverflowingCastFrom<Src> for Dst
where Src: OverflowingCast<Dst>,

source§

fn overflowing_cast_from(src: Src) -> (Dst, bool)

Casts the value.
source§

impl<T> SaturatingAs for T

source§

fn saturating_as<Dst>(self) -> Dst
where T: SaturatingCast<Dst>,

Casts the value.
source§

impl<Src, Dst> SaturatingCastFrom<Src> for Dst
where Src: SaturatingCast<Dst>,

source§

fn saturating_cast_from(src: Src) -> Dst

Casts the value.
§

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

impl<T> UnwrappedAs for T

source§

fn unwrapped_as<Dst>(self) -> Dst
where T: UnwrappedCast<Dst>,

Casts the value.
source§

impl<Src, Dst> UnwrappedCastFrom<Src> for Dst
where Src: UnwrappedCast<Dst>,

source§

fn unwrapped_cast_from(src: Src) -> Dst

Casts the value.
source§

impl<T> WrappingAs for T

source§

fn wrapping_as<Dst>(self) -> Dst
where T: WrappingCast<Dst>,

Casts the value.
source§

impl<Src, Dst> WrappingCastFrom<Src> for Dst
where Src: WrappingCast<Dst>,

source§

fn wrapping_cast_from(src: Src) -> Dst

Casts the value.