blob: cd2a7e686c91d92925cf5493f4839db11315af93 [file] [log] [blame]
Imre Kis9c084c02024-08-14 15:53:45 +02001// SPDX-FileCopyrightText: Copyright 2023-2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! # Peripheral Access Crate fro Arm Fixed Virtual Platform
5//!
6//! The crate provides access to the peripherals of [Arm Fixed Virtual Platform](https://developer.arm.com/Tools%20and%20Software/Fixed%20Virtual%20Platforms).
7
8#![no_std]
9
Imre Kis7c36bde2024-09-26 11:20:06 +020010use core::{
11 marker::PhantomData,
12 ops::{Deref, DerefMut},
13};
Imre Kis9c084c02024-08-14 15:53:45 +020014
15use spin::mutex::Mutex;
16
17use arm_gic::GICDRegisters;
18use arm_pl011::PL011Registers;
19use arm_sp805::SP805Registers;
20
21/// UART0 - PL011
22pub struct UART0 {
23 _marker: PhantomData<*const ()>,
24}
25
26impl UART0 {
Imre Kis7c36bde2024-09-26 11:20:06 +020027 pub const PTR: *mut PL011Registers = 0x1c09_0000 as *mut _;
Imre Kis9c084c02024-08-14 15:53:45 +020028}
29
30impl Deref for UART0 {
31 type Target = PL011Registers;
32
33 #[inline(always)]
34 fn deref(&self) -> &Self::Target {
35 unsafe { &*Self::PTR }
36 }
37}
38
Imre Kis7c36bde2024-09-26 11:20:06 +020039impl DerefMut for UART0 {
40 #[inline(always)]
41 fn deref_mut(&mut self) -> &mut Self::Target {
42 unsafe { &mut *Self::PTR }
43 }
44}
45
Imre Kis9c084c02024-08-14 15:53:45 +020046unsafe impl Send for UART0 {}
47
48/// UART1 - PL011
49pub struct UART1 {
50 _marker: PhantomData<*const ()>,
51}
52
53impl UART1 {
Imre Kis7c36bde2024-09-26 11:20:06 +020054 pub const PTR: *mut PL011Registers = 0x1c0a_0000 as *mut _;
Imre Kis9c084c02024-08-14 15:53:45 +020055}
56
57impl Deref for UART1 {
58 type Target = PL011Registers;
59
60 #[inline(always)]
61 fn deref(&self) -> &Self::Target {
62 unsafe { &*Self::PTR }
63 }
64}
65
Imre Kis7c36bde2024-09-26 11:20:06 +020066impl DerefMut for UART1 {
67 #[inline(always)]
68 fn deref_mut(&mut self) -> &mut Self::Target {
69 unsafe { &mut *Self::PTR }
70 }
71}
72
Imre Kis9c084c02024-08-14 15:53:45 +020073unsafe impl Send for UART1 {}
74
75/// UART2 - PL011
76pub struct UART2 {
77 _marker: PhantomData<*const ()>,
78}
79
80impl UART2 {
Imre Kis7c36bde2024-09-26 11:20:06 +020081 pub const PTR: *mut PL011Registers = 0x1c0b_0000 as *mut _;
Imre Kis9c084c02024-08-14 15:53:45 +020082}
83
84impl Deref for UART2 {
85 type Target = PL011Registers;
86
87 #[inline(always)]
88 fn deref(&self) -> &Self::Target {
89 unsafe { &*Self::PTR }
90 }
91}
92
Imre Kis7c36bde2024-09-26 11:20:06 +020093impl DerefMut for UART2 {
94 #[inline(always)]
95 fn deref_mut(&mut self) -> &mut Self::Target {
96 unsafe { &mut *Self::PTR }
97 }
98}
99
Imre Kis9c084c02024-08-14 15:53:45 +0200100unsafe impl Send for UART2 {}
101
102/// UART3 - PL011
103pub struct UART3 {
104 _marker: PhantomData<*const ()>,
105}
106
107impl UART3 {
Imre Kis7c36bde2024-09-26 11:20:06 +0200108 pub const PTR: *mut PL011Registers = 0x1c0c_0000 as *mut _;
Imre Kis9c084c02024-08-14 15:53:45 +0200109}
110
111impl Deref for UART3 {
112 type Target = PL011Registers;
113
114 #[inline(always)]
115 fn deref(&self) -> &Self::Target {
116 unsafe { &*Self::PTR }
117 }
118}
119
Imre Kis7c36bde2024-09-26 11:20:06 +0200120impl DerefMut for UART3 {
121 #[inline(always)]
122 fn deref_mut(&mut self) -> &mut Self::Target {
123 unsafe { &mut *Self::PTR }
124 }
125}
126
Imre Kis9c084c02024-08-14 15:53:45 +0200127unsafe impl Send for UART3 {}
128
129/// Watchdog - SP805
130#[allow(clippy::upper_case_acronyms)]
131pub struct WATCHDOG {
132 _marker: PhantomData<*const ()>,
133}
134
135impl WATCHDOG {
Imre Kis7c36bde2024-09-26 11:20:06 +0200136 pub const PTR: *mut SP805Registers = 0x1c0f_0000 as *mut _;
Imre Kis9c084c02024-08-14 15:53:45 +0200137}
138
139impl Deref for WATCHDOG {
140 type Target = SP805Registers;
141
142 #[inline(always)]
143 fn deref(&self) -> &Self::Target {
144 unsafe { &*Self::PTR }
145 }
146}
147
Imre Kis7c36bde2024-09-26 11:20:06 +0200148impl DerefMut for WATCHDOG {
149 #[inline(always)]
150 fn deref_mut(&mut self) -> &mut Self::Target {
151 unsafe { &mut *Self::PTR }
152 }
153}
154
Imre Kis9c084c02024-08-14 15:53:45 +0200155unsafe impl Send for WATCHDOG {}
156
157/// GIC Distributor
158#[allow(clippy::upper_case_acronyms)]
159pub struct GICD {
160 _marker: PhantomData<*const ()>,
161}
162
163impl GICD {
Imre Kis7c36bde2024-09-26 11:20:06 +0200164 pub const PTR: *mut GICDRegisters = 0x2f00_0000 as *mut _;
Imre Kis9c084c02024-08-14 15:53:45 +0200165}
166
167impl Deref for GICD {
168 type Target = GICDRegisters;
169
170 #[inline(always)]
171 fn deref(&self) -> &Self::Target {
172 unsafe { &*Self::PTR }
173 }
174}
175
Imre Kis7c36bde2024-09-26 11:20:06 +0200176impl DerefMut for GICD {
177 #[inline(always)]
178 fn deref_mut(&mut self) -> &mut Self::Target {
179 unsafe { &mut *Self::PTR }
180 }
181}
182
Imre Kis9c084c02024-08-14 15:53:45 +0200183unsafe impl Send for GICD {}
184
185static PERIPHERALS_TAKEN: Mutex<bool> = Mutex::new(false);
186
187/// FVP peripherals
188#[allow(non_snake_case)]
189pub struct Peripherals {
190 pub UART0: UART0,
191 pub UART1: UART1,
192 pub UART2: UART2,
193 pub UART3: UART3,
194 pub WATCHDOG: WATCHDOG,
195 pub GICD: GICD,
196}
197
198impl Peripherals {
199 /// Take the peripherals once
200 pub fn take() -> Option<Self> {
201 if !*PERIPHERALS_TAKEN.lock() {
202 Some(unsafe { Self::steal() })
203 } else {
204 None
205 }
206 }
207
208 /// Unsafe version of take()
209 ///
210 /// # Safety
211 /// The caller has to ensure that each peripheral is only used once.
212 pub unsafe fn steal() -> Self {
213 *PERIPHERALS_TAKEN.lock() = true;
214
215 Peripherals {
216 UART0: UART0 {
217 _marker: PhantomData,
218 },
219 UART1: UART1 {
220 _marker: PhantomData,
221 },
222 UART2: UART2 {
223 _marker: PhantomData,
224 },
225 UART3: UART3 {
226 _marker: PhantomData,
227 },
228 WATCHDOG: WATCHDOG {
229 _marker: PhantomData,
230 },
231 GICD: GICD {
232 _marker: PhantomData,
233 },
234 }
235 }
236}