diff --git a/aarch32-cpu/src/generic_timer/el0.rs b/aarch32-cpu/src/generic_timer/el0.rs index 90dd61f..192c01b 100644 --- a/aarch32-cpu/src/generic_timer/el0.rs +++ b/aarch32-cpu/src/generic_timer/el0.rs @@ -1,5 +1,7 @@ //! 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. @@ -7,7 +9,12 @@ use crate::register; /// 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>, +} impl El0PhysicalTimer { /// Create an EL0 Timer handle for the Physical Timer. @@ -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, + } } } @@ -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, + } } } diff --git a/aarch32-cpu/src/generic_timer/el1.rs b/aarch32-cpu/src/generic_timer/el1.rs index 9af1d90..dde027f 100644 --- a/aarch32-cpu/src/generic_timer/el1.rs +++ b/aarch32-cpu/src/generic_timer/el1.rs @@ -5,6 +5,12 @@ 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 { @@ -12,8 +18,9 @@ impl El1PhysicalTimer { /// /// # 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()) } } @@ -80,6 +87,12 @@ 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 { @@ -87,8 +100,9 @@ impl El1VirtualTimer { /// /// # 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()) } } diff --git a/aarch32-cpu/src/generic_timer/el2.rs b/aarch32-cpu/src/generic_timer/el2.rs index fd34c91..3b0aba6 100644 --- a/aarch32-cpu/src/generic_timer/el2.rs +++ b/aarch32-cpu/src/generic_timer/el2.rs @@ -1,10 +1,18 @@ //! 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 { @@ -12,8 +20,9 @@ impl El2PhysicalTimer { /// /// # 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()) } } @@ -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()) } } @@ -146,8 +162,16 @@ 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. @@ -155,9 +179,13 @@ impl El2HypPhysicalTimer { /// # 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, + } } }