Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions aarch32-cpu/src/generic_timer/el0.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
//! Code and types for Generic Timer support at EL0 on Armv8-R.

use core::marker::PhantomData;

use crate::register;

/// Represents our Generic Physical Timer when we are running at EL0.
///
/// Note that for most of these APIs to work, EL0 needs to have been granted
/// access using methods like
/// [El1PhysicalTimer::el0_access_physical_counter](crate::generic_timer::El1PhysicalTimer::el0_access_physical_counter).
pub struct El0PhysicalTimer();
///
/// This type is not [Send] because it is a per-core type and should not be moved across
/// cores on an SMP system.
pub struct El0PhysicalTimer {
_phantom: PhantomData<*const u8>,
}
Comment thread
jonathanpallant marked this conversation as resolved.

impl El0PhysicalTimer {
/// Create an EL0 Timer handle for the Physical Timer.
Expand All @@ -17,11 +24,13 @@ impl El0PhysicalTimer {
///
/// # Safety
///
/// Only create one of these at any given time, as they access shared
/// mutable state within the processor and do read-modify-writes on that
/// state.
/// Only create one Physical Timer handle (at any EL) at any given time, as
/// they access shared mutable state within the processor and do
/// read-modify-writes on that state.
pub unsafe fn new() -> El0PhysicalTimer {
El0PhysicalTimer()
El0PhysicalTimer {
_phantom: PhantomData,
}
}
}

Expand Down Expand Up @@ -80,17 +89,25 @@ impl super::GenericTimer for El0PhysicalTimer {
/// Note that for most of these APIs to work, EL0 needs to have been granted
/// access using methods like
/// [El1VirtualTimer::el0_access_virtual_counter](crate::generic_timer::El1VirtualTimer::el0_access_virtual_counter).
pub struct El0VirtualTimer();
///
/// This type is not [Send] because it is a per-core type and should not be moved across
/// cores on an SMP system.
pub struct El0VirtualTimer {
_phantom: PhantomData<*const u8>,
}

impl El0VirtualTimer {
/// Create an EL0 Timer handle for the Virtual Timer.
///
/// # Safety
///
/// Only create one of these at any given time, as they access shared
/// mutable state within the processor and do read-modify-writes on that state.
/// Only create one Virtual Timer handle (at any EL) at any given time, as
/// they access shared mutable state within the processor and do
/// read-modify-writes on that state.
pub unsafe fn new() -> El0VirtualTimer {
El0VirtualTimer()
El0VirtualTimer {
_phantom: PhantomData,
}
}
}

Expand Down
22 changes: 18 additions & 4 deletions aarch32-cpu/src/generic_timer/el1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@ use crate::register;
use super::{El0PhysicalTimer, El0VirtualTimer, GenericTimer};

/// Represents our Physical Timer when we are running at EL1.
///
/// This works exactly like [El0PhysicalTimer], but it gives you extra methods
/// for functionality that only processors running at EL1 can access.
///
/// This type is not [Send] because it is a per-core type and should not be moved across
/// cores on an SMP system.
pub struct El1PhysicalTimer(pub(crate) El0PhysicalTimer);

impl El1PhysicalTimer {
/// Create an EL1 Generic Timer handle
///
/// # Safety
///
/// Only create one of these at any given time, as they access shared
/// mutable state within the processor and do read-modify-writes on that state.
/// Only create one Physical Timer handle (at any EL) at any given time, as
/// they access shared mutable state within the processor and do
/// read-modify-writes on that state.
pub unsafe fn new() -> El1PhysicalTimer {
unsafe { El1PhysicalTimer(El0PhysicalTimer::new()) }
}
Expand Down Expand Up @@ -80,15 +87,22 @@ impl GenericTimer for El1PhysicalTimer {
}

/// Represents our Virtual Timer when we are running at EL1.
///
/// This works exactly like [El0VirtualTimer], but it gives you extra methods
/// for functionality that only processors running at EL1 can access.
///
/// This type is not [Send] because it is a per-core type and should not be moved across
/// cores on an SMP system.
pub struct El1VirtualTimer(El0VirtualTimer);

impl El1VirtualTimer {
/// Create an EL1 Generic Timer handle
///
/// # Safety
///
/// Only create one of these at any given time, as they access shared
/// mutable state within the processor and do read-modify-writes on that state.
/// Only create one Virtual Timer handle (at any EL) at any given time, as
/// they access shared mutable state within the processor and do
/// read-modify-writes on that state.
pub unsafe fn new() -> El1VirtualTimer {
unsafe { El1VirtualTimer(El0VirtualTimer::new()) }
}
Expand Down
46 changes: 37 additions & 9 deletions aarch32-cpu/src/generic_timer/el2.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
//! Code and types for Generic Timer support at EL2 on Armv8-R.

use core::marker::PhantomData;

use crate::register;

use super::{El1PhysicalTimer, El1VirtualTimer, GenericTimer};

/// Represents our Physical Timer when we are running at EL2.
///
/// This works exactly like [El1PhysicalTimer], but it gives you extra methods
/// for functionality that only processors running at EL2 can access.
///
/// This type is not [Send] because it is a per-core type and should not be moved across
/// cores on an SMP system.
pub struct El2PhysicalTimer(El1PhysicalTimer);

impl El2PhysicalTimer {
/// Create an EL2 Physical Timer handle
///
/// # Safety
///
/// Only create one of these at any given time, as they access shared
/// mutable state within the processor and do read-modify-writes on that state.
/// Only create one Physical Timer handle (at any EL) at any given time, as
/// they access shared mutable state within the processor and do
/// read-modify-writes on that state.
pub unsafe fn new() -> El2PhysicalTimer {
unsafe { El2PhysicalTimer(El1PhysicalTimer::new()) }
}
Expand Down Expand Up @@ -76,15 +85,22 @@ impl GenericTimer for El2PhysicalTimer {
}

/// Represents our Virtual Timer when we are running at EL1.
///
/// This works exactly like [El1VirtualTimer], but it gives you extra methods
/// for functionality that only processors running at EL2 can access.
///
/// This type is not [Send] because it is a per-core type and should not be moved
/// across cores on an SMP system.
pub struct El2VirtualTimer(El1VirtualTimer);

impl El2VirtualTimer {
/// Create an EL2 Generic Timer handle
/// Create an EL2 Virtual Timer handle
///
/// # Safety
///
/// Only create one of these at any given time, as they access shared
/// mutable state within the processor and do read-modify-writes on that state.
/// Only create one Virtual Timer handle (at any EL) at any given time, as
/// they access shared mutable state within the processor and do
/// read-modify-writes on that state.
pub unsafe fn new() -> El2VirtualTimer {
unsafe { El2VirtualTimer(El1VirtualTimer::new()) }
}
Expand Down Expand Up @@ -146,18 +162,30 @@ impl GenericTimer for El2VirtualTimer {
}
}

/// Represents our Hypervisor-specific Physical Timer when we are running at EL1.
pub struct El2HypPhysicalTimer();
/// Represents our Hypervisor-specific Physical Timer.
///
/// This is designed for use by a hypervisor, whilst an EL1 application
/// concurrently uses the Physical Timer and/or the Virtual Timer.
///
/// This type is not [Send] because it is a per-core type and should not be moved across
/// cores on an SMP system.
pub struct El2HypPhysicalTimer {
_phantom: PhantomData<*const u8>,
}

impl El2HypPhysicalTimer {
/// Create a Timer handle for the EL2-specific Hyp Physical Timer.
///
/// # Safety
///
/// Only create one of these at any given time, as they access shared
/// mutable state within the processor and do read-modify-writes on that state.
/// mutable state within the processor and do read-modify-writes on that
/// state. This timer is distinct from the Physical Timer and the Virtual
/// Timer, and so can exist concurrently.
pub unsafe fn new() -> El2HypPhysicalTimer {
El2HypPhysicalTimer()
El2HypPhysicalTimer {
_phantom: PhantomData,
}
}
}

Expand Down
Loading