pvmfw: test: Duplicate DeviceAssigningHypervisor

As vmbase currently can't be compiled for userspace (where unit tests
run) and given that we're about to merge libhyp into vmbase, duplicate
the DeviceAssigningHypervisor definition and provide a replacement for
hyp::Error so that our unit tests for device assignment keep running.

Test: m libpvmfw libpvmfw.device_assignment.test
Change-Id: Ib5fbc918388ad7c058cc215a6883c54067bf6cc8
diff --git a/pvmfw/src/device_assignment.rs b/pvmfw/src/device_assignment.rs
index 885cd22..f826167 100644
--- a/pvmfw/src/device_assignment.rs
+++ b/pvmfw/src/device_assignment.rs
@@ -28,6 +28,8 @@
 use core::iter::Iterator;
 use core::mem;
 use core::ops::Range;
+// TODO(ptosi): Remove the need for this workaround.
+#[cfg(not(test))]
 use hyp::DeviceAssigningHypervisor;
 use libfdt::{Fdt, FdtError, FdtNode, FdtNodeMut, Phandle, Reg};
 use log::error;
@@ -936,6 +938,18 @@
         Ok(())
     }
 
+    // TODO(b/308694211): Remove this workaround for visibility once using
+    // vmbase::hyp::DeviceAssigningHypervisor for tests.
+    #[cfg(test)]
+    fn parse(
+        fdt: &Fdt,
+        vm_dtbo: &VmDtbo,
+        hypervisor: &dyn DeviceAssigningHypervisor,
+    ) -> Result<Option<Self>> {
+        Self::internal_parse(fdt, vm_dtbo, hypervisor)
+    }
+
+    #[cfg(not(test))]
     /// Parses fdt and vm_dtbo, and creates new DeviceAssignmentInfo
     // TODO(b/277993056): Parse __local_fixups__
     // TODO(b/277993056): Parse __fixups__
@@ -944,6 +958,14 @@
         vm_dtbo: &VmDtbo,
         hypervisor: &dyn DeviceAssigningHypervisor,
     ) -> Result<Option<Self>> {
+        Self::internal_parse(fdt, vm_dtbo, hypervisor)
+    }
+
+    fn internal_parse(
+        fdt: &Fdt,
+        vm_dtbo: &VmDtbo,
+        hypervisor: &dyn DeviceAssigningHypervisor,
+    ) -> Result<Option<Self>> {
         let Some(symbols_node) = vm_dtbo.as_ref().symbols()? else {
             // /__symbols__ should contain all assignable devices.
             // If empty, then nothing can be assigned.
@@ -1061,6 +1083,39 @@
 }
 
 #[cfg(test)]
+#[derive(Clone, Copy, Debug)]
+enum MockHypervisorError {
+    FailedGetPhysMmioToken,
+    FailedGetPhysIommuToken,
+}
+
+#[cfg(test)]
+type MockHypervisorResult<T> = core::result::Result<T, MockHypervisorError>;
+
+#[cfg(test)]
+impl fmt::Display for MockHypervisorError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            MockHypervisorError::FailedGetPhysMmioToken => {
+                write!(f, "Failed to get physical MMIO token")
+            }
+            MockHypervisorError::FailedGetPhysIommuToken => {
+                write!(f, "Failed to get physical IOMMU token")
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+trait DeviceAssigningHypervisor {
+    /// Returns MMIO token.
+    fn get_phys_mmio_token(&self, base_ipa: u64, size: u64) -> MockHypervisorResult<u64>;
+
+    /// Returns DMA token as a tuple of (phys_iommu_id, phys_sid).
+    fn get_phys_iommu_token(&self, pviommu_id: u64, vsid: u64) -> MockHypervisorResult<(u64, u64)>;
+}
+
+#[cfg(test)]
 mod tests {
     use super::*;
     use alloc::collections::{BTreeMap, BTreeSet};
@@ -1105,18 +1160,20 @@
     }
 
     impl DeviceAssigningHypervisor for MockHypervisor {
-        fn get_phys_mmio_token(&self, base_ipa: u64, size: u64) -> hyp::Result<u64> {
-            Ok(*self.mmio_tokens.get(&(base_ipa, size)).ok_or(hyp::Error::KvmError(
-                hyp::KvmError::InvalidParameter,
-                0xc6000012, /* VENDOR_HYP_KVM_DEV_REQ_MMIO_FUNC_ID */
-            ))?)
+        fn get_phys_mmio_token(&self, base_ipa: u64, size: u64) -> MockHypervisorResult<u64> {
+            let token = self.mmio_tokens.get(&(base_ipa, size));
+
+            Ok(*token.ok_or(MockHypervisorError::FailedGetPhysMmioToken)?)
         }
 
-        fn get_phys_iommu_token(&self, pviommu_id: u64, vsid: u64) -> hyp::Result<(u64, u64)> {
-            Ok(*self.iommu_tokens.get(&(pviommu_id, vsid)).ok_or(hyp::Error::KvmError(
-                hyp::KvmError::InvalidParameter,
-                0xc6000013, /* VENDOR_HYP_KVM_DEV_REQ_DMA_FUNC_ID */
-            ))?)
+        fn get_phys_iommu_token(
+            &self,
+            pviommu_id: u64,
+            vsid: u64,
+        ) -> MockHypervisorResult<(u64, u64)> {
+            let token = self.iommu_tokens.get(&(pviommu_id, vsid));
+
+            Ok(*token.ok_or(MockHypervisorError::FailedGetPhysIommuToken)?)
         }
     }