Skip to content

Commit 3deb674

Browse files
committed
Reorganize dtb.rs
1 parent c45f795 commit 3deb674

File tree

2 files changed

+46
-21
lines changed

2 files changed

+46
-21
lines changed

modules/axhal/src/dtb.rs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
11
//! DTB (Device Tree Blob) related functionality.
2-
use fdt_parser::{Fdt, FdtHeader};
2+
extern crate alloc;
33

4+
use alloc::boxed::Box;
45
use core::fmt::Write;
6+
use fdt_parser::{Fdt, FdtHeader};
57
use lazyinit::LazyInit;
68

7-
static BOOTARGS_STR: LazyInit<heapless::String<256>> = LazyInit::new();
9+
pub static BOOT_ARG: LazyInit<usize> = LazyInit::new();
10+
static CACHED_FDT: LazyInit<Fdt<'static>> = LazyInit::new();
11+
static BOOTARGS_STR: LazyInit<heapless::String<1024>> = LazyInit::new();
812

9-
/// Get the bootargs from the device tree.
10-
pub fn bootargs_message() -> Option<&'static str> {
11-
let fdt_addr = crate::get_bootarg();
13+
/// Returns the boot argument.
14+
/// This is typically the device tree blob address passed from the bootloader.
15+
pub fn get_bootarg() -> usize {
16+
*BOOT_ARG
17+
}
1218

19+
/// Get the cached FDT or initialize it if not already done.
20+
fn get_fdt() -> Option<&'static Fdt<'static>> {
21+
// Return cached FDT if available
22+
if let Some(fdt) = CACHED_FDT.get() {
23+
return Some(fdt);
24+
}
25+
26+
// Parse and cache the FDT
27+
let fdt_addr = get_bootarg();
1328
if fdt_addr == 0 {
1429
return None;
1530
}
@@ -33,18 +48,38 @@ pub fn bootargs_message() -> Option<&'static str> {
3348
core::slice::from_raw_parts(ptr, size)
3449
};
3550

36-
let fdt = match Fdt::from_bytes(fdt_bytes) {
37-
Ok(fdt) => fdt,
38-
Err(_) => return None,
39-
};
51+
// Leak the FDT bytes to create a 'static reference
52+
let fdt_bytes_static = Box::leak(fdt_bytes.to_vec().into_boxed_slice());
53+
54+
match Fdt::from_bytes(fdt_bytes_static) {
55+
Ok(fdt) => {
56+
// Store the FDT in the cache
57+
CACHED_FDT.init_once(fdt);
58+
CACHED_FDT.get()
59+
}
60+
Err(_) => None,
61+
}
62+
}
63+
64+
/// Get the bootargs chosen from the device tree.
65+
pub fn get_chosen() -> Option<&'static str> {
66+
// If bootargs are already cached, return them
67+
if let Some(bootargs) = BOOTARGS_STR.get() {
68+
return Some(bootargs.as_str());
69+
}
70+
71+
// Get or initialize the cached FDT
72+
let fdt = get_fdt()?;
4073

4174
if let Some(chosen) = fdt.chosen() {
4275
if let Some(bootargs) = chosen.bootargs() {
4376
// Store bootargs in static variable
44-
let mut bootargs_str = heapless::String::<256>::new();
77+
let mut bootargs_str = heapless::String::<1024>::new();
4578
if write!(bootargs_str, "{}", bootargs).is_ok() {
4679
BOOTARGS_STR.init_once(bootargs_str);
4780
return Some(BOOTARGS_STR.as_str());
81+
} else {
82+
warn!("Failed to write bootargs");
4883
}
4984
}
5085
}

modules/axhal/src/lib.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,9 @@ pub use axplat::init::init_later;
109109
#[cfg(feature = "smp")]
110110
pub use axplat::init::{init_early_secondary, init_later_secondary};
111111

112-
use lazyinit::LazyInit;
113-
114-
static BOOT_ARG: LazyInit<usize> = LazyInit::new();
115-
116112
/// Initializes the platform and boot argument.
117113
/// This function should be called as early as possible.
118114
pub fn init_early(cpu_id: usize, arg: usize) {
119-
BOOT_ARG.init_once(arg);
115+
dtb::BOOT_ARG.init_once(arg);
120116
axplat::init::init_early(cpu_id, arg);
121117
}
122-
123-
/// Returns the boot argument.
124-
/// This is typically the device tree blob address passed from the bootloader.
125-
pub fn get_bootarg() -> usize {
126-
*BOOT_ARG
127-
}

0 commit comments

Comments
 (0)