[pvmfw] Move utility functions/consts relating to memory to vmbase

This cl moves some utility functions and constants relating to
memory aligment computation from pvmfw to vmbase for reuse in
rialto in the future.
No behavior change in this cl.

Bug: 284462758
Test: m pvmfw_img
Change-Id: I0ac7350c884ff00dd9379f736e9245aa39ed0b7a
diff --git a/pvmfw/src/config.rs b/pvmfw/src/config.rs
index 8d0c047..4086af7 100644
--- a/pvmfw/src/config.rs
+++ b/pvmfw/src/config.rs
@@ -14,11 +14,11 @@
 
 //! Support for the pvmfw configuration data format.
 
-use crate::helpers;
 use core::fmt;
 use core::mem;
 use core::ops::Range;
 use core::result;
+use vmbase::util::unchecked_align_up;
 use zerocopy::{FromBytes, LayoutVerified};
 
 /// Configuration data header.
@@ -101,8 +101,7 @@
 impl Header {
     const MAGIC: u32 = u32::from_ne_bytes(*b"pvmf");
     const VERSION_1_0: u32 = Self::version(1, 0);
-    const PADDED_SIZE: usize =
-        helpers::unchecked_align_up(mem::size_of::<Self>(), mem::size_of::<u64>());
+    const PADDED_SIZE: usize = unchecked_align_up(mem::size_of::<Self>(), mem::size_of::<u64>());
 
     pub const fn version(major: u16, minor: u16) -> u32 {
         ((major as u32) << 16) | (minor as u32)
diff --git a/pvmfw/src/entry.rs b/pvmfw/src/entry.rs
index 762b88b..6319863 100644
--- a/pvmfw/src/entry.rs
+++ b/pvmfw/src/entry.rs
@@ -33,7 +33,11 @@
 use log::info;
 use log::warn;
 use log::LevelFilter;
-use vmbase::{console, layout, logger, main, power::reboot};
+use vmbase::{
+    console, layout, logger, main,
+    memory::{SIZE_2MB, SIZE_4KB},
+    power::reboot,
+};
 use zeroize::Zeroize;
 
 #[derive(Debug, Clone)]
@@ -84,7 +88,7 @@
 impl<'a> MemorySlices<'a> {
     fn new(fdt: usize, kernel: usize, kernel_size: usize) -> Result<Self, RebootReason> {
         // SAFETY - SIZE_2MB is non-zero.
-        const FDT_SIZE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(helpers::SIZE_2MB) };
+        const FDT_SIZE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(SIZE_2MB) };
         // TODO - Only map the FDT as read-only, until we modify it right before jump_to_payload()
         // e.g. by generating a DTBO for a template DT in main() and, on return, re-map DT as RW,
         // overwrite with the template DT and apply the DTBO.
@@ -409,7 +413,7 @@
                 Some(Self::Config(config.unwrap()))
             }
             AppendedConfigType::NotFound if cfg!(feature = "legacy") => {
-                const BCC_SIZE: usize = helpers::SIZE_4KB;
+                const BCC_SIZE: usize = SIZE_4KB;
                 warn!("Assuming the appended data at {:?} to be a raw BCC", data.as_ptr());
                 Some(Self::LegacyBcc(&mut data[..BCC_SIZE]))
             }
diff --git a/pvmfw/src/exceptions.rs b/pvmfw/src/exceptions.rs
index 4b24d14..a10c300 100644
--- a/pvmfw/src/exceptions.rs
+++ b/pvmfw/src/exceptions.rs
@@ -14,11 +14,11 @@
 
 //! Exception handlers.
 
-use crate::helpers::page_4kb_of;
 use crate::memory::{MemoryTrackerError, MEMORY};
 use core::fmt;
 use vmbase::console;
 use vmbase::logger;
+use vmbase::memory::page_4kb_of;
 use vmbase::read_sysreg;
 use vmbase::{eprintln, power::reboot};
 
diff --git a/pvmfw/src/fdt.rs b/pvmfw/src/fdt.rs
index c0241ca..89d9457 100644
--- a/pvmfw/src/fdt.rs
+++ b/pvmfw/src/fdt.rs
@@ -16,10 +16,8 @@
 
 use crate::bootargs::BootArgsIterator;
 use crate::cstr;
-use crate::helpers::flatten;
 use crate::helpers::RangeExt as _;
 use crate::helpers::GUEST_PAGE_SIZE;
-use crate::helpers::SIZE_4KB;
 use crate::memory::BASE_ADDR;
 use crate::memory::MAX_ADDR;
 use crate::Box;
@@ -43,6 +41,8 @@
 use log::info;
 use log::warn;
 use tinyvec::ArrayVec;
+use vmbase::memory::SIZE_4KB;
+use vmbase::util::flatten;
 
 /// Extract from /config the address range containing the pre-loaded kernel. Absence of /config is
 /// not an error.
diff --git a/pvmfw/src/gpt.rs b/pvmfw/src/gpt.rs
index c3ccb5a..e0ffdc3 100644
--- a/pvmfw/src/gpt.rs
+++ b/pvmfw/src/gpt.rs
@@ -14,7 +14,6 @@
 
 //! Support for parsing GUID partition tables.
 
-use crate::helpers::ceiling_div;
 use crate::virtio::pci::VirtIOBlk;
 use core::cmp::min;
 use core::fmt;
@@ -25,6 +24,7 @@
 use static_assertions::const_assert_eq;
 use uuid::Uuid;
 use virtio_drivers::device::blk::SECTOR_SIZE;
+use vmbase::util::ceiling_div;
 use zerocopy::FromBytes;
 
 pub enum Error {
diff --git a/pvmfw/src/helpers.rs b/pvmfw/src/helpers.rs
index dcfd99c..bbec7a8 100644
--- a/pvmfw/src/helpers.rs
+++ b/pvmfw/src/helpers.rs
@@ -16,69 +16,14 @@
 
 use core::arch::asm;
 use core::ops::Range;
+use vmbase::memory::SIZE_4KB;
 use vmbase::read_sysreg;
+use vmbase::util::unchecked_align_down;
 use zeroize::Zeroize;
 
-pub const SIZE_4KB: usize = 4 << 10;
-pub const SIZE_2MB: usize = 2 << 20;
-pub const SIZE_4MB: usize = 4 << 20;
-
 pub const GUEST_PAGE_SIZE: usize = SIZE_4KB;
 pub const PVMFW_PAGE_SIZE: usize = SIZE_4KB;
 
-/// 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.
-pub const fn unchecked_align_down(addr: usize, alignment: usize) -> usize {
-    addr & !(alignment - 1)
-}
-
-/// Computes the smallest multiple of the provided alignment larger or equal to the address.
-///
-/// Note: the result is undefined if alignment isn't a power of two and may wrap to 0.
-pub const fn unchecked_align_up(addr: usize, alignment: usize) -> usize {
-    unchecked_align_down(addr + alignment - 1, alignment)
-}
-
-/// Safe wrapper around unchecked_align_up() that validates its assumptions and doesn't wrap.
-pub const fn align_up(addr: usize, alignment: usize) -> Option<usize> {
-    if !alignment.is_power_of_two() {
-        None
-    } else if let Some(s) = addr.checked_add(alignment - 1) {
-        Some(unchecked_align_down(s, alignment))
-    } else {
-        None
-    }
-}
-
-/// Performs an integer division rounding up.
-///
-/// Note: Returns None if den isn't a power of two.
-pub const fn ceiling_div(num: usize, den: usize) -> Option<usize> {
-    let Some(r) = align_up(num, den) else {
-        return None;
-    };
-
-    r.checked_div(den)
-}
-
-/// Aligns the given address to the given alignment, if it is a power of two.
-///
-/// Returns `None` if the alignment isn't a power of two.
-#[allow(dead_code)] // Currently unused but might be needed again.
-pub const fn align_down(addr: usize, alignment: usize) -> Option<usize> {
-    if !alignment.is_power_of_two() {
-        None
-    } else {
-        Some(unchecked_align_down(addr, alignment))
-    }
-}
-
-/// Computes the address of the 4KiB page containing a given address.
-pub const fn page_4kb_of(addr: usize) -> usize {
-    unchecked_align_down(addr, SIZE_4KB)
-}
-
 #[inline]
 /// Read the number of words in the smallest cache line of all the data caches and unified caches.
 pub fn min_dcache_line_size() -> usize {
@@ -124,15 +69,6 @@
     flush(reg)
 }
 
-/// Flatten [[T; N]] into &[T]
-/// TODO: use slice::flatten when it graduates from experimental
-pub fn flatten<T, const N: usize>(original: &[[T; N]]) -> &[T] {
-    // SAFETY: no overflow because original (whose size is len()*N) is already in memory
-    let len = original.len() * N;
-    // SAFETY: [T] has the same layout as [T;N]
-    unsafe { core::slice::from_raw_parts(original.as_ptr().cast(), len) }
-}
-
 /// Trait to check containment of one range within another.
 pub(crate) trait RangeExt {
     /// Returns true if `self` is contained within the `other` range.
diff --git a/pvmfw/src/instance.rs b/pvmfw/src/instance.rs
index 95ddefd..9a6a6e4 100644
--- a/pvmfw/src/instance.rs
+++ b/pvmfw/src/instance.rs
@@ -21,7 +21,6 @@
 use crate::gpt;
 use crate::gpt::Partition;
 use crate::gpt::Partitions;
-use crate::helpers::ceiling_div;
 use crate::rand;
 use crate::virtio::pci::VirtIOBlkIterator;
 use core::fmt;
@@ -32,6 +31,7 @@
 use log::trace;
 use uuid::Uuid;
 use virtio_drivers::transport::pci::bus::PciRoot;
+use vmbase::util::ceiling_div;
 use zerocopy::AsBytes;
 use zerocopy::FromBytes;
 
diff --git a/pvmfw/src/memory.rs b/pvmfw/src/memory.rs
index 76950a2..1467611 100644
--- a/pvmfw/src/memory.rs
+++ b/pvmfw/src/memory.rs
@@ -16,7 +16,7 @@
 
 #![deny(unsafe_op_in_unsafe_fn)]
 
-use crate::helpers::{self, page_4kb_of, RangeExt, PVMFW_PAGE_SIZE, SIZE_4MB};
+use crate::helpers::{self, RangeExt, PVMFW_PAGE_SIZE};
 use aarch64_paging::idmap::IdMap;
 use aarch64_paging::paging::{Attributes, Descriptor, MemoryRegion as VaRange};
 use aarch64_paging::MapError;
@@ -40,8 +40,12 @@
 use tinyvec::ArrayVec;
 use vmbase::{
     dsb, isb, layout,
-    memory::{set_dbm_enabled, MemorySharer, PageTable, MMIO_LAZY_MAP_FLAG},
+    memory::{
+        page_4kb_of, set_dbm_enabled, MemorySharer, PageTable, MMIO_LAZY_MAP_FLAG, SIZE_2MB,
+        SIZE_4KB, SIZE_4MB,
+    },
     tlbi,
+    util::align_up,
 };
 
 /// Base of the system's contiguous "main" memory.
@@ -546,9 +550,9 @@
 
 /// Returns memory range reserved for the appended payload.
 pub fn appended_payload_range() -> Range<usize> {
-    let start = helpers::align_up(layout::binary_end(), helpers::SIZE_4KB).unwrap();
+    let start = align_up(layout::binary_end(), SIZE_4KB).unwrap();
     // pvmfw is contained in a 2MiB region so the payload can't be larger than the 2MiB alignment.
-    let end = helpers::align_up(start, helpers::SIZE_2MB).unwrap();
+    let end = align_up(start, SIZE_2MB).unwrap();
     start..end
 }
 
diff --git a/vmbase/src/lib.rs b/vmbase/src/lib.rs
index 2541b8a..80cdf4e 100644
--- a/vmbase/src/lib.rs
+++ b/vmbase/src/lib.rs
@@ -28,6 +28,7 @@
 pub mod memory;
 pub mod power;
 pub mod uart;
+pub mod util;
 
 pub use bionic::STACK_CHK_GUARD;
 
diff --git a/vmbase/src/memory/mod.rs b/vmbase/src/memory/mod.rs
index 5e1065a..3b1b384 100644
--- a/vmbase/src/memory/mod.rs
+++ b/vmbase/src/memory/mod.rs
@@ -22,4 +22,4 @@
 pub use dbm::set_dbm_enabled;
 pub use page_table::{PageTable, MMIO_LAZY_MAP_FLAG};
 pub use shared::MemorySharer;
-pub use util::{phys_to_virt, virt_to_phys};
+pub use util::{page_4kb_of, phys_to_virt, virt_to_phys, SIZE_2MB, SIZE_4KB, SIZE_4MB};
diff --git a/vmbase/src/memory/util.rs b/vmbase/src/memory/util.rs
index 5b89cd1..3186409 100644
--- a/vmbase/src/memory/util.rs
+++ b/vmbase/src/memory/util.rs
@@ -14,8 +14,21 @@
 
 //! Utility functions for memory management.
 
+use crate::util::unchecked_align_down;
 use core::ptr::NonNull;
 
+/// The size of a 4KB memory in bytes.
+pub const SIZE_4KB: usize = 4 << 10;
+/// The size of a 2MB memory in bytes.
+pub const SIZE_2MB: usize = 2 << 20;
+/// The size of a 4MB memory in bytes.
+pub const SIZE_4MB: usize = 4 << 20;
+
+/// Computes the address of the 4KiB page containing a given address.
+pub const fn page_4kb_of(addr: usize) -> usize {
+    unchecked_align_down(addr, SIZE_4KB)
+}
+
 /// Returns the intermediate physical address corresponding to the given virtual address.
 ///
 /// As we use identity mapping for everything, this is just a cast, but it's useful to use it to be
diff --git a/vmbase/src/util.rs b/vmbase/src/util.rs
new file mode 100644
index 0000000..7396edc
--- /dev/null
+++ b/vmbase/src/util.rs
@@ -0,0 +1,72 @@
+// 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.
+
+//! Utility functions.
+
+/// Flatten [[T; N]] into &[T]
+/// TODO: use slice::flatten when it graduates from experimental
+pub fn flatten<T, const N: usize>(original: &[[T; N]]) -> &[T] {
+    // SAFETY: no overflow because original (whose size is len()*N) is already in memory
+    let len = original.len() * N;
+    // SAFETY: [T] has the same layout as [T;N]
+    unsafe { core::slice::from_raw_parts(original.as_ptr().cast(), len) }
+}
+
+/// 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.
+pub const fn unchecked_align_down(addr: usize, alignment: usize) -> usize {
+    addr & !(alignment - 1)
+}
+
+/// Computes the smallest multiple of the provided alignment larger or equal to the address.
+///
+/// Note: the result is undefined if alignment isn't a power of two and may wrap to 0.
+pub const fn unchecked_align_up(addr: usize, alignment: usize) -> usize {
+    unchecked_align_down(addr + alignment - 1, alignment)
+}
+
+/// Safe wrapper around unchecked_align_up() that validates its assumptions and doesn't wrap.
+pub const fn align_up(addr: usize, alignment: usize) -> Option<usize> {
+    if !alignment.is_power_of_two() {
+        None
+    } else if let Some(s) = addr.checked_add(alignment - 1) {
+        Some(unchecked_align_down(s, alignment))
+    } else {
+        None
+    }
+}
+
+/// Aligns the given address to the given alignment, if it is a power of two.
+///
+/// Returns `None` if the alignment isn't a power of two.
+#[allow(dead_code)] // Currently unused but might be needed again.
+const fn align_down(addr: usize, alignment: usize) -> Option<usize> {
+    if !alignment.is_power_of_two() {
+        None
+    } else {
+        Some(unchecked_align_down(addr, alignment))
+    }
+}
+
+/// Performs an integer division rounding up.
+///
+/// Note: Returns None if den isn't a power of two.
+pub const fn ceiling_div(num: usize, den: usize) -> Option<usize> {
+    let Some(r) = align_up(num, den) else {
+        return None;
+    };
+
+    r.checked_div(den)
+}