[pvmfw] Move assembly wrappers to vmbase for reuse

In both pvmfw and rialo.

Test: atest libpvmfw.bootargs.test
Test: m pvmfw_img
Bug: 282928116

Change-Id: If93cfca26cddcc27aca15baae85a0f7609160c42
diff --git a/pvmfw/src/bootargs.rs b/pvmfw/src/bootargs.rs
index f9c8278..e4b1b65 100644
--- a/pvmfw/src/bootargs.rs
+++ b/pvmfw/src/bootargs.rs
@@ -106,14 +106,14 @@
 }
 
 #[cfg(test)]
-#[allow(dead_code)]
-mod helpers;
-
-#[cfg(test)]
 mod tests {
-
     use super::*;
-    use crate::cstr;
+
+    macro_rules! cstr {
+        ($str:literal) => {{
+            core::ffi::CStr::from_bytes_with_nul(concat!($str, "\0").as_bytes()).unwrap()
+        }};
+    }
 
     fn check(raw: &CStr, expected: Result<&[(&str, Option<&str>)], ()>) {
         let actual = BootArgsIterator::new(raw);
diff --git a/pvmfw/src/exceptions.rs b/pvmfw/src/exceptions.rs
index e819729..4b24d14 100644
--- a/pvmfw/src/exceptions.rs
+++ b/pvmfw/src/exceptions.rs
@@ -14,11 +14,12 @@
 
 //! Exception handlers.
 
+use crate::helpers::page_4kb_of;
 use crate::memory::{MemoryTrackerError, MEMORY};
-use crate::{helpers::page_4kb_of, read_sysreg};
 use core::fmt;
 use vmbase::console;
 use vmbase::logger;
+use vmbase::read_sysreg;
 use vmbase::{eprintln, power::reboot};
 
 const UART_PAGE: usize = page_4kb_of(console::BASE_ADDRESS);
diff --git a/pvmfw/src/helpers.rs b/pvmfw/src/helpers.rs
index 9c4cb1b..1d39e1f 100644
--- a/pvmfw/src/helpers.rs
+++ b/pvmfw/src/helpers.rs
@@ -16,6 +16,7 @@
 
 use core::arch::asm;
 use core::ops::Range;
+use vmbase::read_sysreg;
 use zeroize::Zeroize;
 
 pub const SIZE_4KB: usize = 4 << 10;
@@ -25,41 +26,6 @@
 pub const GUEST_PAGE_SIZE: usize = SIZE_4KB;
 pub const PVMFW_PAGE_SIZE: usize = SIZE_4KB;
 
-/// Read a value from a system register.
-#[macro_export]
-macro_rules! read_sysreg {
-    ($sysreg:literal) => {{
-        let mut r: usize;
-        // Safe because it reads a system register and does not affect Rust.
-        #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
-        unsafe {
-            core::arch::asm!(
-                concat!("mrs {}, ", $sysreg),
-                out(reg) r,
-                options(nomem, nostack, preserves_flags),
-            )
-        }
-        r
-    }};
-}
-
-/// Write a value to a system register.
-///
-/// # Safety
-///
-/// Callers must ensure that side effects of updating the system register are properly handled.
-#[macro_export]
-macro_rules! write_sysreg {
-    ($sysreg:literal, $val:expr) => {{
-        let value: usize = $val;
-        core::arch::asm!(
-            concat!("msr ", $sysreg, ", {}"),
-            in(reg) value,
-            options(nomem, nostack, preserves_flags),
-        )
-    }};
-}
-
 /// Computes the largest multiple of the provided alignment smaller or equal to the address.
 ///
 /// Note: the result is undefined if alignment isn't a power of two.
@@ -196,46 +162,3 @@
     const DBM_AVAILABLE: usize = 1 << 1;
     read_sysreg!("id_aa64mmfr1_el1") & DBM_AVAILABLE != 0
 }
-
-/// Executes a data synchronization barrier.
-#[macro_export]
-macro_rules! dsb {
-    ($option:literal) => {{
-        // Safe because this is just a memory barrier and does not affect Rust.
-        #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
-        unsafe {
-            core::arch::asm!(concat!("dsb ", $option), options(nomem, nostack, preserves_flags));
-        }
-    }};
-}
-
-/// Executes an instruction synchronization barrier.
-#[macro_export]
-macro_rules! isb {
-    () => {{
-        // Safe because this is just a memory barrier and does not affect Rust.
-        #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
-        unsafe {
-            core::arch::asm!("isb", options(nomem, nostack, preserves_flags));
-        }
-    }};
-}
-
-/// Invalidates cached leaf PTE entries by virtual address.
-#[macro_export]
-macro_rules! tlbi {
-    ($option:literal, $asid:expr, $addr:expr) => {{
-        let asid: usize = $asid;
-        let addr: usize = $addr;
-        // Safe because it invalidates TLB and doesn't affect Rust. When the address matches a
-        // block entry larger than the page size, all translations for the block are invalidated.
-        #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
-        unsafe {
-            core::arch::asm!(
-                concat!("tlbi ", $option, ", {x}"),
-                x = in(reg) (asid << 48) | (addr >> 12),
-                options(nomem, nostack, preserves_flags)
-            );
-        }
-    }};
-}
diff --git a/pvmfw/src/memory.rs b/pvmfw/src/memory.rs
index 2f6e7a4..c316dd2 100644
--- a/pvmfw/src/memory.rs
+++ b/pvmfw/src/memory.rs
@@ -18,7 +18,6 @@
 
 use crate::helpers::{self, dbm_available, page_4kb_of, RangeExt, PVMFW_PAGE_SIZE, SIZE_4MB};
 use crate::mmu;
-use crate::{dsb, isb, read_sysreg, tlbi, write_sysreg};
 use aarch64_paging::paging::{Attributes, Descriptor, MemoryRegion as VaRange};
 use alloc::alloc::alloc_zeroed;
 use alloc::alloc::dealloc;
@@ -41,6 +40,7 @@
 use once_cell::race::OnceBox;
 use spin::mutex::SpinMutex;
 use tinyvec::ArrayVec;
+use vmbase::{dsb, isb, read_sysreg, tlbi, write_sysreg};
 
 /// Base of the system's contiguous "main" memory.
 pub const BASE_ADDR: usize = 0x8000_0000;
diff --git a/vmbase/src/arch.rs b/vmbase/src/arch.rs
new file mode 100644
index 0000000..d7b63b3
--- /dev/null
+++ b/vmbase/src/arch.rs
@@ -0,0 +1,93 @@
+// 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.
+
+//! Wrappers of assembly calls.
+
+/// Reads a value from a system register.
+#[macro_export]
+macro_rules! read_sysreg {
+    ($sysreg:literal) => {{
+        let mut r: usize;
+        // Safe because it reads a system register and does not affect Rust.
+        #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
+        unsafe {
+            core::arch::asm!(
+                concat!("mrs {}, ", $sysreg),
+                out(reg) r,
+                options(nomem, nostack, preserves_flags),
+            )
+        }
+        r
+    }};
+}
+
+/// Writes a value to a system register.
+///
+/// # Safety
+///
+/// Callers must ensure that side effects of updating the system register are properly handled.
+#[macro_export]
+macro_rules! write_sysreg {
+    ($sysreg:literal, $val:expr) => {{
+        let value: usize = $val;
+        core::arch::asm!(
+            concat!("msr ", $sysreg, ", {}"),
+            in(reg) value,
+            options(nomem, nostack, preserves_flags),
+        )
+    }};
+}
+
+/// Executes an instruction synchronization barrier.
+#[macro_export]
+macro_rules! isb {
+    () => {{
+        // Safe because this is just a memory barrier and does not affect Rust.
+        #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
+        unsafe {
+            core::arch::asm!("isb", options(nomem, nostack, preserves_flags));
+        }
+    }};
+}
+
+/// Executes a data synchronization barrier.
+#[macro_export]
+macro_rules! dsb {
+    ($option:literal) => {{
+        // Safe because this is just a memory barrier and does not affect Rust.
+        #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
+        unsafe {
+            core::arch::asm!(concat!("dsb ", $option), options(nomem, nostack, preserves_flags));
+        }
+    }};
+}
+
+/// Invalidates cached leaf PTE entries by virtual address.
+#[macro_export]
+macro_rules! tlbi {
+    ($option:literal, $asid:expr, $addr:expr) => {{
+        let asid: usize = $asid;
+        let addr: usize = $addr;
+        // Safe because it invalidates TLB and doesn't affect Rust. When the address matches a
+        // block entry larger than the page size, all translations for the block are invalidated.
+        #[allow(unused_unsafe)] // In case the macro is used within an unsafe block.
+        unsafe {
+            core::arch::asm!(
+                concat!("tlbi ", $option, ", {x}"),
+                x = in(reg) (asid << 48) | (addr >> 12),
+                options(nomem, nostack, preserves_flags)
+            );
+        }
+    }};
+}
diff --git a/vmbase/src/lib.rs b/vmbase/src/lib.rs
index d577802..0eca1e4 100644
--- a/vmbase/src/lib.rs
+++ b/vmbase/src/lib.rs
@@ -16,6 +16,7 @@
 
 #![no_std]
 
+pub mod arch;
 mod bionic;
 pub mod console;
 mod entry;