image_types_gbmc_dynamic: Support more bootloader params

This intends to make the parsing logic more flexible and replace
multiple different types of addresses or offsets + lengths of the kernel
data in the u-boot command line.

Tested: Built an aspeed image using the dynamic parameters and the
u-boot commnd lines look good. Also tested with dual spi on a nuvoton
BMC to verify that those commands lines are updated appropriately.

Google-Bug-Id: 340128436
Google-Bug-Id: 351901052
Change-Id: I203272073021d4cb3aabcf938402932839e149e9
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/classes/image_types_gbmc_dynamic.bbclass b/classes/image_types_gbmc_dynamic.bbclass
index 30f785a..5e740c2 100644
--- a/classes/image_types_gbmc_dynamic.bbclass
+++ b/classes/image_types_gbmc_dynamic.bbclass
@@ -243,20 +243,50 @@
   dtc-native:do_populate_sysroot \
   "
 
-UIMAGE_FLASH_ADDR = "invalid"
-UIMAGE_FLASH_ADDR:npcm7xx = "80200000"
-UIMAGE_FLASH_ADDR:npcm8xx = "80400000"
+# Addresses are always exactly 8 hex characters long, to avoid changing binary
+# size when performing the replacement
+UIMAGE_FLASH_NUM            = "${@"[0-9a-fA-F]"*8}"
+UIMAGE_FLASH_BASE           = "invalid"
+UIMAGE_FLASH_BASE:npcm7xx   = "80000000"
+UIMAGE_FLASH_BASE:npcm8xx   = "80000000"
+UIMAGE_FLASH_BASE:aspeed-g6 = "20000000"
 
+# Bootloaders should use the following variables if they want dynamic replacement
+# of fitImage location and size. We do not perform any other replacement to
+# avoid accidentally breaking u-boot.
+#  - `uimage_flash_addr=XXXXXXXX` The direct mapped address of the image in memory
+#  - `uimage_flash_offs=XXXXXXXX` The offset of the image in the SPI
+#  - `uimage_flash_size=XXXXXXXX` The size of the image
 do_modify_bootloaders() {
-    merged=${DEPLOY_DIR_IMAGE}/${UBOOT_BINARY}.${MERGED_SUFFIX}
-    msize=$(stat -c '%s' $merged)
+    bin=${DEPLOY_DIR_IMAGE}/${UBOOT_BINARY}.${MERGED_SUFFIX}
+    if [ ! -e $bin ]; then
+        bin=${DEPLOY_DIR_IMAGE}/u-boot.${UBOOT_SUFFIX}
+    fi
+    msize=$(stat -c '%s' $bin)
     # Partitions are 64K aligned, with u-boot then (64K) image descriptor then kernel
     kern_off=$(expr '(' $msize + 65535 ')' / 65536 '*' 65536 + 65536)
-    # Match the uimage_flash_addr format below with an 0x80000000 base
-    addr=$(printf '%08x' $(expr 2147483648 + $kern_off))
-    grep -q 'uimage_flash_addr=${UIMAGE_FLASH_ADDR}' $merged
-    sed -i "s,uimage_flash_addr=${UIMAGE_FLASH_ADDR},uimage_flash_addr=$addr," $merged
+    # Match the uimage_flash_addr format below the base + kernel offset
+    addr=$(printf '%08x' $(expr $(printf "%d" 0x${UIMAGE_FLASH_BASE}) + $kern_off))
+    off=$(printf '%08x' $kern_off)
+    size=$(printf '%08x' $(stat -c '%s' $(readlink -f ${DEPLOY_DIR_IMAGE}/${FLASH_KERNEL_IMAGE})))
+    replaced=
+    if grep -q 'uimage_flash_offs=${UIMAGE_FLASH_NUM}' $bin; then
+        sed -i "s,uimage_flash_offs=${UIMAGE_FLASH_NUM},uimage_flash_offs=$off,g" $bin
+        replaced=1
+    fi
+    if grep -q 'uimage_flash_addr=${UIMAGE_FLASH_NUM}' $bin; then
+        sed -i "s,uimage_flash_addr=${UIMAGE_FLASH_NUM},uimage_flash_addr=$addr,g" $bin
+        replaced=1
+    fi
+    if [ -z "$replaced" ]; then
+        echo "Don't know how to inject kernel offset into u-boot" >&2
+        exit 1
+    fi
     echo "Set uimage_flash_addr to $addr"
+    sed -i "s,uimage_flash_size=${UIMAGE_FLASH_NUM},uimage_flash_size=$size,g" $bin
 }
 
 addtask do_modify_bootloaders before do_generate_static after do_prepare_bootloaders do_merge_bootloaders
+do_modify_bootloaders[depends] += " \
+  virtual/kernel:do_deploy \
+  "