Skip to content

Commit 59fbedb

Browse files
committed
fix: 以深度优先遍历方案恢复设备树解析
1 parent 55ef7c4 commit 59fbedb

File tree

7 files changed

+86
-114
lines changed

7 files changed

+86
-114
lines changed

Cargo.lock

Lines changed: 11 additions & 69 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rustsbi-qemu/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ r0 = "1"
1515
nb = "1"
1616
buddy_system_allocator = "0.8"
1717
uart_16550 = "0.2"
18+
dtb-walker = { git = "https://github.com/YdrMaster/dtb-walker.git", rev = "0ef2209" }

rustsbi-qemu/src/device_tree.rs

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,56 @@
22
use core::ops::Range;
33

44
pub(crate) struct BoardInfo {
5-
pub model: Vec<String>,
5+
pub dtb: Range<usize>,
6+
pub model: String,
67
pub smp: usize,
8+
pub mem: Vec<Range<usize>>,
79
pub uart: Range<usize>,
810
pub test: Range<usize>,
911
pub clint: Range<usize>,
1012
}
1113

12-
pub(crate) fn parse(_opaque: usize) -> BoardInfo {
13-
BoardInfo {
14-
model: vec![String::from("riscv-virtio,qemu")],
15-
smp: 8,
14+
pub(crate) fn parse(opaque: usize) -> BoardInfo {
15+
use dtb_walker::{Dtb, DtbObj, Property, WalkOperation};
16+
17+
let mut ans = BoardInfo {
18+
dtb: opaque..opaque,
19+
model: String::new(),
20+
smp: 0,
21+
mem: vec![],
1622
uart: 0x1000_0000..0x1000_0100,
1723
test: 0x10_0000..0x10_1000,
1824
clint: 0x200_0000..0x201_0000,
19-
}
25+
};
26+
let dtb = unsafe { Dtb::from_raw_parts(opaque as _) }.unwrap();
27+
ans.dtb.end += dtb.total_size();
28+
dtb.walk(|path, obj| match obj {
29+
DtbObj::SubNode { name } => {
30+
if path.last().is_empty() && name == b"cpus" {
31+
WalkOperation::StepInto
32+
} else if path.last() == b"cpus" && name.starts_with(b"cpu@") {
33+
ans.smp += 1;
34+
WalkOperation::StepOver
35+
} else if path.last().is_empty() && name.starts_with(b"memory") {
36+
WalkOperation::StepInto
37+
} else {
38+
WalkOperation::StepOver
39+
}
40+
}
41+
DtbObj::Property(Property::Model(model)) if path.last().is_empty() => {
42+
if let Ok(model) = model.as_str() {
43+
ans.model = model.into();
44+
}
45+
WalkOperation::StepOver
46+
}
47+
DtbObj::Property(Property::Reg(reg)) if path.last().starts_with(b"memory") => {
48+
for region in reg {
49+
ans.mem.push(region);
50+
}
51+
WalkOperation::StepOut
52+
}
53+
DtbObj::Property(_) => WalkOperation::StepOver,
54+
});
55+
56+
ans
2057
}

rustsbi-qemu/src/main.rs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -105,31 +105,19 @@ extern "C" fn early_trap() -> ! {
105105
}
106106
}
107107

108-
use core::sync::atomic::{
109-
AtomicBool, AtomicUsize,
110-
Ordering::{AcqRel, Acquire},
111-
};
108+
use core::sync::atomic::{AtomicBool, Ordering::AcqRel};
112109
use spin::Once;
113110

114111
#[link_section = ".bss.uninit"]
115112
static HSM: Once<qemu_hsm::QemuHsm> = Once::new();
116113

