11// SPDX-License-Identifier: MIT OR Apache-2.0
22//
33// Copyright (c) 2018-2023 Andre Richter <andre.o.richter@gmail.com>
4+ // Copyright (c) 2026 Devansh Lodha <devanshlodha12@gmail.com>
45
56//! BSP driver support.
67
@@ -12,6 +13,9 @@ use crate::{
1213 memory,
1314 memory:: mmu:: MMIODescriptor ,
1415} ;
16+
17+ #[ cfg( feature = "bsp_rpi5" ) ]
18+ use crate :: driver:: interface:: DeviceDriver ;
1519use core:: {
1620 mem:: MaybeUninit ,
1721 sync:: atomic:: { AtomicBool , Ordering } ,
@@ -31,6 +35,13 @@ static mut INTERRUPT_CONTROLLER: MaybeUninit<device_driver::InterruptController>
3135#[ cfg( feature = "bsp_rpi4" ) ]
3236static mut INTERRUPT_CONTROLLER : MaybeUninit < device_driver:: GICv2 > = MaybeUninit :: uninit ( ) ;
3337
38+ #[ cfg( feature = "bsp_rpi5" ) ]
39+ static mut INTERRUPT_CONTROLLER : MaybeUninit < device_driver:: BCM2712InterruptController > =
40+ MaybeUninit :: uninit ( ) ;
41+
42+ #[ cfg( feature = "bsp_rpi5" ) ]
43+ static mut PCIE : MaybeUninit < device_driver:: BCM2712PCIe > = MaybeUninit :: uninit ( ) ;
44+
3445//--------------------------------------------------------------------------------------------------
3546// Private Code
3647//--------------------------------------------------------------------------------------------------
@@ -54,6 +65,7 @@ unsafe fn post_init_uart() -> Result<(), &'static str> {
5465}
5566
5667/// This must be called only after successful init of the memory subsystem.
68+ #[ cfg( not( feature = "bsp_rpi5" ) ) ]
5769unsafe fn instantiate_gpio ( ) -> Result < ( ) , & ' static str > {
5870 let mmio_descriptor = MMIODescriptor :: new ( mmio:: GPIO_START , mmio:: GPIO_SIZE ) ;
5971 let virt_addr =
@@ -64,6 +76,19 @@ unsafe fn instantiate_gpio() -> Result<(), &'static str> {
6476 Ok ( ( ) )
6577}
6678
79+ #[ cfg( feature = "bsp_rpi5" ) ]
80+ unsafe fn instantiate_gpio ( ) -> Result < ( ) , & ' static str > {
81+ let gpio_desc = MMIODescriptor :: new ( mmio:: GPIO_START , mmio:: GPIO_SIZE ) ;
82+ let gpio_virt = memory:: mmu:: kernel_map_mmio ( "RP1 GPIO" , & gpio_desc) ?;
83+
84+ let pads_desc = MMIODescriptor :: new ( mmio:: PADS_START , mmio:: PADS_SIZE ) ;
85+ let pads_virt = memory:: mmu:: kernel_map_mmio ( "RP1 PADS" , & pads_desc) ?;
86+
87+ GPIO . write ( device_driver:: GPIO :: new ( pads_virt, gpio_virt) ) ;
88+
89+ Ok ( ( ) )
90+ }
91+
6792/// This must be called only after successful init of the GPIO driver.
6893unsafe fn post_init_gpio ( ) -> Result < ( ) , & ' static str > {
6994 GPIO . assume_init_ref ( ) . map_pl011_uart ( ) ;
@@ -99,6 +124,46 @@ unsafe fn instantiate_interrupt_controller() -> Result<(), &'static str> {
99124 Ok ( ( ) )
100125}
101126
127+ #[ cfg( feature = "bsp_rpi5" ) ]
128+ unsafe fn instantiate_interrupt_controller ( ) -> Result < ( ) , & ' static str > {
129+ let gicd_desc = MMIODescriptor :: new ( mmio:: GICD_START , mmio:: GICD_SIZE ) ;
130+ let gicd_virt = memory:: mmu:: kernel_map_mmio ( "GICv2 GICD" , & gicd_desc) ?;
131+
132+ let gicc_desc = MMIODescriptor :: new ( mmio:: GICC_START , mmio:: GICC_SIZE ) ;
133+ let gicc_virt = memory:: mmu:: kernel_map_mmio ( "GICv2 GICC" , & gicc_desc) ?;
134+
135+ let mip_desc = MMIODescriptor :: new ( mmio:: MIP_START , mmio:: MIP_SIZE ) ;
136+ let mip_virt = memory:: mmu:: kernel_map_mmio ( "MIP" , & mip_desc) ?;
137+
138+ let rp1_desc = MMIODescriptor :: new ( mmio:: RP1_CFG_START , mmio:: RP1_CFG_SIZE ) ;
139+ let rp1_virt = memory:: mmu:: kernel_map_mmio ( "RP1 Config (IntC)" , & rp1_desc) ?;
140+
141+ INTERRUPT_CONTROLLER . write ( device_driver:: BCM2712InterruptController :: new (
142+ gicd_virt, gicc_virt, mip_virt, rp1_virt,
143+ ) ) ;
144+
145+ Ok ( ( ) )
146+ }
147+
148+ #[ cfg( feature = "bsp_rpi5" ) ]
149+ unsafe fn instantiate_pcie ( ) -> Result < ( ) , & ' static str > {
150+ let rc_desc = MMIODescriptor :: new ( mmio:: PCIE_RC_START , mmio:: PCIE_RC_SIZE ) ;
151+ let rc_virt = memory:: mmu:: kernel_map_mmio ( "PCIe RC" , & rc_desc) ?;
152+
153+ let rp1_desc = MMIODescriptor :: new ( mmio:: RP1_CFG_START , mmio:: RP1_CFG_SIZE ) ;
154+ let rp1_virt = memory:: mmu:: kernel_map_mmio ( "RP1 Config" , & rp1_desc) ?;
155+
156+ PCIE . write ( device_driver:: BCM2712PCIe :: new ( rc_virt, rp1_virt) ) ;
157+
158+ Ok ( ( ) )
159+ }
160+
161+ #[ cfg( feature = "bsp_rpi5" ) ]
162+ unsafe fn driver_pcie ( ) -> Result < ( ) , & ' static str > {
163+ instantiate_pcie ( ) ?;
164+ PCIE . assume_init_ref ( ) . init ( )
165+ }
166+
102167/// This must be called only after successful init of the interrupt controller driver.
103168unsafe fn post_init_interrupt_controller ( ) -> Result < ( ) , & ' static str > {
104169 generic_exception:: asynchronous:: register_irq_manager ( INTERRUPT_CONTROLLER . assume_init_ref ( ) ) ;
@@ -163,6 +228,9 @@ pub unsafe fn init() -> Result<(), &'static str> {
163228 return Err ( "Init already done" ) ;
164229 }
165230
231+ #[ cfg( feature = "bsp_rpi5" ) ]
232+ driver_pcie ( ) ?;
233+
166234 driver_uart ( ) ?;
167235 driver_gpio ( ) ?;
168236 driver_interrupt_controller ( ) ?;
0 commit comments