diff --git a/src/arch/aarch64/device/mod.rs b/src/arch/aarch64/device/mod.rs index ac38fa0d11..5410a3431d 100644 --- a/src/arch/aarch64/device/mod.rs +++ b/src/arch/aarch64/device/mod.rs @@ -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)] diff --git a/src/arch/aarch64/device/rtc.rs b/src/arch/aarch64/device/rtc.rs index ab0edf611f..1fdff3e38d 100644 --- a/src/arch/aarch64/device/rtc.rs +++ b/src/arch/aarch64/device/rtc.rs @@ -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 { diff --git a/src/arch/aarch64/start.rs b/src/arch/aarch64/start.rs index b3e80ec43e..7c74546ca1 100644 --- a/src/arch/aarch64/start.rs +++ b/src/arch/aarch64/start.rs @@ -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);