|
@@ -58,68 +58,52 @@ extern "C" fn rust_main(_hart_id: usize, opaque: usize, nonstandard_a2: usize) {
|
|
|
serde_device_tree::from_raw_mut(&dtb).unwrap_or_else(fail::device_tree_deserialize);
|
|
|
// 2. Init device
|
|
|
// TODO: The device base address should be find in a better way.
|
|
|
- 'console_finder: for console_path in tree.chosen.stdout_path.iter() {
|
|
|
+ for console_path in tree.chosen.stdout_path.iter() {
|
|
|
if let Some(node) = root.find(console_path) {
|
|
|
- let compatible = node
|
|
|
- .props()
|
|
|
- .map(|mut prop_iter| {
|
|
|
- prop_iter
|
|
|
- .find(|prop_item| prop_item.get_name() == "compatible")
|
|
|
- .map(|prop_item| {
|
|
|
- prop_item.deserialize::<serde_device_tree::buildin::StrSeq>()
|
|
|
- })
|
|
|
- })
|
|
|
- .map_or_else(|| None, |v| v);
|
|
|
- let regs = node
|
|
|
- .props()
|
|
|
- .map(|mut prop_iter| {
|
|
|
- prop_iter
|
|
|
- .find(|prop_item| prop_item.get_name() == "reg")
|
|
|
- .map(|prop_item| {
|
|
|
- let reg =
|
|
|
- prop_item.deserialize::<serde_device_tree::buildin::Reg>();
|
|
|
- if let Some(range) = reg.iter().next() {
|
|
|
- return Some(range);
|
|
|
- }
|
|
|
- None
|
|
|
- })
|
|
|
- .map_or_else(|| None, |v| v)
|
|
|
- })
|
|
|
- .map_or_else(|| None, |v| v);
|
|
|
- if compatible.is_some() && regs.is_some() {
|
|
|
- for device_id in compatible.unwrap().iter() {
|
|
|
- if device_id == "ns16550a" {
|
|
|
- board::console_dev_init(
|
|
|
- MachineConsoleType::Uart16550,
|
|
|
- regs.unwrap().0.start,
|
|
|
- );
|
|
|
- break 'console_finder;
|
|
|
+ let info = dt::get_compatible_and_range(&node);
|
|
|
+ let result = info.is_some_and(|info| {
|
|
|
+ let (compatible, regs) = info;
|
|
|
+ for device_id in compatible.iter() {
|
|
|
+ if device_id == board::UART16650_COMPATIBLE {
|
|
|
+ board::console_dev_init(MachineConsoleType::Uart16550, regs.start);
|
|
|
+ return true;
|
|
|
}
|
|
|
- if device_id == "xlnx,xps-uartlite-1.00.a" {
|
|
|
- board::console_dev_init(
|
|
|
- MachineConsoleType::UartAxiLite,
|
|
|
- regs.unwrap().0.start,
|
|
|
- );
|
|
|
- break 'console_finder;
|
|
|
+ if device_id == board::UARTAXILITE_COMPATIBLE {
|
|
|
+ board::console_dev_init(MachineConsoleType::UartAxiLite, regs.start);
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
+ false
|
|
|
+ });
|
|
|
+ if result {
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- let clint_device = tree.soc.clint.unwrap().iter().next().unwrap();
|
|
|
+ let mut clint_device_address: Option<usize> = None;
|
|
|
+ let mut find_device = |node: &serde_device_tree::buildin::Node| {
|
|
|
+ let info = dt::get_compatible_and_range(node);
|
|
|
+ if let Some(info) = info {
|
|
|
+ let (compatible, regs) = info;
|
|
|
+ let base_address = regs.start;
|
|
|
+ for device_id in compatible.iter() {
|
|
|
+ // Initialize clint device.
|
|
|
+ if device_id == board::SIFIVECLINT_COMPATIBLE {
|
|
|
+ clint_device_address = Some(base_address);
|
|
|
+ board::ipi_dev_init(base_address);
|
|
|
+ }
|
|
|
+ // Initialize reset device.
|
|
|
+ if device_id == board::SIFIVETEST_COMPATIBLE {
|
|
|
+ board::reset_dev_init(base_address);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ root.search(&mut find_device);
|
|
|
let cpu_num = tree.cpus.cpu.len();
|
|
|
- let ipi_base_address = clint_device.at();
|
|
|
-
|
|
|
- // Initialize reset device if present.
|
|
|
- if let Some(test) = tree.soc.test {
|
|
|
- let reset_device = test.iter().next().unwrap();
|
|
|
- let reset_base_address = reset_device.at();
|
|
|
- board::reset_dev_init(usize::from_str_radix(reset_base_address, 16).unwrap());
|
|
|
- }
|
|
|
|
|
|
// Initialize console and IPI devices.
|
|
|
- board::ipi_dev_init(usize::from_str_radix(ipi_base_address, 16).unwrap());
|
|
|
|
|
|
// 3. Init the SBI implementation
|
|
|
// TODO: More than one memory node or range?
|
|
@@ -160,7 +144,7 @@ extern "C" fn rust_main(_hart_id: usize, opaque: usize, nonstandard_a2: usize) {
|
|
|
if let Some(model) = tree.model {
|
|
|
info!("Model: {}", model.iter().next().unwrap_or("<unspecified>"));
|
|
|
}
|
|
|
- info!("Clint device: {}", ipi_base_address);
|
|
|
+ info!("Clint device: {:x?}", clint_device_address);
|
|
|
info!(
|
|
|
"Chosen stdout item: {}",
|
|
|
tree.chosen
|