u-boot mirroring support

Design is at the link below.
https://gerrit.openbmc.org/c/openbmc/docs/+/58025

Tested:
  Tested all "Test Scenarios" specified in the design.

Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
Change-Id: I064115ee1e966a0a1b3ce7ec246c1f88f0bd87f7
diff --git a/meson.build b/meson.build
index 0bca0cf..0d9d68d 100644
--- a/meson.build
+++ b/meson.build
@@ -200,6 +200,7 @@
         'mmc/obmc-flash-mmc-remove@.service.in',
         'mmc/obmc-flash-mmc-setprimary@.service.in',
         'mmc/obmc-flash-mmc-umount.service.in',
+        'mmc/obmc-flash-mmc-mirroruboot.service.in',
     ]
 endif
 
diff --git a/mmc/item_updater_helper.cpp b/mmc/item_updater_helper.cpp
index 70a94bf..db271ab 100644
--- a/mmc/item_updater_helper.cpp
+++ b/mmc/item_updater_helper.cpp
@@ -64,7 +64,11 @@
 
 void Helper::mirrorAlt()
 {
-    // Empty
+    auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                      SYSTEMD_INTERFACE, "StartUnit");
+    auto serviceFile = "obmc-flash-mmc-mirroruboot.service";
+    method.append(serviceFile, "replace");
+    bus.call_noreply(method);
 }
 
 } // namespace updater
diff --git a/mmc/obmc-flash-mmc-mirroruboot.service.in b/mmc/obmc-flash-mmc-mirroruboot.service.in
new file mode 100644
index 0000000..97117e3
--- /dev/null
+++ b/mmc/obmc-flash-mmc-mirroruboot.service.in
@@ -0,0 +1,7 @@
+[Unit]
+Description=Copy uboot from the currently booted bmc chip to the alternate chip
+
+[Service]
+Type=oneshot
+RemainAfterExit=no
+ExecStart=/usr/bin/obmc-flash-bmc mmc-mirroruboot
diff --git a/obmc-flash-bmc b/obmc-flash-bmc
index b76ad62..833a565 100644
--- a/obmc-flash-bmc
+++ b/obmc-flash-bmc
@@ -629,6 +629,33 @@
     fw_setenv bootside "${flashid}"
 }
 
+function mmc_mirroruboot() {
+    # Get current boot device; 0-primary_bootdev device; 1 - alt_bootdev
+    bootdev=$(cat /sys/kernel/debug/aspeed/sbc/abr_image)
+    if [[ "${bootdev}" == "0" ]]; then
+        bootPartition="mmcblk0boot0"
+        alt_bootPartition="mmcblk0boot1"
+    else
+        bootPartition="mmcblk0boot1"
+        alt_bootPartition="mmcblk0boot0"
+    fi
+
+    devUBoot="/dev/${bootPartition}"
+    alt_devUBoot="/dev/${alt_bootPartition}"
+
+    checksum_UBoot="$(md5sum "${devUBoot}")"
+    checksum_UBoot="${checksum_UBoot% *}"
+    checksum_alt_UBoot="$(md5sum "${alt_devUBoot}")"
+    checksum_alt_UBoot="${checksum_alt% *}"
+
+    if [[ "${checksum_UBoot}" != "${checksum_alt_UBoot}" ]]; then
+        echo "Mirroring U-boot to alt chip"
+        echo 0 > "/sys/block/${alt_bootPartition}/force_ro"
+        dd if="${devUBoot}" of="${alt_devUBoot}"
+        echo 1 > "/sys/block/${alt_bootPartition}/force_ro"
+    fi
+}
+
 case "$1" in
     mtduboot)
         reqmtd="$2"
@@ -709,6 +736,9 @@
         flashid="$2"
         mmc_setprimary
         ;;
+    mmc-mirroruboot)
+        mmc_mirroruboot
+        ;;
     static-altfs)
         mount_static_alt "$2" "$3" "$4"
         ;;