Embed the compiled template DT into pvmfw

Specifically, the source dts file is pre-processed by clang to use some
macros from the ARM dt-bindings headers. Then it is actually compiled
into dtbo via the dtc compiler. Then create a rust source file where the
content of the dtbo file is written as a byte array.

Bug: 249054080
Test: m pvmfw
Change-Id: Ib3ab38a10b27001c3e0ee43b3526fc624f8d1a03
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index d78f4f2..b56df4f 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -22,6 +22,7 @@
         "libonce_cell_nostd",
         "libpvmfw_avb_nostd",
         "libpvmfw_embedded_key",
+        "libpvmfw_fdt_template",
         "libstatic_assertions",
         "libtinyvec_nostd",
         "libuuid_nostd",
@@ -117,6 +118,37 @@
     installable: false,
 }
 
+// platform.dts is passed to clang for macro preprocessing, and then compiled to dtbo using dtc.
+// The raw content of the dtbo file is then written as a Rust byte array.
+genrule {
+    name: "pvmfw_fdt_template_rs",
+    srcs: [
+        "platform.dts",
+        ":arm_dt_bindings_headers", // implicit dependency
+    ],
+    out: ["lib.rs"],
+    tools: ["dtc"],
+    cmd: "prebuilts/clang/host/linux-x86/clang-r487747/bin/clang " + // UGLY!!!
+        "-E -P -x assembler-with-cpp -I external/arm-trusted-firmware/include " +
+        "-o $(genDir)/preprocessed.dts $(location platform.dts) && " +
+        "$(location dtc) -I dts -O dtb -o $(genDir)/compiled.dtbo $(genDir)/preprocessed.dts && " +
+        "(" +
+        "    echo '#![no_std]';" +
+        "    echo '#![allow(missing_docs)]';" +
+        "    echo 'pub const RAW: &[u8] = &[';" +
+        "    xxd -i < $(genDir)/compiled.dtbo;" +
+        "    echo '];';" +
+        ") > $(out)",
+}
+
+rust_library_rlib {
+    name: "libpvmfw_fdt_template",
+    defaults: ["vmbase_ffi_defaults"],
+    prefer_rlib: true,
+    srcs: [":pvmfw_fdt_template_rs"],
+    crate_name: "pvmfw_fdt_template",
+}
+
 bootimg {
     name: "pvmfw_img",
     stem: "pvmfw.img",