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