1#!/bin/bash 2 3set -e 4 5# Check if PCH is on standby to proceed with the 6# host firmware update 7# 8# Find the GPIO pin associated with "pch-ready" 9# and read the value 10PCH_READY_GPIO_PIN=$(gpiofind "pch-ready") 11 12if [ -z "${PCH_READY_GPIO_PIN}" ]; then 13 echo "gpio 'pch-ready' not found in device tree. Exiting." 14 exit 0 15fi 16 17read -r PCH_READY_GPIO_CHIP PCH_READY_GPIO_LINE <<< "$PCH_READY_GPIO_PIN" 18GPIO_VALUE=$(gpioget "$PCH_READY_GPIO_CHIP" "$PCH_READY_GPIO_LINE") 19 20if [ "${GPIO_VALUE}" != "0" ]; then 21 echo "PCH is not on standby. Exiting host firmware version read." 22 exit 0 23fi 24 25IMAGE_FILE=$(find "$1" -name "*.rom") 26 27IPMB_OBJ="xyz.openbmc_project.Ipmi.Channel.Ipmb" 28IPMB_PATH="/xyz/openbmc_project/Ipmi/Channel/Ipmb" 29IPMB_INTF="org.openbmc.Ipmb" 30 31# me address, 0x2e oen, 0x00 - lun, 0xdf - force recovery 32ME_CMD_RECOVER=(1 0x2e 0 0xdf 4 0x57 0x01 0x00 0x01) 33# me address, 0x6 App Fn, 0x00 - lun, 0x2 - cold reset 34ME_CMD_RESET=(1 6 0 0x2 0) 35# me address, 0x6 App Fn, 0x00 - lun, 0x1 - get device id 36ME_GET_DEVICE_ID=(1 6 0 0x1 0) 37 38echo "Bios firmware upgrade started at $(date)" 39 40me_wait_poweron() { 41 echo "Wait for ME firmware to start" 42 for _ in {1..10}; do 43 busctl call --timeout=1 "$IPMB_OBJ" "$IPMB_PATH" "$IPMB_INTF" sendRequest yyyyay "${ME_GET_DEVICE_ID[@]}" 2>/dev/null 44 exit_code=$? 45 46 if [ "$exit_code" -eq 0 ]; then 47 break 48 fi 49 50 sleep 1 51 done 52 53 if [ "$exit_code" -ne 0 ]; then 54 echo "Failed to communicate with SPS firmware after 10 attempts." 55 exit 1 56 fi 57} 58 59me_force_recovery_mode() { 60 # Set ME to recovery mode 61 echo "Set ME to recovery mode" 62 busctl call "$IPMB_OBJ" "$IPMB_PATH" "$IPMB_INTF" sendRequest yyyyay "${ME_CMD_RECOVER[@]}" 63} 64 65me_reset() { 66 #Reset ME to boot from new bios 67 echo "Reset ME to boot from new firmware" 68 busctl call "$IPMB_OBJ" "$IPMB_PATH" "$IPMB_INTF" sendRequest yyyyay "${ME_CMD_RESET[@]}" 69} 70 71configure_flash_env() { 72 # 1. Assert PCH RESET 73 # 2. Enable/Disable FM_FLASH_SEC_OVRD 74 # 3. De-assert PCH RESET 75 local action="$1" 76 if [ "$action" == "enable" ]; then 77 echo "Asserting PCH RESET and enabling flash write override" 78 gpioset "${PCH_RESET_GPIO_CHIP}" "${PCH_RESET_GPIO_LINE}=0" 79 gpioset "${FLASH_OVERRIDE_GPIO_CHIP}" "${FLASH_OVERRIDE_GPIO_LINE}=1" 80 gpioset "${PCH_RESET_GPIO_CHIP}" "${PCH_RESET_GPIO_LINE}=1" 81 sleep 2 82 elif [ "$action" == "disable" ]; then 83 echo "Disabling flash write override and resetting PCH RESET" 84 gpioset "${PCH_RESET_GPIO_CHIP}" "${PCH_RESET_GPIO_LINE}=0" 85 gpioset "${FLASH_OVERRIDE_GPIO_CHIP}" "${FLASH_OVERRIDE_GPIO_LINE}=0" 86 gpioset "${PCH_RESET_GPIO_CHIP}" "${PCH_RESET_GPIO_LINE}=1" 87 else 88 echo "Invalid action specified for configure_flash_env. Use 'enable' or 'disable'." 89 exit 1 90 fi 91} 92 93cleanup_env() { 94 # Disable flash protection and clean up 95 configure_flash_env "disable" 96} 97 98reset_and_cleanup_env() { 99 echo "Reset ME and disable flash-write-override GPIO" 100 me_reset 101 sleep 5 102 cleanup_env 103} 104 105 106PCH_RESET_GPIO_PIN=$(gpiofind "pch-reset") 107if [ -z "${PCH_RESET_GPIO_PIN}" ]; then 108 echo "gpio 'pch-ready' not found in device tree. Exiting." 109 exit 0 110fi 111read -r PCH_RESET_GPIO_CHIP PCH_RESET_GPIO_LINE <<< "$PCH_RESET_GPIO_PIN" 112 113FLASH_OVERRIDE_GPIO_PIN="$(gpiofind flash-write-override)" 114if [ -z "${FLASH_OVERRIDE_GPIO_PIN}" ]; then 115 echo "gpio 'flash-write-override' not found in device tree. Exiting." 116 exit 0 117fi 118read -r FLASH_OVERRIDE_GPIO_CHIP FLASH_OVERRIDE_GPIO_LINE <<< "$FLASH_OVERRIDE_GPIO_PIN" 119 120configure_flash_env "enable" 121sleep 2 122 123me_wait_poweron 124 125me_force_recovery_mode 126 127# Fetch the MTD device number for the specified espi flash device 128DEVICE_NAME="espi-flash-mafs" 129MTD_DEVICE_NUMBER=$(grep "$DEVICE_NAME" /proc/mtd | awk -F: '{print $1}' | awk -F'mtd' '{print $2}') 130 131if [ -n "$MTD_DEVICE_NUMBER" ]; then 132 echo "Found MTD device number: $MTD_DEVICE_NUMBER" 133else 134 echo "Error: MTD device with name '$DEVICE_NAME' not found!" 135 reset_and_cleanup_env 136 exit 1 137fi 138 139#Flashcp image to device. 140if [ -e "$IMAGE_FILE" ]; 141then 142 echo "Bios image is $IMAGE_FILE" 143 flashrom -p linux_mtd:dev="${MTD_DEVICE_NUMBER}" -w "$IMAGE_FILE" 144else 145 echo "Bios image $IMAGE_FILE doesn't exist" 146fi 147 148reset_and_cleanup_env 149