blob: f1d02d9c59a6c0fd8c121b1cf71549a9b75891fe [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
Andrew Walbran8fb815a2025-02-24 16:19:14 +000010use core::fmt::Debug;
Imre Kis9c084c02024-08-14 15:53:45 +020011
Imre Kis9c084c02024-08-14 15:53:45 +020012use arm_gic::GICDRegisters;
Balint Dobszay4292ed42025-01-09 13:52:32 +010013use arm_pl011_uart::PL011Registers;
Imre Kis9c084c02024-08-14 15:53:45 +020014use arm_sp805::SP805Registers;
Andrew Walbran8fb815a2025-02-24 16:19:14 +000015pub use safe_mmio::PhysicalInstance;
Andrew Walbran1a289d12025-02-11 14:55:39 +000016use spin::mutex::Mutex;
Imre Kis9c084c02024-08-14 15:53:45 +020017
18static PERIPHERALS_TAKEN: Mutex<bool> = Mutex::new(false);
19
20/// FVP peripherals
Andrew Walbran1a289d12025-02-11 14:55:39 +000021#[derive(Debug)]
Imre Kis9c084c02024-08-14 15:53:45 +020022pub struct Peripherals {
Andrew Walbran1a289d12025-02-11 14:55:39 +000023 pub uart0: PhysicalInstance<PL011Registers>,
24 pub uart1: PhysicalInstance<PL011Registers>,
25 pub uart2: PhysicalInstance<PL011Registers>,
26 pub uart3: PhysicalInstance<PL011Registers>,
27 pub watchdog: PhysicalInstance<SP805Registers>,
28 pub gicd: PhysicalInstance<GICDRegisters>,
Imre Kis9c084c02024-08-14 15:53:45 +020029}
30
31impl Peripherals {
32 /// Take the peripherals once
33 pub fn take() -> Option<Self> {
34 if !*PERIPHERALS_TAKEN.lock() {
Imre Kis75a43542024-10-02 14:11:25 +020035 // SAFETY: PERIPHERALS_TAKEN ensures that this is only called once.
Imre Kis9c084c02024-08-14 15:53:45 +020036 Some(unsafe { Self::steal() })
37 } else {
38 None
39 }
40 }
41
42 /// Unsafe version of take()
43 ///
44 /// # Safety
Andrew Walbran1a289d12025-02-11 14:55:39 +000045 ///
46 /// The caller must ensure that each peripheral is only used once.
Imre Kis9c084c02024-08-14 15:53:45 +020047 pub unsafe fn steal() -> Self {
48 *PERIPHERALS_TAKEN.lock() = true;
49
50 Peripherals {
Andrew Walbran1a289d12025-02-11 14:55:39 +000051 uart0: PhysicalInstance::new(0x1c09_0000),
52 uart1: PhysicalInstance::new(0x1c0a_0000),
53 uart2: PhysicalInstance::new(0x1c0b_0000),
54 uart3: PhysicalInstance::new(0x1c0c_0000),
55 watchdog: PhysicalInstance::new(0x1c0f_0000),
56 gicd: PhysicalInstance::new(0x2f00_0000),
Imre Kis9c084c02024-08-14 15:53:45 +020057 }
58 }
59}