blob: bb954de709e4f64b839aedcc10d35ab5c974ed4d [file] [log] [blame]
Imre Kis55661632025-03-14 15:25:40 +01001// SPDX-FileCopyrightText: Copyright 2023-2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
Imre Kis9c084c02024-08-14 15:53:45 +02002// 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 Kis55661632025-03-14 15:25:40 +010010// Re-export peripheral drivers and common safe-mmio types
11pub use arm_gic;
12pub use arm_pl011_uart;
13pub use arm_sp805;
14pub use safe_mmio::{PhysicalInstance, UniqueMmioPointer};
Tomás González52cb4a62025-03-19 18:41:00 +000015pub mod power_controller;
Imre Kis9c084c02024-08-14 15:53:45 +020016
Imre Kis9c084c02024-08-14 15:53:45 +020017use arm_gic::GICDRegisters;
Balint Dobszay4292ed42025-01-09 13:52:32 +010018use arm_pl011_uart::PL011Registers;
Imre Kis9c084c02024-08-14 15:53:45 +020019use arm_sp805::SP805Registers;
Imre Kis55661632025-03-14 15:25:40 +010020use core::fmt::Debug;
Tomás González52cb4a62025-03-19 18:41:00 +000021use power_controller::FvpPowerControllerRegisters;
Andrew Walbran1a289d12025-02-11 14:55:39 +000022use spin::mutex::Mutex;
Imre Kis9c084c02024-08-14 15:53:45 +020023
24static PERIPHERALS_TAKEN: Mutex<bool> = Mutex::new(false);
25
26/// FVP peripherals
Andrew Walbran1a289d12025-02-11 14:55:39 +000027#[derive(Debug)]
Imre Kis9c084c02024-08-14 15:53:45 +020028pub struct Peripherals {
Andrew Walbran1a289d12025-02-11 14:55:39 +000029 pub uart0: PhysicalInstance<PL011Registers>,
30 pub uart1: PhysicalInstance<PL011Registers>,
31 pub uart2: PhysicalInstance<PL011Registers>,
32 pub uart3: PhysicalInstance<PL011Registers>,
33 pub watchdog: PhysicalInstance<SP805Registers>,
34 pub gicd: PhysicalInstance<GICDRegisters>,
Tomás González52cb4a62025-03-19 18:41:00 +000035 pub power_controller: PhysicalInstance<FvpPowerControllerRegisters>,
Imre Kis9c084c02024-08-14 15:53:45 +020036}
37
38impl Peripherals {
39 /// Take the peripherals once
40 pub fn take() -> Option<Self> {
41 if !*PERIPHERALS_TAKEN.lock() {
Imre Kis75a43542024-10-02 14:11:25 +020042 // SAFETY: PERIPHERALS_TAKEN ensures that this is only called once.
Imre Kis9c084c02024-08-14 15:53:45 +020043 Some(unsafe { Self::steal() })
44 } else {
45 None
46 }
47 }
48
49 /// Unsafe version of take()
50 ///
51 /// # Safety
Andrew Walbran1a289d12025-02-11 14:55:39 +000052 ///
53 /// The caller must ensure that each peripheral is only used once.
Imre Kis9c084c02024-08-14 15:53:45 +020054 pub unsafe fn steal() -> Self {
55 *PERIPHERALS_TAKEN.lock() = true;
56
57 Peripherals {
Andrew Walbran1a289d12025-02-11 14:55:39 +000058 uart0: PhysicalInstance::new(0x1c09_0000),
59 uart1: PhysicalInstance::new(0x1c0a_0000),
60 uart2: PhysicalInstance::new(0x1c0b_0000),
61 uart3: PhysicalInstance::new(0x1c0c_0000),
62 watchdog: PhysicalInstance::new(0x1c0f_0000),
Tomás González52cb4a62025-03-19 18:41:00 +000063 power_controller: PhysicalInstance::new(0x1c10_0000),
Andrew Walbran1a289d12025-02-11 14:55:39 +000064 gicd: PhysicalInstance::new(0x2f00_0000),
Imre Kis9c084c02024-08-14 15:53:45 +020065 }
66 }
67}