meta-ampere: support Altra Boot Progress handling
Handle Altra Boot Progress reported from SCP regiter map by the use of
smpro-misc driver.
Tested: check boot progress is updated in Redfish for:
1. Reboot Host.
2. IPMI chassis power reset
3. IPMI chassis power cycle
4. IPMI chassis power off, then on
5. WebUI Orderly – OS shuts down, then server reboots
6. WebUI Immediate – Server reboots without OS shutting down
Signed-off-by: Thang Q. Nguyen <thang@os.amperecomputing.com>
Change-Id: I9483328ccf5731904d0e6e71074561f7dd743bed
diff --git a/meta-ampere/meta-common/recipes-ampere/host/ac01-boot-progress/ampere-boot-progress.service b/meta-ampere/meta-common/recipes-ampere/host/ac01-boot-progress/ampere-boot-progress.service
new file mode 100644
index 0000000..267d901
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ampere/host/ac01-boot-progress/ampere-boot-progress.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Ampere Altra Boot Progress Handling
+After=ampere-host-already-on@0.target
+BindTo=obmc-host-already-on@0.target
+
+[Service]
+Restart=simple
+ExecStart=/usr/sbin/ampere_boot_progress.sh
+SyslogIdentifier=ampere-boot-progress
+RemainAfterExit=no
+
+[Install]
+WantedBy=obmc-host-already-on@0.target
diff --git a/meta-ampere/meta-common/recipes-ampere/host/ac01-boot-progress/ampere_boot_progress.sh b/meta-ampere/meta-common/recipes-ampere/host/ac01-boot-progress/ampere_boot_progress.sh
new file mode 100755
index 0000000..87ad34f
--- /dev/null
+++ b/meta-ampere/meta-common/recipes-ampere/host/ac01-boot-progress/ampere_boot_progress.sh
@@ -0,0 +1,201 @@
+#!/bin/bash
+# Initialize variables
+boot_stage=00
+boot_status=00
+uefi_code=00000000
+
+function set_postcode()
+{
+ # shellcheck disable=SC2086
+ busctl set-property xyz.openbmc_project.State.Boot.Raw \
+ /xyz/openbmc_project/state/boot/raw0 \
+ xyz.openbmc_project.State.Boot.Raw Value \(tay\) "$1" 0
+}
+
+function update_boot_progress_last_state_time()
+{
+ # Get BMC current time
+ bp_last_state_time=$(busctl get-property xyz.openbmc_project.Time.Manager \
+ /xyz/openbmc_project/time/bmc \
+ xyz.openbmc_project.Time.EpochTime \
+ Elapsed | cut -d' ' -f2)
+
+ # Update the Boot Progress LastStateTime
+ busctl set-property xyz.openbmc_project.State.Host \
+ /xyz/openbmc_project/state/host0 \
+ xyz.openbmc_project.State.Boot.Progress \
+ BootProgressLastUpdate t \
+ "$bp_last_state_time"
+}
+
+function update_boot_progress()
+{
+ bootprog=$1
+
+ busctl set-property xyz.openbmc_project.State.Host \
+ /xyz/openbmc_project/state/host0 \
+ xyz.openbmc_project.State.Boot.Progress \
+ BootProgress s \
+ "xyz.openbmc_project.State.Boot.Progress.ProgressStages.$bootprog"
+
+ # Update Boot Progress LastStateTime
+ update_boot_progress_last_state_time
+}
+
+function get_boot_stage_string()
+{
+ bootstage=$1
+ ueficode=$2
+
+ case $bootstage in
+
+ 00)
+ boot_stage_str="SMpro"
+ ;;
+
+ 01)
+ boot_stage_str="PMpro"
+ ;;
+
+ 02)
+ boot_stage_str="ATF BL1 (Code=${ueficode})"
+ ;;
+
+ 03)
+ boot_stage_str="DDR initialization (Code=${ueficode})"
+ ;;
+
+ 04)
+ boot_stage_str="DDR training progress (Code=${ueficode})"
+ ;;
+
+ 05)
+ boot_stage_str="ATF BL2 (Code=${ueficode})"
+ ;;
+
+ 06)
+ boot_stage_str="ATF BL31 (Code=${ueficode})"
+ ;;
+
+ 07)
+ boot_stage_str="ATF BL32 (Code=${ueficode})"
+ ;;
+
+ 08)
+ boot_stage_str="UEFI booting (UEFI Code=${ueficode})"
+ ;;
+ 09)
+ boot_stage_str="OS booting"
+ ;;
+
+ esac
+
+ echo "$boot_stage_str"
+}
+
+function set_boot_progress()
+{
+ boot_stage=$1
+ uefi_code=$2
+
+ case $boot_stage in
+
+ 02)
+ update_boot_progress "PrimaryProcInit"
+ ;;
+
+ 03)
+ update_boot_progress "MemoryInit"
+ ;;
+
+ 08)
+ if [[ "$uefi_code" =~ 0201* ]]; then
+ update_boot_progress "PCIInit"
+ fi
+ ;;
+ 09)
+ update_boot_progress "OSStart"
+ ;;
+
+ esac
+}
+
+function log_redfish_biosboot_ok_event()
+{
+ logger-systemd --journald << EOF
+MESSAGE=
+PRIORITY=2
+SEVERITY=
+REDFISH_MESSAGE_ID=OpenBMC.0.1.BIOSBoot.OK
+REDFISH_MESSAGE_ARGS="UEFI firmware booting done"
+EOF
+}
+
+function log_redfish_bios_panic_event()
+{
+ boot_state_str=$(get_boot_stage_string "$1" "$2")
+
+ logger-systemd --journald << EOF
+MESSAGE=
+PRIORITY=2
+SEVERITY=
+REDFISH_MESSAGE_ID=OpenBMC.0.1.BIOSFirmwarePanicReason.Warning
+REDFISH_MESSAGE_ARGS=${boot_state_str}
+EOF
+}
+
+cnt=0
+# If any reason makes SCP fail to access in 6s, break the service.
+while [ $cnt -lt 30 ];
+do
+ # Sleep 200ms
+ usleep 200000
+ if ! read -r bg <<< "$(cat /sys/bus/platform/devices/smpro-misc.2.auto/boot_progress)";
+ then
+ cnt=$((cnt + 1))
+ continue
+ fi
+ cnt=0
+
+ # Check if any update from previous check
+ if [ "$last_bg" == "$bg" ]; then
+ continue
+ fi
+ last_bg=$bg
+
+ # Check if the Host is already ON or not. If Host is already boot, update boot progress and break.
+ if [ "${boot_stage}" == "00" ] && [ "${bg[0]}" == "09" ];
+ then
+ update_boot_progress "OSRunning"
+ break
+ fi
+
+ # Update current boot progress
+ boot_stage=${bg:2:2}
+ boot_status=${bg:0:2}
+ uefi_code=${bg:4}
+ echo "Boot Progress = ${boot_stage} ${boot_status} ${uefi_code}"
+
+ # Log Boot Progress to dbus
+ if [ "${boot_status}" == "03" ]; then
+ # Log Redfish Event if failure.
+ log_redfish_bios_panic_event "$boot_stage" "$uefi_code"
+ elif [ "${boot_status}" == "01" ]; then
+ # Check and set boot progress to dbus
+ set_boot_progress "$boot_stage" "$uefi_code"
+ fi
+
+ # Log POST Code to dbus.
+ set_postcode "0x$boot_stage$boot_status$uefi_code"
+
+ # Stop the service when booting to OS
+ if [ "${boot_stage}" == "08" ] && [ "${boot_status}" == "02" ]; then
+ update_boot_progress "SystemInitComplete"
+ log_redfish_biosboot_ok_event
+ elif [ "${boot_stage}" == "09" ] && [ "${boot_status}" == "02" ];
+ then
+ update_boot_progress "OSRunning"
+ break
+ fi
+done
+