117-
#[link_section = ".bss.uninit"]
118-
static SMP: AtomicUsize = AtomicUsize::new(0);
119-
120114
/// rust 入口。
121115
extern "C" fn rust_main(_hartid: usize, opaque: usize) {
122116
unsafe { set_mtvec(early_trap as _) };
123117

124118
#[link_section = ".bss.uninit"]
125119
static GENESIS: AtomicBool = AtomicBool::new(false);
126120

127-
let mut smp = SMP.load(Acquire);
128-
let mask = 1 << hart_id();
129-
while let Err(val) = SMP.compare_exchange(smp, smp | mask, AcqRel, Acquire) {
130-
smp = val;
131-
}
132-
133121
// 全局初始化过程
134122
if !GENESIS.swap(true, AcqRel) {
135123
// 清零 bss 段
@@ -157,18 +145,20 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) {
157145
[rustsbi] Implementation : RustSBI-QEMU Version {ver_impl}
158146
[rustsbi] Platform Name : {model:?}
159147
[rustsbi] Platform SMP : {smp}
148+
[rustsbi] Platform Memory : {mem:#x?}
160149
[rustsbi] Boot HART : {hartid}
161-
[rustsbi] Device Tree Address: {dtb:#x}
150+
[rustsbi] Device Tree Region : {dtb:#x?}
162151
[rustsbi] Firmware Address : {firmware:#x}
163152
[rustsbi] Supervisor Address : {SUPERVISOR_ENTRY:#x}
164153
",
165154
ver_sbi = rustsbi::VERSION,
166155
logo = rustsbi::LOGO,
167156
ver_impl = env!("CARGO_PKG_VERSION"),
168157
model = board_info.model,
169-
smp = SMP.load(Acquire),
158+
smp = board_info.smp,
159+
mem = board_info.mem[0],
170160
hartid = hart_id(),
171-
dtb = opaque,
161+
dtb = board_info.dtb,
172162
firmware = entry as usize,
173163
);
174164
}

test-kernel/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,4 @@ riscv = "0.8"
1313
spin = "0.9"
1414
r0 = "1"
1515
lazy_static = { version = "1", features = ["spin_no_std"] }
16-
serde = { version = "1.0", default-features = false, features = ["derive"] }
17-
serde-device-tree = { git = "https://github.com/rustsbi/serde-device-tree.git", rev = "b8c2da9", default-features = false }
16+
dtb-walker = { git = "https://github.com/YdrMaster/dtb-walker.git", rev = "0ef2209" }

test-kernel/src/device_tree.rs

Lines changed: 0 additions & 19 deletions
This file was deleted.

test-kernel/src/main.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ extern crate sbi_rt as sbi;
1616

1717
#[macro_use]
1818
mod console;
19-
mod device_tree;
2019
mod test;
2120

2221
mod constants {
@@ -68,7 +67,7 @@ static mut EXPECTED: [Option<Trap>; 8] = [None; 8];
6867
extern "C" fn primary_rust_main(hartid: usize, dtb_pa: usize) -> ! {
6968
zero_bss();
7069

71-
let smp = device_tree::parse_smp(dtb_pa);
70+
let smp = parse_smp(dtb_pa);
7271
println!(
7372
r"
7473
_____ _ _ __ _
@@ -256,3 +255,26 @@ fn zero_bss() {
256255
}
257256
unsafe { r0::zero_bss(&mut sbss, &mut ebss) };
258257
}
258+
259+
fn parse_smp(dtb_pa: usize) -> usize {
260+
use dtb_walker::{Dtb, DtbObj, WalkOperation};
261+
262+
let mut smp = 0usize;
263+
unsafe { Dtb::from_raw_parts(dtb_pa as _) }
264+
.unwrap()
265+
.walk(|path, obj| match obj {
266+
DtbObj::SubNode { name } => {
267+
if path.last().is_empty() && name == b"cpus" {
268+
WalkOperation::StepInto
269+
} else if path.last() == b"cpus" && name.starts_with(b"cpu@") {
270+
smp += 1;
271+
WalkOperation::StepOver
272+
} else {
273+
WalkOperation::StepOver
274+
}
275+
}
276+
DtbObj::Property(_) => WalkOperation::StepOver,
277+
});
278+
279+
smp
280+
}

0 commit comments

Comments
 (0)