Make it possible to boot aarch64 with invalid DTB
This commit is contained in:
@@ -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)]
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user