Make it possible to boot aarch64 with invalid DTB

This commit is contained in:
Jeremy Soller
2024-10-30 12:34:50 -06:00
parent 4dd6a26742
commit b221bb6c51
3 changed files with 32 additions and 52 deletions
+2 -5
View File
@@ -27,19 +27,16 @@ unsafe fn init_root_ic(fdt: &Fdt) {
ROOT_IC_IDX.store(ic_idx, Ordering::Relaxed);
}
pub unsafe fn init(fdt: &Fdt) {
pub unsafe fn init_devicetree(fdt: &Fdt) {
info!("IRQCHIP INIT");
crate::dtb::irqchip::init(&fdt);
init_root_ic(&fdt);
info!("GIT INIT");
generic_timer::init(fdt);
}
pub unsafe fn init_noncore(fdt: &Fdt) {
info!("SERIAL INIT");
serial::init(fdt);
info!("RTC INIT");
rtc::init();
rtc::init(fdt);
}
#[derive(Default)]
+22 -40
View File
@@ -1,53 +1,35 @@
use core::ptr::read_volatile;
use crate::{
memory::{Frame, KernelMapper},
paging::{Page, PageFlags, PhysicalAddress, VirtualAddress},
time,
};
use crate::time;
static RTC_DR: u32 = 0x000;
static RTC_DR: usize = 0x000;
static mut PL031_RTC: Pl031rtc = Pl031rtc { address: 0 };
pub unsafe fn init() {
PL031_RTC.init();
*time::START.lock() = (PL031_RTC.time() as u128) * time::NANOS_PER_SEC;
pub unsafe fn init(fdt: &fdt::Fdt) {
if let Some(node) = fdt.find_compatible(&["arm,pl031"]) {
match node.reg().and_then(|mut iter| iter.next()) {
Some(reg) => {
let mut rtc = Pl031rtc {
phys: reg.starting_address as usize,
};
log::info!("PL031 RTC at {:#x}", rtc.phys);
*time::START.lock() = (rtc.time() as u128) * time::NANOS_PER_SEC;
}
None => {
log::warn!("No PL031 RTC registers");
}
}
} else {
log::warn!("No PL031 RTC found");
}
}
struct Pl031rtc {
pub address: usize,
pub phys: usize,
}
impl Pl031rtc {
unsafe fn init(&mut self) {
let mut mapper = KernelMapper::lock();
let start_frame = Frame::containing(PhysicalAddress::new(0x09010000));
let end_frame = Frame::containing(PhysicalAddress::new(0x09010000 + 0x1000 - 1));
for frame in Frame::range_inclusive(start_frame, end_frame) {
let page = Page::containing_address(VirtualAddress::new(
frame.base().data() + crate::PHYS_OFFSET,
));
mapper
.get_mut()
.expect("failed to access KernelMapper for mapping RTC")
.map_phys(
page.start_address(),
frame.base(),
PageFlags::new().write(true),
)
.expect("failed to map RTC")
.flush();
}
self.address = crate::PHYS_OFFSET + 0x09010000;
}
unsafe fn read(&self, reg: u32) -> u32 {
let val = read_volatile((self.address + reg as usize) as *const u32);
val
unsafe fn read(&self, reg: usize) -> u32 {
read_volatile((crate::PHYS_OFFSET + self.phys + reg) as *const u32)
}
pub fn time(&mut self) -> u64 {
+8 -7
View File
@@ -199,14 +199,15 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
dtb::init(dtb_data);
//TODO: do not require DTB here?
let dtb = dtb_res.unwrap();
// Initialize devices
device::init(&dtb);
// Initialize all of the non-core devices not otherwise needed to complete initialization
device::init_noncore(&dtb);
match dtb_res {
Ok(dtb) => {
device::init_devicetree(&dtb);
}
Err(err) => {
log::warn!("failed to parse DTB: {}", err);
}
}
BSP_READY.store(true, Ordering::SeqCst);