Skip to main content

os/
device_tree.rs

1//! Device tree helpers.
2
3use core::sync::atomic::{AtomicUsize, Ordering};
4use fdt::Fdt;
5use log::info;
6
7static CLOCK_FREQ: AtomicUsize = AtomicUsize::new(0);
8
9/// Initializes early device information from the flattened device tree.
10pub(crate) fn init(dtb_pa: usize) {
11    let fdt = unsafe { Fdt::from_ptr(dtb_pa as *const u32) }.expect("invalid device tree");
12    let cpus = fdt.root().cpus();
13    let clock_freq = cpus
14        .common_timebase_frequency()
15        .or_else(|| cpus.iter().next().map(|cpu| cpu.timebase_frequency()))
16        .expect("missing timebase-frequency in device tree") as usize;
17    CLOCK_FREQ.store(clock_freq, Ordering::Relaxed);
18    info!("CLOCK_FREQ from device tree: {}", clock_freq);
19}
20
21/// Returns the number of `mtime` ticks per second.
22pub(crate) fn clock_freq() -> usize {
23    let clock_freq = CLOCK_FREQ.load(Ordering::Relaxed);
24    assert!(clock_freq != 0, "device tree is not initialized");
25    clock_freq
26}