image_classes_dynamic: Support arbitrary address size

Some of our 64bit platforms now have a flash peripheral that resides
outside of the 32bit address space. We now need 9 or more nibbles to
express the size. To better support this, we make the address
replacement dynamic. The lower 7 nibbles of the address (28 bits) are
used for the offset into the flash, while the upper nibbles are used
for the address to the peripheral.

Tested: Built a 7xx and 8xx platform that use dynamic images and
verified manually that their command lines reflect valid flash
addresses.

Google-Bug-Id: 397986419
Change-Id: Ifc1caa9fdc0ae038cf8ad1d1360b99ce30c8773a
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 e88a377..34ed1c0 100644
--- a/classes/image_types_gbmc_dynamic.bbclass
+++ b/classes/image_types_gbmc_dynamic.bbclass
@@ -243,22 +243,18 @@
   dtc-native:do_populate_sysroot \
   "
 
-# 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_NUM:aspeed-g7  = "${@"[0-9a-fA-F]"*9}"
-UIMAGE_FLASH_BASE           = "invalid"
-UIMAGE_FLASH_BASE:npcm7xx   = "80000000"
-UIMAGE_FLASH_BASE:npcm8xx   = "80000000"
-UIMAGE_FLASH_BASE:aspeed-g6 = "20000000"
-UIMAGE_FLASH_BASE:aspeed-g7 = "100000000"
+# Flash addresses are always 7 nibbles long, however the absolute memory address
+# may require up to 64 bits (9 additional nibbles). We need to ensure the
+# replacement never changes the binary size.
+UIMAGE_FLASH_NUM            = "${@"[0-9a-fA-F]"*7}"
+UIMAGE_FLASH_DYN            = "${@"[0-9a-fA-F]\\\\?"*9}"
 
 # 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
+#  - `uimage_flash_addr=XXXXXXXX[;\0]` The direct mapped address of the image in memory
+#  - `uimage_flash_offs=XXXXXXXX[;\0]` The offset of the image in the SPI
+#  - `uimage_flash_size=XXXXXXXX[;\0]` The size of the image
 do_modify_bootloaders() {
     bin=${DEPLOY_DIR_IMAGE}/${UBOOT_BINARY}.${MERGED_SUFFIX}
     if [ ! -e $bin ]; then
@@ -268,24 +264,24 @@
     # 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 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})))
+    addr=$(printf '%07x' $kern_off)
+    off=$(printf '%07x' $kern_off)
+    size=$(printf '%07x' $(stat -c '%s' $(readlink -f ${DEPLOY_DIR_IMAGE}/${FLASH_KERNEL_IMAGE})))
+    set -x
     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
+    if grep -q "uimage_flash_offs=${UIMAGE_FLASH_DYN}${UIMAGE_FLASH_NUM}[;\\x0]" $bin; then
+        sed -i "s,\\(uimage_flash_offs=${UIMAGE_FLASH_DYN}\\)${UIMAGE_FLASH_NUM}\\([;\\x0\]\),\\1$off\\2,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
+    if grep -q "uimage_flash_addr=${UIMAGE_FLASH_DYN}${UIMAGE_FLASH_NUM}[;\\x0]" $bin; then
+        sed -i "s,\\(uimage_flash_addr=${UIMAGE_FLASH_DYN}\\)${UIMAGE_FLASH_NUM}\\([;\\x0]\\),\\1$addr\\2,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
+    sed -i "s,\\(uimage_flash_size=${UIMAGE_FLASH_DYN}\\)${UIMAGE_FLASH_NUM};,\\1$size;,g" $bin
 }
 
 MODIFY_BOOTLOADER_DEPENDS = ""