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