1#!/bin/bash
2# Initialize variables
3boot_stage=00
4boot_status=00
5uefi_code=00000000
6
7function set_postcode()
8{
9	# shellcheck disable=SC2086
10	busctl set-property xyz.openbmc_project.State.Boot.Raw \
11		/xyz/openbmc_project/state/boot/raw0 \
12		xyz.openbmc_project.State.Boot.Raw Value \(tay\) "$1" 0
13}
14
15function update_boot_progress_last_state_time()
16{
17	# Get BMC current time
18	bp_last_state_time=$(busctl get-property xyz.openbmc_project.Time.Manager \
19		/xyz/openbmc_project/time/bmc \
20		xyz.openbmc_project.Time.EpochTime \
21		Elapsed | cut -d' ' -f2)
22
23	# Update the Boot Progress LastStateTime
24	busctl set-property xyz.openbmc_project.State.Host \
25		/xyz/openbmc_project/state/host0 \
26		xyz.openbmc_project.State.Boot.Progress \
27		BootProgressLastUpdate t \
28		"$bp_last_state_time"
29}
30
31function update_boot_progress()
32{
33	bootprog=$1
34
35	busctl set-property xyz.openbmc_project.State.Host \
36		/xyz/openbmc_project/state/host0 \
37		xyz.openbmc_project.State.Boot.Progress \
38		BootProgress s \
39		"xyz.openbmc_project.State.Boot.Progress.ProgressStages.$bootprog"
40
41	# Update Boot Progress LastStateTime
42	update_boot_progress_last_state_time
43}
44
45function get_boot_stage_string()
46{
47	bootstage=$1
48	ueficode=$2
49
50	case $bootstage in
51
52		00)
53			boot_stage_str="SMpro"
54			;;
55
56		01)
57			boot_stage_str="PMpro"
58			;;
59
60		02)
61			boot_stage_str="ATF BL1 (Code=${ueficode})"
62			;;
63
64		03)
65			boot_stage_str="DDR initialization (Code=${ueficode})"
66			;;
67
68		04)
69			boot_stage_str="DDR training progress (Code=${ueficode})"
70			;;
71
72		05)
73			boot_stage_str="ATF BL2 (Code=${ueficode})"
74			;;
75
76		06)
77			boot_stage_str="ATF BL31 (Code=${ueficode})"
78			;;
79
80		07)
81			boot_stage_str="ATF BL32 (Code=${ueficode})"
82			;;
83
84		08)
85			boot_stage_str="UEFI booting (UEFI Code=${ueficode})"
86			;;
87		09)
88			boot_stage_str="OS booting"
89			;;
90
91	esac
92
93	echo "$boot_stage_str"
94}
95
96function set_boot_progress()
97{
98	boot_stage=$1
99	uefi_code=$2
100
101	case $boot_stage in
102
103		02)
104			update_boot_progress "PrimaryProcInit"
105			;;
106
107		03)
108			update_boot_progress "MemoryInit"
109			;;
110
111		08)
112			if [[ "$uefi_code" =~ 0201* ]]; then
113				update_boot_progress "PCIInit"
114			fi
115			;;
116		09)
117			update_boot_progress "OSStart"
118			;;
119
120	esac
121}
122
123function log_redfish_biosboot_ok_event()
124{
125	logger --journald << EOF
126MESSAGE=
127PRIORITY=2
128SEVERITY=
129REDFISH_MESSAGE_ID=OpenBMC.0.1.BIOSBoot.OK
130REDFISH_MESSAGE_ARGS="UEFI firmware booting done"
131EOF
132}
133
134function log_redfish_bios_panic_event()
135{
136	boot_state_str=$(get_boot_stage_string "$1" "$2")
137
138	logger --journald << EOF
139MESSAGE=
140PRIORITY=2
141SEVERITY=
142REDFISH_MESSAGE_ID=OpenBMC.0.1.BIOSFirmwarePanicReason.Warning
143REDFISH_MESSAGE_ARGS=${boot_state_str}
144EOF
145}
146
147cnt=0
148# If any reason makes SCP fail to access in 6s, break the service.
149while [ $cnt -lt 30 ];
150do
151	# Sleep 200ms
152	sleep 1s
153	if ! read -r bg <<< "$(cat /sys/bus/platform/devices/smpro-misc.2.auto/boot_progress)";
154	then
155		cnt=$((cnt + 1))
156		continue
157	fi
158	cnt=0
159
160	# Check if any update from previous check
161	if [ "$last_bg" == "$bg" ]; then
162		continue
163	fi
164	last_bg=$bg
165
166	# Check if the Host is already ON or not. If Host is already boot, update boot progress and break.
167	if [ "${boot_stage}" == "00" ] && [ "${bg[0]}" == "09" ];
168	then
169		update_boot_progress "OSRunning"
170		break
171	fi
172
173	# Update current boot progress
174	boot_stage=${bg:2:2}
175	boot_status=${bg:0:2}
176	uefi_code=${bg:4}
177	echo "Boot Progress = ${boot_stage} ${boot_status} ${uefi_code}"
178
179	# Log Boot Progress to dbus
180	if [ "${boot_status}" == "03" ]; then
181		# Log Redfish Event if failure.
182		log_redfish_bios_panic_event "$boot_stage" "$uefi_code"
183		# Dimm training failed, check errors
184		if [ "${boot_stage}" == "04" ]; then
185			/usr/sbin/dimm_train_fail_log.sh 0
186			/usr/sbin/dimm_train_fail_log.sh 1
187		fi
188	elif [ "${boot_status}" == "01" ]; then
189		# Check and set boot progress to dbus
190		set_boot_progress "$boot_stage" "$uefi_code"
191	fi
192
193	# Log POST Code to dbus.
194	set_postcode "0x$boot_stage$boot_status$uefi_code"
195
196	# Stop the service when booting to OS
197	if [ "${boot_stage}" == "08" ] && [ "${boot_status}" == "02" ]; then
198		update_boot_progress "SystemInitComplete"
199		log_redfish_biosboot_ok_event
200	elif [ "${boot_stage}" == "09" ] && [ "${boot_status}" == "02" ];
201	then
202		update_boot_progress "OSRunning"
203		break
204	fi
205done
206
207