Initial commit

This commit is contained in:
Your Name
2026-04-23 17:07:55 +08:00
commit b7e39e063b
16725 changed files with 1625565 additions and 0 deletions
@@ -0,0 +1,8 @@
[Unit]
Description=Ampere Altra Boot Progress Handling
After=obmc-host-already-on@0.target
BindTo=obmc-host-already-on@0.target
[Service]
ExecStart=/usr/sbin/ampere_boot_progress.sh
SyslogIdentifier=ampere-boot-progress
@@ -0,0 +1,206 @@
#!/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
sleep 1s
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"
# Dimm training failed, check errors
if [ "${boot_stage}" == "04" ]; then
/usr/sbin/dimm_train_fail_log.sh 0
/usr/sbin/dimm_train_fail_log.sh 1
fi
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
@@ -0,0 +1,190 @@
#!/bin/bash
smpro_path() {
if [ "$1" == 0 ]; then
echo "/sys/bus/i2c/drivers/smpro-core/2-004f"
else
echo "/sys/bus/i2c/drivers/smpro-core/2-004e"
fi
}
function log_ampere_oem_redfish_event()
{
msg=$1
priority=$2
severity=$3
msgID=$4
msgArgs1=$5
msgArgs2=$6
logger-systemd --journald << EOF
MESSAGE=${msg}
PRIORITY=${priority}
SEVERITY=${severity}
REDFISH_MESSAGE_ID=${msgID}
REDFISH_MESSAGE_ARGS=${msgArgs1},${msgArgs2}
EOF
}
parse_phy_syndrome_s1_type() {
s1=$1
slice=$((s1 & 0xf))
ubit=$(((s1 & 0x10) >> 4))
lbit=$(((s1 & 0x20) >> 5))
uMsg="Upper Nibble: No Error"
lMsg="Lower Nibble: No Error"
if [ $ubit == 1 ]; then
uMsg="Upper Nibble: No rising edge error"
fi
if [ $lbit == 1 ]; then
lMsg="Lower Nibble: No rising edge error"
fi
echo "Slice $slice: $uMsg, $lMsg"
}
parse_phy_syndrome() {
s0=$1
s1=$2
case $s0 in
1)
echo "PHY Training Setup failure"
;;
2)
s1Msg=$(parse_phy_syndrome_s1_type "$s1")
echo "PHY Write Leveling failure: $s1Msg"
;;
3)
echo "PHY Read Gate Leveling failure"
;;
4)
echo "PHY Read Leveling failure"
;;
5)
echo "PHY Software Training failure"
;;
*)
echo "N/A"
;;
esac
}
parse_dimm_syndrome() {
s0=$1
case $s0 in
1)
echo "DRAM VREFDQ Training failure"
;;
2)
echo "LRDIMM DB Training failure"
;;
3)
echo "LRDIMM DB Software Training failure"
;;
*)
echo "N/A"
;;
esac
}
log_err_to_redfish_err() {
channel="$(printf '%d' "0x$1" 2>/dev/null)"
data="$(printf '%d' "0x$2" 2>/dev/null)"
trErrType=$((data & 0x03))
rank=$(((data & 0x1C) >> 2))
syndrome0=$(((data & 0xE0) >> 5))
syndrome1=$(((data & 0xFF00) >> 8))
# PHY sysdrom errors
fType=""
redfisComp="DIMM"
redfisMsg=""
if [ $trErrType == 1 ]; then
fType="PHY training failure"
redfisMsg=$(parse_phy_syndrome $syndrome0 $syndrome1)
# DIMM traning errors
elif [ $trErrType == 2 ]; then
fType="DIMM training failure"
redfisMsg=$(parse_dimm_syndrome $syndrome0)
else
fType="Invalid DIMM Syndrome error type"
redfisMsg="NA"
fi
#smg=$("DDR training: MCU rank $rank: $fType: $redfisMsg")
log_ampere_oem_redfish_event \
"" 2 "" "OpenBMC.0.1.AmpereCritical.Critical" \
$redfisComp "Slot $channel MCU rank $rank: $fType: $redfisMsg"
}
log_err_to_sel_err() {
channel="$(printf '%d' "0x$1" 2>/dev/null)"
data="$(printf '%d' "0x$2" 2>/dev/null)"
byte0=$(((data & 0xff00) >> 8))
byte1=$((data & 0xff))
evtdata0=$((EVENT_DIR_ASSERTION | OEM_SENSOR_SPECIFIC))
evtdata1=$(((channel << 4) | BOOT_SYNDROME_DATA | (socket << 3)))
# phy sysdrom errors
# OEM data bytes
# oem id: 3 bytes [0x3a 0xcd 0x00]
# sensor num: 1 bytes
# sensor type: 1 bytes
# data bytes: 4 bytes
# sel type: 4 byte [0x00 0x00 0x00 0xC0]
busctl call xyz.openbmc_project.Logging.IPMI \
/xyz/openbmc_project/Logging/IPMI \
xyz.openbmc_project.Logging.IPMI IpmiSelAddOem \
sayy "" 12 \
0x3a 0xcd 0x00 \
"$SENSOR_TYPE_SYSTEM_FW_PROGRESS" "$SENSOR_BOOT_PROGRESS" \
"$evtdata0" "$evtdata1" "$byte0" "$byte1" \
0x00 0x00 0x00 0xC0
}
BOOT_SYNDROME_DATA=4
SENSOR_BOOT_PROGRESS=235
EVENT_DIR_ASSERTION=0x00
OEM_SENSOR_SPECIFIC=0x70
SENSOR_TYPE_SYSTEM_FW_PROGRESS=0x0F
socket=$1
base="$(smpro_path "$socket")"
# For the second socket, it is required to read out to
# clear all old boot progress before query the dimm
# training fail info.
# Normally, it would take up to 12 times to read them all
# Make the value to 16 to make sure it always works.
if [ "$socket" == "1" ]; then
path=("$base"/smpro-misc.*.auto/boot_progress)
filename="${path[0]}"
if [ ! -f "$filename" ];
then
echo "Error: $filename not found"
else
for ((i=0; i<16; i++))
do
cat "$filename" > /dev/null 2>&1
done
fi
fi
# Checking for DIMM slot 0-15
for ((i=0; i<16; i++))
do
path=("$base"/smpro-errmon.*.auto/event_dimm"${i}"_syndrome)
filename="${path[0]}"
if [ ! -f "$filename" ];
then
echo "Error: $filename not found"
continue
fi
line=$(cat "$filename")
if [ -n "$line" ];
then
log_err_to_redfish_err "$i" "$line"
log_err_to_sel_err "$i" "$line"
fi
done
exit 0;