pvmfw: Implement jump_to_payload with asm!()

Move the start_payload routine to Rust as at the point where we might
call it, the system is in a state where Rust code can run and there is
then no reason to avoid the Rust compiler, unlike vmbase/entry.S. By
using asm!(), the compiler is made aware of the routine and will handle
ABI compatibility and more.

Test: atest MicrodroidTestApp
Change-Id: If9867d0142c1254e370f6c97d4f3ef749771afe2
diff --git a/pvmfw/src/entry.rs b/pvmfw/src/entry.rs
index 95dc0b0..a606462 100644
--- a/pvmfw/src/entry.rs
+++ b/pvmfw/src/entry.rs
@@ -15,8 +15,8 @@
 //! Low-level entry and exit points of pvmfw.
 
 use crate::helpers::FDT_MAX_SIZE;
-use crate::jump_to_payload;
 use crate::mmio_guard;
+use core::arch::asm;
 use core::slice;
 use log::{debug, LevelFilter};
 use vmbase::{console, logger, main, power::reboot};
@@ -79,3 +79,60 @@
 
     Ok(())
 }
+
+fn jump_to_payload(fdt_address: u64, payload_start: u64) -> ! {
+    const SCTLR_EL1_RES1: usize = (0b11 << 28) | (0b101 << 20) | (0b1 << 11);
+    // Stage 1 instruction access cacheability is unaffected.
+    const SCTLR_EL1_I: usize = 0b1 << 12;
+    // SETEND instruction disabled at EL0 in aarch32 mode.
+    const SCTLR_EL1_SED: usize = 0b1 << 8;
+    // Various IT instructions are disabled at EL0 in aarch32 mode.
+    const SCTLR_EL1_ITD: usize = 0b1 << 7;
+
+    const SCTLR_EL1_VAL: usize = SCTLR_EL1_RES1 | SCTLR_EL1_ITD | SCTLR_EL1_SED | SCTLR_EL1_I;
+
+    // SAFETY - We're exiting pvmfw by passing the register values we need to a noreturn asm!().
+    unsafe {
+        asm!(
+            "msr sctlr_el1, {sctlr_el1_val}",
+            "isb",
+            "mov x1, xzr",
+            "mov x2, xzr",
+            "mov x3, xzr",
+            "mov x4, xzr",
+            "mov x5, xzr",
+            "mov x6, xzr",
+            "mov x7, xzr",
+            "mov x8, xzr",
+            "mov x9, xzr",
+            "mov x10, xzr",
+            "mov x11, xzr",
+            "mov x12, xzr",
+            "mov x13, xzr",
+            "mov x14, xzr",
+            "mov x15, xzr",
+            "mov x16, xzr",
+            "mov x17, xzr",
+            "mov x18, xzr",
+            "mov x19, xzr",
+            "mov x20, xzr",
+            "mov x21, xzr",
+            "mov x22, xzr",
+            "mov x23, xzr",
+            "mov x24, xzr",
+            "mov x25, xzr",
+            "mov x26, xzr",
+            "mov x27, xzr",
+            "mov x28, xzr",
+            "mov x29, xzr",
+            "msr ttbr0_el1, xzr",
+            "isb",
+            "dsb nsh",
+            "br x30",
+            sctlr_el1_val = in(reg) SCTLR_EL1_VAL,
+            in("x0") fdt_address,
+            in("x30") payload_start,
+            options(nomem, noreturn, nostack),
+        );
+    };
+}