vmbase: uart: Move asm block to crate::arch

Move the manual assembly into the vmbase::arch module so that the
vmbase::uart driver remains arch-agnostic, making it easier to port to
other CPU architectures.

Note that the manual assembly is preferred over using the standard
write_volatile() due to b/345658173 and [1] (see also aosp/3125955).

[1]: https://github.com/rust-lang/rust/issues/131894

Test: m pvmfw # Then check disassembly for STRB
Change-Id: I6d404df4c0439b8e208d1ef533b60434d2b2bec8
diff --git a/libs/libvmbase/src/arch.rs b/libs/libvmbase/src/arch.rs
index d8bb8b2..992ab27 100644
--- a/libs/libvmbase/src/arch.rs
+++ b/libs/libvmbase/src/arch.rs
@@ -91,3 +91,22 @@
         }
     }};
 }
+
+/// Write with well-defined compiled behavior.
+///
+/// See https://github.com/rust-lang/rust/issues/131894
+///
+/// # Safety
+///
+/// `dst` must be valid for writes.
+pub unsafe fn write_volatile_u8(dst: *mut u8, src: u8) {
+    // SAFETY: strb only modifies *dst, which must be valid for writes.
+    unsafe {
+        core::arch::asm!(
+            "strb {value:w}, [{ptr}]",
+            value = in(reg) src,
+            ptr = in(reg) dst,
+            options(preserves_flags),
+        );
+    }
+}