• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Support for single-register read/write access.
2 
3 use crate::arch::Arch;
4 use crate::target::Target;
5 use crate::target::TargetResult;
6 
7 /// Target Extension - Support for single-register access.
8 ///
9 /// While this is an optional feature, it is **highly recommended** to
10 /// implement it when possible, as it can significantly improve performance
11 /// on certain architectures.
12 ///
13 /// If this extension is not implemented, the GDB client will fall-back to
14 /// accessing _all_ registers, even in cases where it only requires knowing a
15 /// single register's value.
16 ///
17 /// Moreover, certain architectures have registers that are not accessible as
18 /// part of the default default register file used by the `read/write_registers`
19 /// methods, and can only be accessed via this extension (e.g: the RISC-V
20 /// Control and Status registers).
21 pub trait SingleRegisterAccess<Tid>: Target
22 where
23     Tid: crate::is_valid_tid::IsValidTid,
24 {
25     /// Read to a single register on the target.
26     ///
27     /// The `tid` field identifies which thread the value should be read from.
28     /// On single threaded targets, `tid` is set to `()` and can be ignored.
29     ///
30     /// Implementations should write the value of the register using target's
31     /// native byte order in the buffer `buf`.
32     ///
33     /// Return the number of bytes written into `buf` or `0` if the register is
34     /// valid but unavailable.
35     ///
36     /// If the requested register could not be accessed, an appropriate
37     /// non-fatal error should be returned.
read_register( &mut self, tid: Tid, reg_id: <Self::Arch as Arch>::RegId, buf: &mut [u8], ) -> TargetResult<usize, Self>38     fn read_register(
39         &mut self,
40         tid: Tid,
41         reg_id: <Self::Arch as Arch>::RegId,
42         buf: &mut [u8],
43     ) -> TargetResult<usize, Self>;
44 
45     /// Write from a single register on the target.
46     ///
47     /// The `tid` field identifies which thread the value should be written to.
48     /// On single threaded targets, `tid` is set to `()` and can be ignored.
49     ///
50     /// The `val` buffer contains the new value of the register in the target's
51     /// native byte order. It is guaranteed to be the exact length as the target
52     /// register.
53     ///
54     /// If the requested register could not be accessed, an appropriate
55     /// non-fatal error should be returned.
write_register( &mut self, tid: Tid, reg_id: <Self::Arch as Arch>::RegId, val: &[u8], ) -> TargetResult<(), Self>56     fn write_register(
57         &mut self,
58         tid: Tid,
59         reg_id: <Self::Arch as Arch>::RegId,
60         val: &[u8],
61     ) -> TargetResult<(), Self>;
62 }
63 
64 /// See [`SingleRegisterAccess`]
65 pub type SingleRegisterAccessOps<'a, Tid, T> =
66     &'a mut dyn SingleRegisterAccess<Tid, Arch = <T as Target>::Arch, Error = <T as Target>::Error>;
67