arm_gic_driver/lib.rs
1#![no_std]
2
3//! # ARM GIC Driver
4//!
5//! A driver for the ARM Generic Interrupt Controller (GIC).
6//!
7//! ## Platform Support
8//!
9//! This driver is designed for ARM AArch64 systems and provides:
10//!
11//! - **GICv2 support**: Available on both 32-bit and 64-bit ARM platforms
12//! - **GICv3 support**: Only available on 64-bit ARM (AArch64) platforms
13//! - **System Register access**: Only available on AArch64 platforms
14//!
15//! ### Platform-Specific Modules
16//!
17//! - The [`v3`] module is **only available on AArch64** (`target_arch = "aarch64"`)
18//!
19//! If you're working on a non-ARM platform, most of this driver's functionality
20//! will not be available at compile time.
21
22pub(crate) mod define;
23pub mod sys_reg;
24
25#[cfg(test)]
26mod tests;
27mod version;
28
29use core::{
30 fmt::{Debug, Display},
31 ptr::NonNull,
32};
33
34pub use define::IntId;
35pub use version::*;
36
37/// Virtual address wrapper for memory-mapped register access.
38///
39/// This type provides a safe wrapper around virtual addresses used for accessing
40/// memory-mapped registers in the GIC. It ensures type safety while allowing
41/// efficient pointer operations.
42///
43/// # Examples
44///
45/// ```no_run
46/// use arm_gic_driver::VirtAddr;
47///
48/// let addr = VirtAddr::new(0xF900_0000);
49/// let ptr: *mut u32 = addr.as_ptr();
50/// ```
51#[repr(transparent)]
52#[derive(Copy, Clone, Debug, Eq, PartialEq)]
53pub struct VirtAddr(usize);
54
55impl VirtAddr {
56 /// Create a new `VirtAddr` from a raw address value.
57 ///
58 /// # Arguments
59 ///
60 /// * `val` - The virtual address as a usize value
61 ///
62 /// # Examples
63 ///
64 /// ```
65 /// use arm_gic_driver::VirtAddr;
66 ///
67 /// let addr = VirtAddr::new(0xF900_0000);
68 /// ```
69 pub const fn new(val: usize) -> Self {
70 Self(val)
71 }
72
73 /// Get the virtual address as a raw pointer of the specified type.
74 ///
75 /// # Type Parameters
76 ///
77 /// * `T` - The target pointer type
78 ///
79 /// # Returns
80 ///
81 /// A raw mutable pointer to type `T`
82 ///
83 /// # Safety
84 ///
85 /// The caller must ensure that:
86 /// - The address is valid for the target type `T`
87 /// - The memory region is properly mapped and accessible
88 /// - Appropriate synchronization is used for concurrent access
89 ///
90 /// # Examples
91 ///
92 /// ```no_run
93 /// use arm_gic_driver::VirtAddr;
94 ///
95 /// let addr = VirtAddr::new(0xF900_0000);
96 /// let ptr: *mut u32 = addr.as_ptr();
97 /// ```
98 pub const fn as_ptr<T>(&self) -> *mut T {
99 self.0 as *mut T
100 }
101}
102
103impl From<usize> for VirtAddr {
104 fn from(addr: usize) -> Self {
105 Self(addr)
106 }
107}
108
109impl From<VirtAddr> for usize {
110 fn from(addr: VirtAddr) -> Self {
111 addr.0
112 }
113}
114
115impl From<*mut u8> for VirtAddr {
116 fn from(addr: *mut u8) -> Self {
117 Self(addr as usize)
118 }
119}
120
121impl<T> From<NonNull<T>> for VirtAddr {
122 fn from(addr: NonNull<T>) -> Self {
123 Self(addr.as_ptr() as usize)
124 }
125}
126
127impl Display for VirtAddr {
128 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
129 write!(f, "VirtAddr({:#p})", self.0 as *const u8)
130 }
131}