[rialto] Parse the PCI info from rialto's device tree
This is the first part of the change to enable access
to a virtio socket device via the PCI bus in rialto.
Bug: 282928116
Test: atest rialto_test
Change-Id: Ia7979f45f3ed565ce185bf337211740f74ebee2c
diff --git a/rialto/Android.bp b/rialto/Android.bp
index cf81563..eb49395 100644
--- a/rialto/Android.bp
+++ b/rialto/Android.bp
@@ -12,6 +12,8 @@
"libaarch64_paging",
"libbuddy_system_allocator",
"libhyp",
+ "libfdtpci",
+ "liblibfdt",
"liblog_rust_nostd",
"libvmbase",
],
diff --git a/rialto/src/error.rs b/rialto/src/error.rs
index 754e554..bf26639 100644
--- a/rialto/src/error.rs
+++ b/rialto/src/error.rs
@@ -16,7 +16,9 @@
use aarch64_paging::MapError;
use core::{fmt, result};
+use fdtpci::PciError;
use hyp::Error as HypervisorError;
+use libfdt::FdtError;
pub type Result<T> = result::Result<T, Error>;
@@ -28,16 +30,22 @@
PageTableMapping(MapError),
/// Failed to initialize the logger.
LoggerInit,
+ /// Invalid FDT.
+ InvalidFdt(FdtError),
+ /// Invalid PCI.
+ InvalidPci(PciError),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- Self::Hypervisor(e) => write!(f, "MMIO guard failed: {e}."),
+ Self::Hypervisor(e) => write!(f, "Hypervisor error: {e}."),
Self::PageTableMapping(e) => {
write!(f, "Failed when attempting to map some range in the page table: {e}.")
}
Self::LoggerInit => write!(f, "Failed to initialize the logger."),
+ Self::InvalidFdt(e) => write!(f, "Invalid FDT: {e}"),
+ Self::InvalidPci(e) => write!(f, "Invalid PCI: {e}"),
}
}
}
@@ -53,3 +61,15 @@
Self::PageTableMapping(e)
}
}
+
+impl From<FdtError> for Error {
+ fn from(e: FdtError) -> Self {
+ Self::InvalidFdt(e)
+ }
+}
+
+impl From<PciError> for Error {
+ fn from(e: PciError) -> Self {
+ Self::InvalidPci(e)
+ }
+}
diff --git a/rialto/src/main.rs b/rialto/src/main.rs
index 0f92d3f..57bed69 100644
--- a/rialto/src/main.rs
+++ b/rialto/src/main.rs
@@ -28,7 +28,8 @@
paging::{Attributes, MemoryRegion},
};
use buddy_system_allocator::LockedHeap;
-use core::ops::Range;
+use core::{ops::Range, slice};
+use fdtpci::PciInfo;
use hyp::get_hypervisor;
use log::{debug, error, info};
use vmbase::{layout, main, power::reboot};
@@ -113,8 +114,17 @@
vmbase::logger::init(log::LevelFilter::Debug).map_err(|_| Error::LoggerInit)
}
-fn try_main() -> Result<()> {
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+/// * The `fdt_addr` must be a valid pointer and points to a valid `Fdt`.
+unsafe fn try_main(fdt_addr: usize) -> Result<()> {
info!("Welcome to Rialto!");
+ // SAFETY: The caller ensures that `fdt_addr` is valid.
+ let fdt = unsafe { slice::from_raw_parts(fdt_addr as *mut u8, SZ_1M) };
+ let fdt = libfdt::Fdt::from_slice(fdt)?;
+ let pci_info = PciInfo::from_fdt(fdt)?;
+ debug!("PCI: {:#x?}", pci_info);
let mut pgt = IdMap::new(PT_ASID, PT_ROOT_LEVEL);
init_kernel_pgt(&mut pgt)?;
@@ -122,13 +132,15 @@
}
/// Entry point for Rialto.
-pub fn main(_a0: u64, _a1: u64, _a2: u64, _a3: u64) {
+pub fn main(fdt_addr: u64, _a1: u64, _a2: u64, _a3: u64) {
init_heap();
if try_init_logger().is_err() {
// Don't log anything if the logger initialization fails.
reboot();
}
- match try_main() {
+ // SAFETY: `fdt_addr` is supposed to be a valid pointer and points to
+ // a valid `Fdt`.
+ match unsafe { try_main(fdt_addr as usize) } {
Ok(()) => info!("Rialto ends successfully."),
Err(e) => {
error!("Rialto failed with {e}");