blob: b02f407b1c37755cabf10b4c25ba2fcc7e57d7c9 [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 Kisad55c032025-03-25 11:33:53 +010010pub mod system;
11
Imre Kis55661632025-03-14 15:25:40 +010012// Re-export peripheral drivers and common safe-mmio types
13pub use arm_gic;
14pub use arm_pl011_uart;
15pub use arm_sp805;
16pub use safe_mmio::{PhysicalInstance, UniqueMmioPointer};
Tomás González52cb4a62025-03-19 18:41:00 +000017pub mod power_controller;
Imre Kis9c084c02024-08-14 15:53:45 +020018
Imre Kis9c084c02024-08-14 15:53:45 +020019use arm_gic::GICDRegisters;
Balint Dobszay4292ed42025-01-09 13:52:32 +010020use arm_pl011_uart::PL011Registers;
Imre Kis9c084c02024-08-14 15:53:45 +020021use arm_sp805::SP805Registers;
Imre Kis58d74c42025-03-24 17:33:15 +010022use core::{fmt::Debug, ops::RangeInclusive};
Tomás González52cb4a62025-03-19 18:41:00 +000023use power_controller::FvpPowerControllerRegisters;
Andrew Walbran1a289d12025-02-11 14:55:39 +000024use spin::mutex::Mutex;
Imre Kisad55c032025-03-25 11:33:53 +010025use system::FvpSystemRegisters;
Imre Kis9c084c02024-08-14 15:53:45 +020026
27static PERIPHERALS_TAKEN: Mutex<bool> = Mutex::new(false);
28
Imre Kis58d74c42025-03-24 17:33:15 +010029/// Memory map based on 'Table 6-5: Base Platform memory map' of 'Fast Models Version 11.28
30/// Reference Guide'. The ranges for normal memory regions are public, however the peripheral
31/// regions are private and they should be accessed through the `Peripherals` structure.
32pub struct MemoryMap;
33
34#[allow(unused)]
35impl MemoryMap {
36 pub const TRUSTED_BOOT_ROM: RangeInclusive<usize> = 0x00_0000_0000..=0x00_03FF_FFFF;
37 pub const TRUSTED_SRAM: RangeInclusive<usize> = 0x00_0400_0000..=0x00_0407_FFFF;
38 pub const TRUSTED_DRAM: RangeInclusive<usize> = 0x00_0600_0000..=0x00_07FF_FFFF;
39 pub const NOR_FLASH0: RangeInclusive<usize> = 0x00_0800_0000..=0x00_0BFF_FFFF;
40 pub const NOR_FLASH1: RangeInclusive<usize> = 0x00_0C00_0000..=0x00_0FFF_FFFF;
41 pub const PSRAM: RangeInclusive<usize> = 0x00_1400_0000..=0x00_17FF_FFFF;
42 pub const VRAM: RangeInclusive<usize> = 0x00_1800_0000..=0x00_19FF_FFFF;
43 const ETHERNET: RangeInclusive<usize> = 0x00_1A00_0000..=0x00_1AFF_FFFF;
44 const USB: RangeInclusive<usize> = 0x00_1B00_0000..=0x00_1BFF_FFFF;
45 const VE_SYSTEM: RangeInclusive<usize> = 0x00_1C01_0000..=0x00_1C01_FFFF;
46 const SYSTEM_CONTROLLER: RangeInclusive<usize> = 0x00_1C02_0000..=0x00_1C02_FFFF;
47 const AACI: RangeInclusive<usize> = 0x00_1C04_0000..=0x00_1C04_FFFF;
48 const MCI: RangeInclusive<usize> = 0x00_1C05_0000..=0x00_1C05_FFFF;
49 const KMI_KEYBOARD: RangeInclusive<usize> = 0x00_1C06_0000..=0x00_1C06_FFFF;
50 const KMI_MOUSE: RangeInclusive<usize> = 0x00_1C07_0000..=0x00_1C07_FFFF;
51 const UART0: RangeInclusive<usize> = 0x00_1C09_0000..=0x00_1C09_FFFF;
52 const UART1: RangeInclusive<usize> = 0x00_1C0A_0000..=0x00_1C0A_FFFF;
53 const UART2: RangeInclusive<usize> = 0x00_1C0B_0000..=0x00_1C0B_FFFF;
54 const UART3: RangeInclusive<usize> = 0x00_1C0C_0000..=0x00_1C0C_FFFF;
55 const VFS2: RangeInclusive<usize> = 0x00_1C0D_0000..=0x00_1C0D_FFFF;
56 const WATCHDOG: RangeInclusive<usize> = 0x00_1C0F_0000..=0x00_1C0F_FFFF;
57 const POWER_CONTROLLER: RangeInclusive<usize> = 0x00_1C10_0000..=0x00_1C10_FFFF;
58 const DUAL_TIMER0: RangeInclusive<usize> = 0x00_1C11_0000..=0x00_1C11_FFFF;
59 const DUAL_TIEMR1: RangeInclusive<usize> = 0x00_1C12_0000..=0x00_1C12_FFFF;
60 const VIRTIO_BLOCK_DEVICE: RangeInclusive<usize> = 0x00_1C13_0000..=0x00_1C13_FFFF;
61 const VIRTIO_PLAN9_DEVICE: RangeInclusive<usize> = 0x00_1C14_0000..=0x00_1C14_FFFF;
62 const VIRTIO_NET_DEVICE: RangeInclusive<usize> = 0x00_1C15_0000..=0x00_1C15_FFFF;
63 const RTC: RangeInclusive<usize> = 0x00_1C17_0000..=0x00_1C17_FFFF;
64 const CF_CARD: RangeInclusive<usize> = 0x00_1C1A_0000..=0x00_1C1A_FFFF;
65 const CLCD_CONTROLLER: RangeInclusive<usize> = 0x00_1C1F_0000..=0x00_1C1F_FFFF;
66 const VIRTIO_RNG: RangeInclusive<usize> = 0x00_1C20_0000..=0x00_1C20_FFFF;
67 const LS64_TESTING_FIFO: RangeInclusive<usize> = 0x00_1D00_0000..=0x00_1D00_FFFF;
68 const UTILITY_BUS: RangeInclusive<usize> = 0x00_1E00_0000..=0x00_1EFF_FFFF;
69 pub const NON_TRUSTED_ROM: RangeInclusive<usize> = 0x00_1F00_0000..=0x00_1F00_0FFF;
70 const CORESIGHT: RangeInclusive<usize> = 0x00_2000_0000..=0x00_27FF_FFFF;
71 const REFCLK_CNTCONTROL: RangeInclusive<usize> = 0x00_2A43_0000..=0x00_2A43_FFFF;
72 const EL2_WATCHDOG_CONTROL: RangeInclusive<usize> = 0x00_2A44_0000..=0x00_2A44_FFFF;
73 const EL2_WATCHDOG_REFRESH: RangeInclusive<usize> = 0x00_2A45_0000..=0x00_2A45_FFFF;
74 const TRUSTED_WATCHDOG: RangeInclusive<usize> = 0x00_2A49_0000..=0x00_2A49_FFFF;
75 const TRUSTZONE_CONTROLLER: RangeInclusive<usize> = 0x00_2A4A_0000..=0x00_2A4A_FFFF;
76 const REFCLK_CNTREAD: RangeInclusive<usize> = 0x00_2A80_0000..=0x00_2A80_FFFF;
77 const AP_REFCLK_CNTCTL: RangeInclusive<usize> = 0x00_2A81_0000..=0x00_2A81_FFFF;
78 const AP_REFCLK_CNTBASE0: RangeInclusive<usize> = 0x00_2A82_0000..=0x00_2A82_FFFF;
79 const AP_REFCLK_CNTBASE1: RangeInclusive<usize> = 0x00_2A83_0000..=0x00_2A83_FFFF;
80 const DMC_400_CFG: RangeInclusive<usize> = 0x00_2B0A_0000..=0x00_2B0A_FFFF;
81 const SMMUV3_AEM: RangeInclusive<usize> = 0x00_2B40_0000..=0x00_2B4F_FFFF;
82 const DMA330X4: RangeInclusive<usize> = 0x00_2B50_0000..=0x00_2B5F_FFFF;
83 const GICC: RangeInclusive<usize> = 0x00_2C00_0000..=0x00_2C00_1FFF;
84 const GICH: RangeInclusive<usize> = 0x00_2C01_0000..=0x00_2C01_0FFF;
85 const GICV: RangeInclusive<usize> = 0x00_2C02_F000..=0x00_2C03_0FFF;
86 const CCI_400: RangeInclusive<usize> = 0x00_2C09_0000..=0x00_2C09_FFFF;
87 const MALI_G76: RangeInclusive<usize> = 0x00_2D00_0000..=0x00_2DFF_0000;
88 pub const NON_TRUSTED_SRAM: RangeInclusive<usize> = 0x00_2E00_0000..=0x00_2E00_FFFF;
89 const GICD: RangeInclusive<usize> = 0x00_2F00_0000..=0x00_2F00_FFFF;
90 const GITS: RangeInclusive<usize> = 0x00_2F02_0000..=0x00_2F03_FFFF;
91 const GICR: RangeInclusive<usize> = 0x00_2F10_0000..=0x00_2F1F_FFFF;
92 const PCIE_CONFIG_REGION: RangeInclusive<usize> = 0x00_4000_0000..=0x00_4FFF_FFFF;
93 const PCIE_MEMORY_REGION1: RangeInclusive<usize> = 0x00_5000_0000..=0x00_5FFF_FFFF;
94 const TRUSTED_RNG: RangeInclusive<usize> = 0x00_7FE6_0000..=0x00_7FE6_0FFF;
95 const TRUSTED_NV_COUNTERS: RangeInclusive<usize> = 0x00_7FE7_0000..=0x00_7FE7_0FFF;
96 const TRUSTED_ROOT_KEY_STORAGE: RangeInclusive<usize> = 0x00_7FE8_0000..=0x00_7FE8_0FFF;
97 const DDR3_PHY: RangeInclusive<usize> = 0x00_7FEF_0000..=0x00_7FEF_FFFF;
98 const HDLCD_CONTROLLER: RangeInclusive<usize> = 0x00_7FF6_0000..=0x00_7FF6_FFFF;
99 pub const DRAM0: RangeInclusive<usize> = 0x00_8000_0000..=0x00_FFFF_FFFF;
100 pub const DRAM1: RangeInclusive<usize> = 0x08_8000_0000..=0x0F_FFFF_FFFF;
101 const PCIE_MEMORY_REGION2: RangeInclusive<usize> = 0x40_0000_0000..=0x7F_FFFF_FFFF;
102 pub const DRAM2: RangeInclusive<usize> = 0x88_0000_0000..=0xFF_FFFF_FFFF;
103 pub const DRAM3: RangeInclusive<usize> = 0x00_0880_0000_0000..=0x00_0FFF_FFFF_FFFF;
104 pub const DRAM4: RangeInclusive<usize> = 0x08_8000_0000_0000..=0x0F_FFFF_FFFF_FFFF;
105 pub const DRAM5: RangeInclusive<usize> = 0x88_0000_0000_0000..=0x8F_FFFF_FFFF_FFFF;
106}
107
Imre Kis9c084c02024-08-14 15:53:45 +0200108/// FVP peripherals
Andrew Walbran1a289d12025-02-11 14:55:39 +0000109#[derive(Debug)]
Imre Kis9c084c02024-08-14 15:53:45 +0200110pub struct Peripherals {
Imre Kisad55c032025-03-25 11:33:53 +0100111 pub system: PhysicalInstance<FvpSystemRegisters>,
Andrew Walbran1a289d12025-02-11 14:55:39 +0000112 pub uart0: PhysicalInstance<PL011Registers>,
113 pub uart1: PhysicalInstance<PL011Registers>,
114 pub uart2: PhysicalInstance<PL011Registers>,
115 pub uart3: PhysicalInstance<PL011Registers>,
116 pub watchdog: PhysicalInstance<SP805Registers>,
117 pub gicd: PhysicalInstance<GICDRegisters>,
Tomás González52cb4a62025-03-19 18:41:00 +0000118 pub power_controller: PhysicalInstance<FvpPowerControllerRegisters>,
Imre Kis9c084c02024-08-14 15:53:45 +0200119}
120
121impl Peripherals {
122 /// Take the peripherals once
123 pub fn take() -> Option<Self> {
124 if !*PERIPHERALS_TAKEN.lock() {
Imre Kis75a43542024-10-02 14:11:25 +0200125 // SAFETY: PERIPHERALS_TAKEN ensures that this is only called once.
Imre Kis9c084c02024-08-14 15:53:45 +0200126 Some(unsafe { Self::steal() })
127 } else {
128 None
129 }
130 }
131
132 /// Unsafe version of take()
133 ///
134 /// # Safety
Andrew Walbran1a289d12025-02-11 14:55:39 +0000135 ///
136 /// The caller must ensure that each peripheral is only used once.
Imre Kis9c084c02024-08-14 15:53:45 +0200137 pub unsafe fn steal() -> Self {
138 *PERIPHERALS_TAKEN.lock() = true;
139
140 Peripherals {
Imre Kisad55c032025-03-25 11:33:53 +0100141 system: PhysicalInstance::new(*MemoryMap::VE_SYSTEM.start()),
Imre Kis58d74c42025-03-24 17:33:15 +0100142 uart0: PhysicalInstance::new(*MemoryMap::UART0.start()),
143 uart1: PhysicalInstance::new(*MemoryMap::UART1.start()),
144 uart2: PhysicalInstance::new(*MemoryMap::UART2.start()),
145 uart3: PhysicalInstance::new(*MemoryMap::UART3.start()),
146 watchdog: PhysicalInstance::new(*MemoryMap::WATCHDOG.start()),
147 power_controller: PhysicalInstance::new(*MemoryMap::POWER_CONTROLLER.start()),
148 gicd: PhysicalInstance::new(*MemoryMap::GICD.start()),
Imre Kis9c084c02024-08-14 15:53:45 +0200149 }
150 }
151}