summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-core/fw-update/files/fwupd.sh
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-core/fw-update/files/fwupd.sh')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/fw-update/files/fwupd.sh172
1 files changed, 172 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-core/fw-update/files/fwupd.sh b/meta-openbmc-mods/meta-common/recipes-core/fw-update/files/fwupd.sh
new file mode 100644
index 000000000..889a73c06
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/fw-update/files/fwupd.sh
@@ -0,0 +1,172 @@
+#!/bin/sh
+
+SSH_ID=$HOME/.ssh/id_rsa.db
+[ -e $HOME/.fwupd.defaults ] && source $HOME/.fwupd.defaults
+
+usage() {
+ echo "usage: $(basename $0) uri"
+ echo " uri is something like: file:///path/to/fw"
+ echo " tftp://tftp.server.ip.addr/path/to/fw"
+ echo " scp://[user@]scp.server.ip.addr:/path/to/fw"
+ echo " http[s]://web.server.ip.addr/path/to/fw"
+ echo " ftp://[user@]ftp.server.ip.addr/path/to/fw"
+ exit 1
+}
+
+if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then usage; fi
+if [ $# -eq 0 ]; then
+ # set DEFURI in $HOME/.fwupd.defaults
+ URI="$DEFURI"
+else
+ URI="$1"
+fi
+
+PROTO=$(echo "$URI" | sed 's,\([a-z]*\)://.*$,\1,')
+REMOTE=$(echo "$URI" | sed 's,.*://\(.*\)$,\1,')
+REMOTE_HOST=$(echo "$REMOTE" | sed 's,\([^/]*\)/.*$,\1,')
+if [ "$PROTO" = 'scp' ]; then
+ REMOTE_PATH=$(echo "$REMOTE" | cut -d':' -f2)
+else
+ REMOTE_PATH=$(echo "$REMOTE" | sed 's,[^/]*/\(.*\)$,\1,')
+fi
+LOCAL_PATH="/tmp/$(basename $REMOTE_PATH)"
+echo "PROTO=$PROTO"
+echo "REMOTE=$REMOTE"
+echo "REMOTE_HOST=$REMOTE_HOST"
+echo "REMOTE_PATH=$REMOTE_PATH"
+if [ ! -e $LOCAL_PATH ] || [ $(stat -c %s $LOCAL_PATH) -eq 0 ]; then
+ echo "Download '$REMOTE_PATH' from $PROTO $REMOTE_HOST $REMOTE_PATH"
+ case "$PROTO" in
+ scp)
+ mkdir -p $HOME/.ssh
+ if [ -e "$SSH_ID" ]; then
+ ARG_ID="-i $SSH_ID"
+ fi
+ scp $ARG_ID $REMOTE_HOST$REMOTE_PATH $LOCAL_PATH
+ if [ $? -ne 0 ]; then
+ echo "scp $REMOTE $LOCAL_PATH failed!"
+ exit 255
+ fi
+ ;;
+ tftp)
+ cd /tmp
+ tftp -g -r "$REMOTE_PATH" "$REMOTE_HOST"
+ if [ $? -ne 0 ]; then
+ echo "tftp -g -r \"$REMOTE_PATH\" \"$REMOTE_HOST\" failed!"
+ exit 255
+ fi
+ ;;
+ http|https|ftp)
+ wget --no-check-certificate "$URI" -O "$LOCAL_PATH"
+ if [ $? -ne 0 ]; then
+ echo "wget $URI failed!"
+ exit 255
+ fi
+ ;;
+ file)
+ cp "$REMOTE_PATH" "$LOCAL_PATH"
+ ;;
+ *)
+ echo "Invalid URI $URI"
+ exit 1;
+ ;;
+ esac
+fi
+
+# PFR image update section
+# this file being created at build time for PFR images
+if [ -e /usr/share/pfr ]
+then
+# read the image type from the uploaded image
+# Byte at location 0x8 gives image type
+img_type=$(hexdump -s 8 -n 1 $LOCAL_PATH | cut -b12,1 | sed '2d;')
+echo "image-type=$img_type"
+
+# BMC image - max size 32MB
+if [ "$img_type" = '04' ]; then
+ echo "BMC firmware image"
+ # 32MB - 33554432
+ img_size=33554432
+ upd_intent_val=0x08
+ # page is at 4KB boundary
+ img_page_offset=0
+ erase_offset=0
+ blk_cnt=0x200
+# CPLD image- max size 4MB
+elif [ "$img_type" = '00' ]; then
+ echo "CPLD firmware image"
+ # 4MB - 4194304
+ img_size=4194304
+ upd_intent_val=0x04
+ # dd command accepts the offset in decimal
+ # below is the page offset in 4KB boundary
+ img_page_offset=12288
+ erase_offset=0x3000000
+ blk_cnt=0x40
+# BIOS image- max size 16MB
+elif [ "$img_type" = '02' ]; then
+ echo "BIOS firmware image"
+ # 16MB- 16777216
+ img_size=16777216
+ upd_intent_val=0x01
+ # dd command accepts the offset in decimal
+ # below is the page offset in 4KB boundary
+ img_page_offset=8192
+ erase_offset=0x2000000
+ blk_cnt=0x100
+else
+ echo "${img_type}:Unknown image type, exiting the firmware update script"
+ exit 1
+fi
+
+# do a quick sanity check on the image
+if [ $(stat -c "%s" "$LOCAL_PATH") -gt $img_size ]; then
+ echo "Update file "$LOCAL_PATH" is bigger than the supported image size"
+ exit 1
+fi
+
+TGT="/dev/mtd/image-stg"
+echo "Updating $(basename $TGT)"
+flash_erase $TGT $erase_offset $blk_cnt
+echo "Writing $(stat -c "%s" "$LOCAL_PATH") bytes"
+# cat "$LOCAL_PATH" > "$TGT"
+dd bs=4k seek=$img_page_offset if=$LOCAL_PATH of=$TGT
+sync
+echo "Written $(stat -c "%s" "$LOCAL_PATH") bytes"
+# remove the updated image from /tmp
+rm -f $LOCAL_PATH
+echo "Setting update intent in PFR CPLD"
+sleep 5 # delay for sync and to get the above echo messages
+# write to PFRCPLD about BMC update intent.
+i2cset -y 4 0x70 0x13 $upd_intent_val
+
+else # Non-PFR image update section
+# do a quick sanity check on the image
+if [ $(stat -c "%s" "$LOCAL_PATH") -lt 10000000 ]; then
+ echo "Update file "$LOCAL_PATH" seems to be too small"
+ exit 1
+fi
+dtc -I dtb -O dtb "$LOCAL_PATH" > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+ echo "Update file $LOCAL_PATH doesn't seem to be in the proper format"
+ exit 1
+fi
+
+# guess based on fw_env which partition we booted from
+BOOTADDR=$(fw_printenv bootcmd | awk '{print $2}')
+
+TGT="/dev/mtd/image-a"
+case "$BOOTADDR" in
+ 20080000) TGT="/dev/mtd/image-b"; BOOTADDR="22480000" ;;
+ 22480000) TGT="/dev/mtd/image-a"; BOOTADDR="20080000" ;;
+ *) TGT="/dev/mtd/image-a"; BOOTADDR="20080000" ;;
+esac
+echo "Updating $(basename $TGT) (use bootm $BOOTADDR)"
+flash_erase $TGT 0 0
+echo "Writing $(stat -c "%s" "$LOCAL_PATH") bytes"
+cat "$LOCAL_PATH" > "$TGT"
+fw_setenv "bootcmd" "bootm ${BOOTADDR}"
+
+# reboot
+reboot
+fi