1#!/bin/bash
2# shellcheck disable=SC2046
3
4do_fru_upgrade() {
5	FRU_DEVICE="/sys/bus/i2c/devices/3-0050/eeprom"
6
7	if ! command -v ampere_fru_upgrade;
8	then
9		echo "Bypass fru update as no ampere_fru_upgrade available"
10		exit
11	fi
12	ampere_fru_upgrade -d $FRU_DEVICE -f "$IMAGE"
13
14	systemctl restart xyz.openbmc_project.FruDevice.service
15}
16
17do_smpmpro_upgrade() {
18	I2C_BUS_DEV="1"
19	EEPROM_ADDR="0x50"
20
21	if ! command -v ampere_eeprom_prog;
22	then
23		echo "Bypass SCP firmware update as no ampere_eeprom_prog available"
24		exit
25	fi
26	echo "SECPRO mode: $SECPRO"
27	# Turn off the Host if it is currently ON
28	chassisstate=$(obmcutil chassisstate | awk -F. '{print $NF}')
29	echo "Current Chassis State: $chassisstate"
30	if [ "$chassisstate" == 'On' ];
31	then
32		echo "Turning the Chassis off"
33		obmcutil chassisoff
34
35		# Wait 60s until Chassis is off
36		cnt=30
37		while [ "$cnt" -gt 0 ];
38		do
39			cnt=$((cnt - 1))
40			sleep 2
41			# Check if HOST was OFF
42			chassisstate_off=$(obmcutil chassisstate | awk -F. '{print $NF}')
43			if [ "$chassisstate_off" != 'On' ];
44			then
45				break
46			fi
47
48			if [ "$cnt" == "0" ];
49			then
50				echo "--- Error : Failed turning the Chassis off"
51				exit 1
52			fi
53		done
54	fi
55
56	if [[ $SECPRO == 1 ]]; then
57		gpioset $(gpiofind host0-special-boot)=1
58		gpioset $(gpiofind s1-special-boot)=1
59	fi
60
61	# Switch EEPROM control to BMC AST2500 I2C
62	gpioset $(gpiofind spi0-program-sel)=0
63
64	# 08 is BMC_GPIOB0_I2C_BACKUP_SEL
65	if [[ $DEV_SEL == 1 ]]; then
66		echo "Run update primary Boot EEPROM"
67		gpioset $(gpiofind i2c-backup-sel)=1       # Main EEPROM
68	elif [[ $DEV_SEL == 2 ]]; then
69		echo "Run update secondary Boot EEPROM"
70		gpioset $(gpiofind i2c-backup-sel)=0       # Second EEPROM
71	else
72		echo "Please choose Main (1) or Second EEPROM (2)"
73		exit 0
74	fi
75
76	# Write Firmware to EEPROM and read back for validation
77	ampere_eeprom_prog -b $I2C_BUS_DEV -s $EEPROM_ADDR -p -f "$IMAGE"
78
79	# Switch EEPROM control to Host
80	# 08 is BMC_GPIOB0_I2C_BACKUP_SEL
81	gpioset $(gpiofind i2c-backup-sel)=1
82	gpioset $(gpiofind spi0-program-sel)=1
83
84	# Deassert SECPRO GPIO PINs
85	if [[ $SECPRO == 1 ]]; then
86		echo "De-asserting special GPIO PINs"
87		gpioset $(gpiofind host0-special-boot)=0
88		gpioset $(gpiofind s1-special-boot)=0
89	fi
90
91	if [ "$chassisstate" == 'On' ];
92	then
93		sleep 5
94		echo "Turn on the Host"
95		obmcutil poweron
96	fi
97
98}
99
100
101if [ $# -eq 0 ]; then
102	echo "Usage:"
103	echo "      $(basename "$0") <Type> <Image file> <DEV_SEL> [SECPRO]"
104	echo "Where:"
105	echo "    <Type>: eeprom or fru"
106	echo "            If Type is eeprom, then DEV_SEL must is 1 (MAIN EEPROM), 2 (Failover)"
107	echo "    SECPRO: Optional, input '1' to enter & flash secpro mode. Default: 0"
108	exit 0
109fi
110
111TYPE=$1
112IMAGE=$2
113if [ -z "$3" ]
114then
115	DEV_SEL="1"    # by default, select Main image
116else
117	DEV_SEL=$3
118fi
119
120SECPRO=0
121if [ -n "$4" ]; then
122	if [[ "$4" == "1" ]]; then
123		SECPRO=1
124	fi
125fi
126
127MANIFEST="$(echo "$IMAGE" | cut -d'/' -f-4)/MANIFEST"
128if [ -f "$MANIFEST" ]; then
129	echo "MANIFEST: $MANIFEST"
130	if grep -qF "SECPRO" "$MANIFEST"; then
131		SECPRO=1
132	fi
133fi
134
135# Restrict to flash failover in case of SECPRO
136if [ $SECPRO == 1 ] && [ "$DEV_SEL" == 2 ]; then
137	echo "Not allow to flash the failover with SECPRO image"
138	exit
139fi
140
141case $TYPE in
142	"smpmpro" | "eeprom")
143		do_smpmpro_upgrade
144		;;
145	"fru")
146		do_fru_upgrade
147		;;
148esac
149