Refactor Xlat Debug implementations

* Force hexadecimal formatting for addresses
* Convert Xlat::print into Debug implementation

Signed-off-by: Imre Kis <imre.kis@arm.com>
Change-Id: Ibaa8c2cbc2f3bf567f32df97755af38c7c96b86a
diff --git a/src/address.rs b/src/address.rs
index f1b5220..320a0d2 100644
--- a/src/address.rs
+++ b/src/address.rs
@@ -1,11 +1,11 @@
 // SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
 // SPDX-License-Identifier: MIT OR Apache-2.0
 
-use core::ops::Range;
+use core::{fmt, ops::Range};
 
 use super::TranslationGranule;
 
-#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
 pub struct PhysicalAddress(pub(super) usize);
 
 impl PhysicalAddress {
@@ -42,7 +42,15 @@
     }
 }
 
-#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
+impl fmt::Debug for PhysicalAddress {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_tuple("PA")
+            .field(&format_args!("{:#x}", self.0))
+            .finish()
+    }
+}
+
+#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
 pub struct VirtualAddress(pub(super) usize);
 
 impl VirtualAddress {
@@ -103,6 +111,14 @@
     }
 }
 
+impl fmt::Debug for VirtualAddress {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_tuple("VA")
+            .field(&format_args!("{:#x}", self.0))
+            .finish()
+    }
+}
+
 pub struct VirtualAddressRange {
     pub(super) start: VirtualAddress,
     pub(super) end: VirtualAddress,
diff --git a/src/granule.rs b/src/granule.rs
index 0263c90..caa8b97 100644
--- a/src/granule.rs
+++ b/src/granule.rs
@@ -1,7 +1,7 @@
 // SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
 // SPDX-License-Identifier: MIT OR Apache-2.0
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub enum TranslationGranule<const VA_BITS: usize> {
     Granule4k = 4 * 1024,
     Granule16k = 16 * 1024,
diff --git a/src/lib.rs b/src/lib.rs
index e8bd6eb..846351d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,6 +7,7 @@
 
 extern crate alloc;
 
+use core::fmt;
 use core::iter::zip;
 use core::panic;
 
@@ -14,7 +15,6 @@
 use alloc::format;
 use alloc::string::String;
 use block::{Block, BlockIterator};
-use log::debug;
 
 use bitflags::bitflags;
 use packed_struct::prelude::*;
@@ -111,11 +111,13 @@
     }
 }
 
+#[derive(Debug)]
 pub enum RegimeVaRange {
     Lower,
     Upper,
 }
 
+#[derive(Debug)]
 pub enum TranslationRegime {
     EL1_0(RegimeVaRange, u8), // EL1 and EL0 stage 1, TTBRx_EL1
     #[cfg(target_feature = "vh")]
@@ -487,28 +489,18 @@
         }
     }
 
-    /// Prints the translation tables to debug console recursively
-    pub fn print(&self) {
-        debug!("Xlat table -> {:#010x}", self.base_table.get_pa().0 as u64);
-        Self::print_table(
-            self.granule.initial_lookup_level(),
-            0,
-            unsafe { self.base_table.get_as_slice() },
-            self.granule,
-        );
-    }
-
     /// Prints a single translation table to the debug console
     /// # Arguments
     /// * level: Level of the translation table
     /// * va: Base virtual address of the table
     /// * table: Table entries
-    pub fn print_table(
+    fn dump_table(
+        f: &mut fmt::Formatter<'_>,
         level: isize,
         va: usize,
         table: &[Descriptor],
         granule: TranslationGranule<VA_BITS>,
-    ) {
+    ) -> fmt::Result {
         let level_prefix = match level {
             0 | 1 => "|-",
             2 => "|  |-",
@@ -517,26 +509,32 @@
 
         for (descriptor, va) in zip(table, (va..).step_by(granule.block_size_at_level(level))) {
             match descriptor.get_descriptor_type(level) {
-                DescriptorType::Block => debug!(
-                    "{} {:#010x} Block -> {:#010x}",
-                    level_prefix,
-                    va,
-                    descriptor.get_block_output_address(granule, level).0
-                ),
+                DescriptorType::Block => {
+                    writeln!(
+                        f,
+                        "{} {:#010x} Block -> {:#010x}",
+                        level_prefix,
+                        va,
+                        descriptor.get_block_output_address(granule, level).0
+                    )?;
+                }
                 DescriptorType::Table => {
                     let next_level_table =
                         unsafe { descriptor.get_next_level_table(granule, level) };
-                    debug!(
+                    writeln!(
+                        f,
                         "{} {:#010x} Table -> {:#010x}",
                         level_prefix,
                         va,
                         next_level_table.as_ptr() as usize
-                    );
-                    Self::print_table(level + 1, va, next_level_table, granule);
+                    )?;
+                    Self::dump_table(f, level + 1, va, next_level_table, granule)?;
                 }
                 _ => {}
             }
         }
+
+        Ok(())
     }
 
     /// Adds memory region from the translation table. The function splits the region to blocks and
@@ -918,3 +916,24 @@
         }
     }
 }
+
+impl<const VA_BITS: usize> fmt::Debug for Xlat<VA_BITS> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("Xlat")
+            .field("regime", &self.regime)
+            .field("granule", &self.granule)
+            .field("VA_BITS", &VA_BITS)
+            .field("base_table", &self.base_table.get_pa())
+            .finish()?;
+
+        Self::dump_table(
+            f,
+            self.granule.initial_lookup_level(),
+            0,
+            unsafe { self.base_table.get_as_slice() },
+            self.granule,
+        )?;
+
+        Ok(())
+    }
+}