1b50fedbcSChanh Nguyen#!/bin/bash 2b50fedbcSChanh Nguyen 3b50fedbcSChanh Nguyen# This script is used to flash the UEFI/EDKII 4b50fedbcSChanh Nguyen 5b50fedbcSChanh Nguyen# Syntax: ampere_flash_bios.sh $image_file $device_sellect 6b50fedbcSChanh Nguyen# Where: 7b50fedbcSChanh Nguyen# $image_file : the image binary file 8b50fedbcSChanh Nguyen# $device_sellect : 1 - Host Main SPI Nor 9b50fedbcSChanh Nguyen# 2 - Host Second SPI Nor 10b50fedbcSChanh Nguyen 11b50fedbcSChanh Nguyen# Author : Chanh Nguyen (chnguyen@amperecomputing.com) 12b50fedbcSChanh Nguyen 13b50fedbcSChanh Nguyen# Note: 14b50fedbcSChanh Nguyen# BMC_GPIOW6_SPI0_PROGRAM_SEL (GPIO 182): 1 => BMC owns SPI bus for upgrading 15b50fedbcSChanh Nguyen# 0 => HOST owns SPI bus for upgrading 16b50fedbcSChanh Nguyen 17b50fedbcSChanh Nguyen# BMC_GPIOW7_SPI0_BACKUP_SEL (GPIO 183) : 1 => to switch SPI_CS0_L to primary SPI Nor device 18b50fedbcSChanh Nguyen# 0 => to switch SPI_CS0_L to second SPI Nor device 19b50fedbcSChanh Nguyen 20b50fedbcSChanh Nguyen# shellcheck disable=SC2046 21*e6a0291eSThang Q. Nguyen# shellcheck disable=SC2086 22b50fedbcSChanh Nguyen 23b50fedbcSChanh Nguyendo_flash () { 24*e6a0291eSThang Q. Nguyen # always unbind then bind the ASpeed SMC driver again to prevent 25*e6a0291eSThang Q. Nguyen # the changing of the device erasesize by nvparm 26b50fedbcSChanh Nguyen HOST_MTD=$(< /proc/mtd grep "pnor" | sed -n 's/^\(.*\):.*/\1/p') 27*e6a0291eSThang Q. Nguyen if [ -n "$HOST_MTD" ]; 28b50fedbcSChanh Nguyen then 29b50fedbcSChanh Nguyen echo 1e630000.spi > /sys/bus/platform/drivers/spi-aspeed-smc/unbind 30b50fedbcSChanh Nguyen sleep 2 31b50fedbcSChanh Nguyen fi 32b50fedbcSChanh Nguyen echo 1e630000.spi > /sys/bus/platform/drivers/spi-aspeed-smc/bind 33b50fedbcSChanh Nguyen 34*e6a0291eSThang Q. Nguyen # Check the PNOR partition available 35b50fedbcSChanh Nguyen HOST_MTD=$(< /proc/mtd grep "pnor" | sed -n 's/^\(.*\):.*/\1/p') 36b50fedbcSChanh Nguyen if [ -z "$HOST_MTD" ]; 37b50fedbcSChanh Nguyen then 38*e6a0291eSThang Q. Nguyen echo "Fail to probe the Host SPI-NOR device" 39b50fedbcSChanh Nguyen exit 1 40b50fedbcSChanh Nguyen fi 41b50fedbcSChanh Nguyen 42b50fedbcSChanh Nguyen echo "--- Flashing firmware image $IMAGE to @/dev/$HOST_MTD" 43b50fedbcSChanh Nguyen flashcp -v "$IMAGE" /dev/"$HOST_MTD" 44b50fedbcSChanh Nguyen} 45b50fedbcSChanh Nguyen 46b50fedbcSChanh Nguyen 47b50fedbcSChanh Nguyenif [ $# -eq 0 ]; then 487fc10f7eSHieu Huynh echo "Usage: $(basename "$0") <UEFI/EDKII image file> <DEV_SEL> [SPECIAL_BOOT]" 497fc10f7eSHieu Huynh echo "Where:" 507fc10f7eSHieu Huynh echo " DEV_SEL 1 is Primary SPI (by default), 2 is Second SPI" 51*e6a0291eSThang Q. Nguyen echo " SPECIAL_BOOT: Optional, input '1' to flash "Secure Provisioning" image and enter Special Boot mode. Default: 0" 52b50fedbcSChanh Nguyen exit 0 53b50fedbcSChanh Nguyenfi 54b50fedbcSChanh Nguyen 55b50fedbcSChanh NguyenIMAGE="$1" 56b50fedbcSChanh Nguyenif [ ! -f "$IMAGE" ]; then 57b50fedbcSChanh Nguyen echo "The image file $IMAGE does not exist" 58b50fedbcSChanh Nguyen exit 1 59b50fedbcSChanh Nguyenfi 60b50fedbcSChanh Nguyen 61b50fedbcSChanh Nguyenif [ -z "$2" ]; then 62b50fedbcSChanh Nguyen DEV_SEL="1" # by default, select primary device 63b50fedbcSChanh Nguyenelse 64b50fedbcSChanh Nguyen DEV_SEL="$2" 65b50fedbcSChanh Nguyenfi 66b50fedbcSChanh Nguyen 677fc10f7eSHieu HuynhSPECIAL_BOOT=0 687fc10f7eSHieu Huynhif [[ "$3" == "1" ]]; then 697fc10f7eSHieu Huynh SPECIAL_BOOT=1 707fc10f7eSHieu Huynhfi 717fc10f7eSHieu Huynh 727fc10f7eSHieu Huynhecho "SPECIAL_BOOT mode: $SPECIAL_BOOT" 73b50fedbcSChanh Nguyen# Turn off the Host if it is currently ON 74b50fedbcSChanh Nguyenchassisstate=$(obmcutil chassisstate | awk -F. '{print $NF}') 75b50fedbcSChanh Nguyenecho "--- Current Chassis State: $chassisstate" 76b50fedbcSChanh Nguyenif [ "$chassisstate" == 'On' ]; 77b50fedbcSChanh Nguyenthen 78b50fedbcSChanh Nguyen echo "--- Turning the Chassis off" 79b50fedbcSChanh Nguyen obmcutil chassisoff 80b50fedbcSChanh Nguyen sleep 10 81b50fedbcSChanh Nguyen # Check if HOST was OFF 82b50fedbcSChanh Nguyen chassisstate_off=$(obmcutil chassisstate | awk -F. '{print $NF}') 83b50fedbcSChanh Nguyen if [ "$chassisstate_off" == 'On' ]; 84b50fedbcSChanh Nguyen then 85b50fedbcSChanh Nguyen echo "--- Error : Failed turning the Chassis off" 86b50fedbcSChanh Nguyen exit 1 87b50fedbcSChanh Nguyen fi 88b50fedbcSChanh Nguyenfi 89b50fedbcSChanh Nguyen 90b50fedbcSChanh Nguyen# Switch the host SPI bus to BMC" 91b50fedbcSChanh Nguyenecho "--- Switch the host SPI bus to BMC." 92b50fedbcSChanh Nguyenif ! gpioset $(gpiofind spi0-program-sel)=1; then 93b50fedbcSChanh Nguyen echo "ERROR: Switch the host SPI bus to BMC. Please check gpio state" 94b50fedbcSChanh Nguyen exit 1 95b50fedbcSChanh Nguyenfi 96b50fedbcSChanh Nguyen 97b50fedbcSChanh Nguyen# Switch the host SPI bus (between primary and secondary) 98b50fedbcSChanh Nguyen# 183 is BMC_GPIOW7_SPI0_BACKUP_SEL 99b50fedbcSChanh Nguyenif [[ $DEV_SEL == 1 ]]; then 100b50fedbcSChanh Nguyen echo "Run update Primary Host SPI-NOR" 101b50fedbcSChanh Nguyen gpioset $(gpiofind spi0-backup-sel)=1 # Primary SPI 102b50fedbcSChanh Nguyenelif [[ $DEV_SEL == 2 ]]; then 103*e6a0291eSThang Q. Nguyen echo "Run update Secondary Host SPI-NOR" 104b50fedbcSChanh Nguyen gpioset $(gpiofind spi0-backup-sel)=0 # Second SPI 105b50fedbcSChanh Nguyenelse 106b50fedbcSChanh Nguyen echo "Please choose primary SPI (1) or second SPI (2)" 107b50fedbcSChanh Nguyen exit 0 108b50fedbcSChanh Nguyenfi 109b50fedbcSChanh Nguyen 110*e6a0291eSThang Q. Nguyen# Restrict to flash Secondary Host SPI-NOR in case of SPECIAL_BOOT 1117fc10f7eSHieu Huynhif [ $SPECIAL_BOOT == 1 ] && [ "$DEV_SEL" == 2 ]; then 112*e6a0291eSThang Q. Nguyen echo "Flashing 2nd Host SPI NOR image with SECProv image is not allowed" 1137fc10f7eSHieu Huynh exit 1147fc10f7eSHieu Huynhfi 1157fc10f7eSHieu Huynh 116b50fedbcSChanh Nguyen# Flash the firmware 117b50fedbcSChanh Nguyendo_flash 118b50fedbcSChanh Nguyen 1197fc10f7eSHieu Huynh# Assert SPECIAL_BOOT GPIO PIN 1207fc10f7eSHieu Huynhif [[ $SPECIAL_BOOT == 1 ]]; then 1217fc10f7eSHieu Huynh gpioset $(gpiofind host0-special-boot)=1 122*e6a0291eSThang Q. Nguyen # Set HOST BOOTCOUNT to 0 to prevent Host reboot 123*e6a0291eSThang Q. Nguyen busctl set-property xyz.openbmc_project.State.Host0 \ 124*e6a0291eSThang Q. Nguyen /xyz/openbmc_project/state/host0 \ 125*e6a0291eSThang Q. Nguyen xyz.openbmc_project.Control.Boot.RebootAttempts RetryAttempts u 0 1267fc10f7eSHieu Huynhfi 1277fc10f7eSHieu Huynh 128*e6a0291eSThang Q. Nguyen# Switch the SPI bus to the primary SPI device 129b50fedbcSChanh Nguyenecho "Switch to the Primary Host SPI-NOR" 130b50fedbcSChanh Nguyengpioset $(gpiofind spi0-backup-sel)=1 # Primary SPI 131b50fedbcSChanh Nguyen 132b50fedbcSChanh Nguyen# Switch the host SPI bus to HOST." 133b50fedbcSChanh Nguyenecho "--- Switch the host SPI bus to HOST." 134b50fedbcSChanh Nguyenif ! gpioset $(gpiofind spi0-program-sel)=0; then 135*e6a0291eSThang Q. Nguyen echo "ERROR: Switch the host SPI bus to HOST. Please check GPIO state" 136b50fedbcSChanh Nguyen exit 1 137b50fedbcSChanh Nguyenfi 138b50fedbcSChanh Nguyen 1397fc10f7eSHieu Huynhif [ "$chassisstate" == 'On' ] || [ $SPECIAL_BOOT == 1 ]; 140b50fedbcSChanh Nguyenthen 141b50fedbcSChanh Nguyen sleep 5 142b50fedbcSChanh Nguyen echo "Turn on the Host" 143b50fedbcSChanh Nguyen obmcutil poweron 144b50fedbcSChanh Nguyenfi 1457fc10f7eSHieu Huynh 146*e6a0291eSThang Q. Nguyen# Detection SECProv of failure or success 1477fc10f7eSHieu Huynhif [[ $SPECIAL_BOOT == 1 ]]; then 148*e6a0291eSThang Q. Nguyen # 30s time out in wait for FW_BOOT_OK 149*e6a0291eSThang Q. Nguyen state=0 150*e6a0291eSThang Q. Nguyen cnt=60 151*e6a0291eSThang Q. Nguyen while [ $cnt -gt 0 ]; 1527fc10f7eSHieu Huynh do 153*e6a0291eSThang Q. Nguyen # Monitor FW_BOOT_OK gpio 154*e6a0291eSThang Q. Nguyen state=$(gpioget $(gpiofind s0-fw-boot-ok)) 155*e6a0291eSThang Q. Nguyen if [[ "$state" == "1" ]]; then 156*e6a0291eSThang Q. Nguyen break 1577fc10f7eSHieu Huynh fi 158*e6a0291eSThang Q. Nguyen sleep 0.5 159*e6a0291eSThang Q. Nguyen cnt=$((cnt - 1)) 1607fc10f7eSHieu Huynh done 161*e6a0291eSThang Q. Nguyen 162*e6a0291eSThang Q. Nguyen echo "--- Turning the Chassis off" 163*e6a0291eSThang Q. Nguyen obmcutil chassisoff 164*e6a0291eSThang Q. Nguyen 165*e6a0291eSThang Q. Nguyen # Deassert SPECIAL_BOOT GPIO PIN 166*e6a0291eSThang Q. Nguyen gpioset $(gpiofind host0-special-boot)=0 167*e6a0291eSThang Q. Nguyen 168*e6a0291eSThang Q. Nguyen sleep 10 169*e6a0291eSThang Q. Nguyen # Recover HOST BOOTCOUNT to default 170*e6a0291eSThang Q. Nguyen busctl set-property xyz.openbmc_project.State.Host0 \ 171*e6a0291eSThang Q. Nguyen /xyz/openbmc_project/state/host0 \ 172*e6a0291eSThang Q. Nguyen xyz.openbmc_project.Control.Boot.RebootAttempts RetryAttempts u 3 1737fc10f7eSHieu Huynhfi 174