kernel/utilities/
static_ref.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 2022.
4
5//! Wrapper type for safe pointers to static memory.
6
7use core::ops::Deref;
8use core::ptr::NonNull;
9
10/// A pointer to statically allocated mutable data such as memory mapped I/O
11/// registers.
12///
13/// This is a simple wrapper around a raw pointer that encapsulates an unsafe
14/// dereference in a safe manner. It serve the role of creating a `&'static T`
15/// given a raw address and acts similarly to `extern` definitions, except
16/// [`StaticRef`] is subject to module and crate boundaries, while `extern`
17/// definitions can be imported anywhere.
18///
19/// Because this defers the actual dereference, this can be put in a `const`,
20/// whereas `const I32_REF: &'static i32 = unsafe { &*(0x1000 as *const i32) };`
21/// will always fail to compile since `0x1000` doesn't have an allocation at
22/// compile time, even if it's known to be a valid MMIO address.
23#[derive(Debug)]
24pub struct StaticRef<T> {
25    ptr: NonNull<T>,
26}
27
28impl<T> StaticRef<T> {
29    /// Create a new [`StaticRef`] from a raw pointer
30    ///
31    /// ## Safety
32    ///
33    /// - `ptr` must be aligned, non-null, and dereferencable as `T`.
34    /// - `*ptr` must be valid for the program duration.
35    pub const unsafe fn new(ptr: *const T) -> StaticRef<T> {
36        // SAFETY: `ptr` is non-null as promised by the caller.
37        StaticRef {
38            ptr: NonNull::new_unchecked(ptr.cast_mut()),
39        }
40    }
41}
42
43impl<T> Clone for StaticRef<T> {
44    fn clone(&self) -> Self {
45        *self
46    }
47}
48
49impl<T> Copy for StaticRef<T> {}
50
51impl<T> Deref for StaticRef<T> {
52    type Target = T;
53    fn deref(&self) -> &T {
54        // SAFETY: `ptr` is aligned and dereferencable for the program duration
55        // as promised by the caller of `StaticRef::new`.
56        unsafe { self.ptr.as_ref() }
57    }
58}