blob: 2887feff15e94891879bafdd75276a5bfe80e09d [file] [log] [blame]
//! Support for single-register read/write access.
use crate::arch::Arch;
use crate::target::{Target, TargetResult};
/// Target Extension - Support for single-register access.
///
/// While this is an optional feature, it is **highly recommended** to
/// implement it when possible, as it can significantly improve performance
/// on certain architectures.
///
/// If this extension is not implemented, the GDB client will fall-back to
/// accessing _all_ registers, even in cases where it only requires knowing a
/// single register's value.
///
/// Moreover, certain architectures have registers that are not accessible as
/// part of the default default register file used by the `read/write_registers`
/// methods, and can only be accessed via this extension (e.g: the RISC-V
/// Control and Status registers).
pub trait SingleRegisterAccess<Tid>: Target
where
Tid: crate::is_valid_tid::IsValidTid,
{
/// Read to a single register on the target.
///
/// The `tid` field identifies which thread the value should be read from.
/// On single threaded targets, `tid` is set to `()` and can be ignored.
///
/// Implementations should write the value of the register using target's
/// native byte order in the buffer `buf`.
///
/// Return the number of bytes written into `buf` or `0` if the register is
/// valid but unavailable.
///
/// If the requested register could not be accessed, an appropriate
/// non-fatal error should be returned.
fn read_register(
&mut self,
tid: Tid,
reg_id: <Self::Arch as Arch>::RegId,
buf: &mut [u8],
) -> TargetResult<usize, Self>;
/// Write from a single register on the target.
///
/// The `tid` field identifies which thread the value should be written to.
/// On single threaded targets, `tid` is set to `()` and can be ignored.
///
/// The `val` buffer contains the new value of the register in the target's
/// native byte order. It is guaranteed to be the exact length as the target
/// register.
///
/// If the requested register could not be accessed, an appropriate
/// non-fatal error should be returned.
fn write_register(
&mut self,
tid: Tid,
reg_id: <Self::Arch as Arch>::RegId,
val: &[u8],
) -> TargetResult<(), Self>;
}
/// See [`SingleRegisterAccess`]
pub type SingleRegisterAccessOps<'a, Tid, T> =
&'a mut dyn SingleRegisterAccess<Tid, Arch = <T as Target>::Arch, Error = <T as Target>::Error>;