Skip to main content

kernel/utilities/
machine_register.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2024.
4
5//! Machine-specific register-sized type.
6//!
7//! This type holds exactly one machine register of data. This type should be
8//! used when storing a value that is exactly the contents of a register with no
9//! additional type information.
10//!
11//! Tock defines this as a custom type as there is currently (Nov 2024) no
12//! suitable standard type for this purpose that is correct across all hardware
13//! architectures Tock supports. The closest suitable type is `*mut ()`.
14//! However, in hybrid CHERI `*mut ()` is smaller than a full register.
15
16use core::fmt::{Formatter, LowerHex, UpperHex};
17
18use super::capability_ptr::CapabilityPtr;
19
20/// [`MachineRegister`] is a datatype that can hold exactly the contents of a
21/// register with no additional semantic information.
22///
23/// [`MachineRegister`] is useful when you know data is the size of a register,
24/// but not its true data type. In the future it may be possible, useful, or
25/// necessary to change the implementation of [`MachineRegister`], however, the
26/// semantics will remain. No use of [`MachineRegister`] should assume a
27/// particular Rust implementation or any semantics other this description.
28#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
29#[repr(transparent)]
30pub struct MachineRegister {
31    // We store the actual data as a CapabilityPtr as a convenient way to hold
32    // an architecture-specific register's worth of data. `value` may or may not
33    // really be a CapabilityPtr: it may instead contain an integer.
34    value: CapabilityPtr,
35}
36
37impl From<CapabilityPtr> for MachineRegister {
38    /// Creates a [`MachineRegister`] containing this [`CapabilityPtr`],
39    /// including its provenance.
40    fn from(from: CapabilityPtr) -> Self {
41        Self { value: from }
42    }
43}
44
45// Note: `From<usize> for MachineRegister` is implemented in the capability_ptr
46// module.
47
48impl UpperHex for MachineRegister {
49    #[inline]
50    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
51        UpperHex::fmt(&self.value, f)
52    }
53}
54
55impl LowerHex for MachineRegister {
56    #[inline]
57    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
58        LowerHex::fmt(&self.value, f)
59    }
60}
61
62impl MachineRegister {
63    /// Returns this [`MachineRegister`] as a [`CapabilityPtr`].
64    ///
65    /// If this [`MachineRegister`] contains a pointer with provenance and/or
66    /// authority, the returned [`CapabilityPtr`] will have the same provenance
67    /// and/or authority.
68    pub fn as_capability_ptr(self) -> CapabilityPtr {
69        self.value
70    }
71
72    /// Returns this [`MachineRegister`] as a [`usize`].
73    ///
74    /// This is intended for use on [`MachineRegister`]s created from a
75    /// [`usize`], in which case the original [`usize`] will be returned. If
76    /// this [`MachineRegister`] was created from a pointer, this returns the
77    /// pointer's address (without exposing provenance).
78    pub fn as_usize(self) -> usize {
79        self.value.addr()
80    }
81
82    /// Returns this [`MachineRegister`] as a [`usize`], 32 bits only.
83    ///
84    /// This returns a `usize`, but only uses the lowest 32 bits from the
85    /// [`MachineRegister`]. If there are upper bits, they are set to 0. This is
86    /// useful for capturing only the lower 32 bits on a 64-bit machine.
87    ///
88    /// This is intended for use on [`MachineRegister`]s created from a
89    /// [`usize`], in which case 32 bits of the original [`usize`] will be
90    /// returned. If this [`MachineRegister`] was created from a pointer, this
91    /// returns the lowest 32 bits of the pointer's address (without exposing
92    /// provenance).
93    pub fn as_usize_32bit(self) -> usize {
94        self.value.addr() & 0xFFFF_FFFF
95    }
96}