vmbase: Move hvc to aarch64

This commit move ARM hypercall interface to aarch64 directories.

Bug: 362733888
Test: m libvmbase

Change-Id: I17666437670feb9528c6871a36f9d6ecd3ea95d4
diff --git a/libs/libvmbase/src/arch/aarch64.rs b/libs/libvmbase/src/arch/aarch64.rs
index a3f1dd5..f888ccf 100644
--- a/libs/libvmbase/src/arch/aarch64.rs
+++ b/libs/libvmbase/src/arch/aarch64.rs
@@ -15,6 +15,7 @@
 //! Wrappers of assembly calls.
 
 pub mod dbm;
+pub mod hvc;
 pub mod layout;
 pub mod linker;
 pub mod page_table;
diff --git a/libs/libvmbase/src/arch/aarch64/hvc.rs b/libs/libvmbase/src/arch/aarch64/hvc.rs
new file mode 100644
index 0000000..b20f62d
--- /dev/null
+++ b/libs/libvmbase/src/arch/aarch64/hvc.rs
@@ -0,0 +1,67 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Wrappers around calls to the hypervisor.
+
+/// TRNG ARM specific module
+pub mod trng;
+use self::trng::Error;
+use smccc::{
+    error::{positive_or_error_64, success_or_error_64},
+    hvc64,
+};
+
+/// ARM HVC call number that will return TRNG version
+const ARM_SMCCC_TRNG_VERSION: u32 = 0x8400_0050;
+/// ARM TRNG feature hypercall number
+const ARM_SMCCC_TRNG_FEATURES: u32 = 0x8400_0051;
+#[allow(dead_code)]
+/// ARM SMCC TRNG get uuid hypercall number
+const ARM_SMCCC_TRNG_GET_UUID: u32 = 0x8400_0052;
+#[allow(dead_code)]
+/// ARM SMCC TRNG 32BIT random hypercall number
+const ARM_SMCCC_TRNG_RND32: u32 = 0x8400_0053;
+
+/// ARM SMCCC 64BIT random hypercall number
+pub const ARM_SMCCC_TRNG_RND64: u32 = 0xc400_0053;
+
+/// Returns the (major, minor) version tuple, as defined by the SMCCC TRNG.
+pub fn trng_version() -> trng::Result<trng::Version> {
+    let args = [0u64; 17];
+
+    let version = positive_or_error_64::<Error>(hvc64(ARM_SMCCC_TRNG_VERSION, args)[0])?;
+    (version as u32 as i32).try_into()
+}
+
+/// Buffer for random number
+pub type TrngRng64Entropy = [u64; 3];
+
+/// Return hardware backed entropy from TRNG
+pub fn trng_rnd64(nbits: u64) -> trng::Result<TrngRng64Entropy> {
+    let mut args = [0u64; 17];
+    args[0] = nbits;
+
+    let regs = hvc64(ARM_SMCCC_TRNG_RND64, args);
+    success_or_error_64::<Error>(regs[0])?;
+
+    Ok([regs[1], regs[2], regs[3]])
+}
+
+/// Return TRNG feature
+pub fn trng_features(fid: u32) -> trng::Result<u64> {
+    let mut args = [0u64; 17];
+    args[0] = fid as u64;
+
+    positive_or_error_64::<Error>(hvc64(ARM_SMCCC_TRNG_FEATURES, args)[0])
+}
diff --git a/libs/libvmbase/src/arch/aarch64/hvc/trng.rs b/libs/libvmbase/src/arch/aarch64/hvc/trng.rs
new file mode 100644
index 0000000..26a515e
--- /dev/null
+++ b/libs/libvmbase/src/arch/aarch64/hvc/trng.rs
@@ -0,0 +1,97 @@
+// Copyright 2023, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use core::fmt;
+use core::result;
+
+/// Standard SMCCC TRNG error values as described in DEN 0098 1.0 REL0.
+#[derive(Debug, Clone, PartialEq)]
+pub enum Error {
+    /// The call is not supported by the implementation.
+    NotSupported,
+    /// One of the call parameters has a non-supported value.
+    InvalidParameter,
+    /// Call returned without the requested entropy bits.
+    NoEntropy,
+    /// Negative values indicate error.
+    Unknown(i64),
+    /// The call returned a positive value when 0 was expected.
+    Unexpected(u64),
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            Self::NotSupported => write!(f, "SMCCC TRNG call not supported"),
+            Self::InvalidParameter => write!(f, "SMCCC TRNG call received non-supported value"),
+            Self::NoEntropy => write!(f, "SMCCC TRNG call returned no entropy"),
+            Self::Unexpected(v) => write!(f, "Unexpected SMCCC TRNG return value {} ({0:#x})", v),
+            Self::Unknown(e) => write!(f, "Unknown SMCCC TRNG return value {} ({0:#x})", e),
+        }
+    }
+}
+
+impl From<i64> for Error {
+    fn from(value: i64) -> Self {
+        match value {
+            -1 => Error::NotSupported,
+            -2 => Error::InvalidParameter,
+            -3 => Error::NoEntropy,
+            _ if value < 0 => Error::Unknown(value),
+            _ => Error::Unexpected(value as u64),
+        }
+    }
+}
+
+/// Local result alias
+pub type Result<T> = result::Result<T, Error>;
+
+/// A version of the SMCCC TRNG interface.
+#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
+pub struct Version {
+    /// Version majon number
+    pub major: u16,
+    /// Version minor number
+    pub minor: u16,
+}
+
+impl fmt::Display for Version {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}.{}", self.major, self.minor)
+    }
+}
+
+impl fmt::Debug for Version {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self, f)
+    }
+}
+
+impl TryFrom<i32> for Version {
+    type Error = Error;
+
+    fn try_from(value: i32) -> core::result::Result<Self, Error> {
+        if value < 0 {
+            Err((value as i64).into())
+        } else {
+            Ok(Self { major: (value >> 16) as u16, minor: value as u16 })
+        }
+    }
+}
+
+impl From<Version> for u32 {
+    fn from(version: Version) -> Self {
+        (u32::from(version.major) << 16) | u32::from(version.minor)
+    }
+}