Skip to content

Commit 0a91cc4

Browse files
committed
feat(boot): Orchestrate PCIe and RP1 initialization sequence
1 parent a34720d commit 0a91cc4

File tree

1 file changed

+68
-0
lines changed
  • 19_kernel_heap/kernel/src/bsp/raspberrypi

1 file changed

+68
-0
lines changed

19_kernel_heap/kernel/src/bsp/raspberrypi/driver.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
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;
1519
use 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")]
3236
static 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"))]
5769
unsafe 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.
6893
unsafe 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.
103168
unsafe 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

Comments
 (0)