Merge "[service-vm] Identitfy service VM in pvmfw with avb property"
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index c329d26..287e14a 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -149,20 +149,39 @@
     installable: false,
 }
 
-// platform.dts is passed to clang for macro preprocessing, and then compiled to dtbo using dtc.
-// The raw content of the dtbo file is then written as a Rust byte array.
+// We need to rename *.dts into *.cpp as cc_object doesn't accept *.dts as an
+// input
 genrule {
-    name: "pvmfw_fdt_template_rs",
-    srcs: [
-        "platform.dts",
-        ":arm_dt_bindings_headers", // implicit dependency
+    name: "pvmfw_platform.dts.renamed",
+    srcs: ["platform.dts"],
+    out: ["out.cpp"],
+    cmd: "cp $(in) $(out)",
+    visibility: ["//visibility:private"],
+}
+
+// Then run the macro processor to replace symbols like GIC_SPI into actual
+// numbers defined in the ARM DT binding headers
+cc_object {
+    name: "pvmfw_platform.dts.preprocessed",
+    header_libs: ["arm_dt_bindings_headers"],
+    host_supported: true,
+    srcs: [":pvmfw_platform.dts.renamed"],
+    cflags: [
+        "-E",
+        "-P",
+        "-xassembler-with-cpp", // allow C preprocessor directives
     ],
+    visibility: ["//visibility:private"],
+}
+
+// Compile the preprocessed dts into binary and create a rust library source
+// having the binary.
+cc_genrule {
+    name: "pvmfw_fdt_template_rs",
+    srcs: [":pvmfw_platform.dts.preprocessed"],
     out: ["lib.rs"],
     tools: ["dtc"],
-    cmd: "prebuilts/clang/host/linux-x86/clang-r487747c/bin/clang " + // UGLY!!!
-        "-E -P -x assembler-with-cpp -I external/arm-trusted-firmware/include " +
-        "-o $(genDir)/preprocessed.dts $(location platform.dts) && " +
-        "$(location dtc) -I dts -O dtb -o $(genDir)/compiled.dtbo $(genDir)/preprocessed.dts && " +
+    cmd: "$(location dtc) -I dts -O dtb -o $(genDir)/compiled.dtbo $(in) && " +
         "(" +
         "    echo '#![no_std]';" +
         "    echo '#![allow(missing_docs)]';" +
@@ -170,6 +189,7 @@
         "    xxd -i < $(genDir)/compiled.dtbo;" +
         "    echo '];';" +
         ") > $(out)",
+    visibility: ["//visibility:private"],
 }
 
 rust_library_rlib {
diff --git a/pvmfw/avb/src/descriptor/collection.rs b/pvmfw/avb/src/descriptor/collection.rs
index 910a782..c6698c0 100644
--- a/pvmfw/avb/src/descriptor/collection.rs
+++ b/pvmfw/avb/src/descriptor/collection.rs
@@ -126,24 +126,23 @@
     descriptor: *const AvbDescriptor,
     user_data: *mut c_void,
 ) -> bool {
-    let res = user_data as *mut Result<Descriptors, AvbIOError>;
     // SAFETY: It is safe because the caller ensures that `user_data` points to a valid struct and
     // is initialized.
-    let Some(Ok(descriptors)) = (unsafe { res.as_mut() }) else {
+    let Some(res) = (unsafe { (user_data as *mut Result<Descriptors, AvbIOError>).as_mut() }) else {
+        return false;
+    };
+    let Ok(descriptors) = res else {
         return false;
     };
     // SAFETY: It is safe because the caller ensures that the `descriptor` pointer is non-null
     // and valid.
-    if let Err(e) = unsafe { try_check_and_save_descriptor(descriptor, descriptors) } {
-        // SAFETY: It is safe because the caller ensures that `user_data` points to a valid
-        // `Result<Descriptors, AvbIOError>` struct and has no other user when this is called.
-        unsafe {
+    unsafe { try_check_and_save_descriptor(descriptor, descriptors) }.map_or_else(
+        |e| {
             *res = Err(e);
-        }
-        false
-    } else {
-        true
-    }
+            false
+        },
+        |_| true,
+    )
 }
 
 /// # Safety
diff --git a/rialto/Android.bp b/rialto/Android.bp
index 5f5cde8..59f8ba2 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}");