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,31 @@
SUMMARY = "Ampere Computing LLC System Firmware Hang Handler"
DESCRIPTION = "A host control implementation suitable for Ampere Computing LLC's systems"
PR = "r1"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
inherit systemd
inherit obmc-phosphor-systemd
RDEPENDS:${PN} = "bash"
FILESEXTRAPATHS:append := "${THISDIR}/${PN}:"
SYSTEMD_PACKAGES = "${PN}"
SRC_URI = " \
file://ampere-sysfw-hang-handler.service \
file://ampere_sysfw_hang_handler.sh \
"
SYSTEMD_SERVICE:${PN} += "ampere-sysfw-hang-handler.service"
SYSFW_HANG_TGT = "ampere-sysfw-hang-handler.service"
SYSFW_HANG_INSTMPL = "ampere-sysfw-hang-handler.service"
AMPER_HOST_RUNNING = "obmc-host-already-on@{0}.target"
SYSFW_HANG_TARGET_FMT = "../${SYSFW_HANG_TGT}:${AMPER_HOST_RUNNING}.wants/${SYSFW_HANG_INSTMPL}"
SYSTEMD_LINK:${PN} += "${@compose_list_zip(d, 'SYSFW_HANG_TARGET_FMT', 'OBMC_HOST_INSTANCES')}"
do_install() {
install -d ${D}/usr/sbin
install -m 0755 ${WORKDIR}/ampere_sysfw_hang_handler.sh ${D}/${sbindir}/
}
@@ -0,0 +1,10 @@
[Unit]
Description=Ampere System Firmware Hang Handler
After=obmc-host-already-on@0.target
BindTo=obmc-host-already-on@0.target
ConditionPathExists=!/var/ampere/sysfw-hang-disable
[Service]
Type=simple
ExecStart=/usr/sbin/ampere_sysfw_hang_handler.sh
SyslogIdentifier=ampere_sysfw_hang
@@ -0,0 +1,42 @@
#!/bin/bash
# shellcheck source=meta-ampere/meta-mitchell/recipes-ampere/platform/ampere-platform-init/gpio-lib.sh
source /usr/sbin/gpio-lib.sh
# Do event trigger
function sel_trigger()
{
echo "Error: system firmware hang, trigger sel"
ampere_add_redfishevent.sh OpenBMC.0.1.SystemPowerOnFailed.Critical
}
# Do reset the system
function reset_system()
{
echo "Error: system firmware hang, reset the system"
ipmitool chassis power reset
}
s0_last_hb_state=0
cnt=-1
while true
do
# Monitor heart beat GPIO value, GPIOF4 for Socket 0
s0_hb_state=$(gpio_name_get s0-heartbeat)
if [ "$s0_last_hb_state" != "$s0_hb_state" ]; then
cnt=0
else
cnt=$((cnt + 1))
fi
if [ "$cnt" -ge 6 ]; then
echo "Error: system firmware hang"
sel_trigger
reset_system
exit 0
fi
s0_last_hb_state="$s0_hb_state"
sleep 0.5
done
exit 0
@@ -0,0 +1,42 @@
SUMMARY = "OpenBMC for Ampere - Applications"
PR = "r1"
inherit packagegroup
PROVIDES = "${PACKAGES}"
PACKAGES = " \
${PN}-chassis \
${PN}-flash \
${PN}-system \
"
PROVIDES += "virtual/obmc-chassis-mgmt"
PROVIDES += "virtual/obmc-flash-mgmt"
PROVIDES += "virtual/obmc-system-mgmt"
RPROVIDES:${PN}-chassis += "virtual-obmc-chassis-mgmt"
RPROVIDES:${PN}-flash += "virtual-obmc-flash-mgmt"
RPROVIDES:${PN}-system += "virtual-obmc-system-mgmt"
SUMMARY:${PN}-chassis = "Ampere Chassis"
RDEPENDS:${PN}-chassis = " \
obmc-phosphor-buttons-signals \
obmc-phosphor-buttons-handler \
phosphor-skeleton-control-power \
ampere-hostctrl \
phosphor-hostlogger \
phosphor-sel-logger \
phosphor-logging \
phosphor-post-code-manager \
phosphor-host-postd \
"
SUMMARY:${PN}-system = "Ampere System"
RDEPENDS:${PN}-system = " \
smbios-mdr \
"
SUMMARY:${PN}-flash = "Ampere Flash"
RDEPENDS:${PN}-flash = " \
phosphor-software-manager \
"
@@ -0,0 +1,14 @@
FILESEXTRAPATHS:append := "${THISDIR}/${PN}:"
RDEPENDS:${PN} = "bash"
SRC_URI += " \
file://ampere_fault_monitor.sh \
file://ampere_check_gpio_fault.sh \
"
do_install() {
install -d ${D}/${sbindir}
install -m 755 ${WORKDIR}/ampere_fault_monitor.sh ${D}/${sbindir}/
install -m 755 ${WORKDIR}/ampere_check_gpio_fault.sh ${D}/${sbindir}/
}
@@ -0,0 +1,351 @@
#!/bin/bash
# This script monitors S0/S1 GPIO fault and detects errors from CPUs
#
# So far, there is no specification describes the behavior of LED when an error (a pattern is detected) occurs.
# So when detecting a pattern, we simply set the gpio fault flag and turn on the SYS LED.
#
# The Parttern will in the format:
# <minor_byte> <quite_gap_1second> <major_byte> <stop_condition_low_for_3seconds>
#
# Ex: pattern minor_byte=0x03, major_byte=0x02, you will see the waveform like
# _1010100...(quite gap, low for 1 second)..0111111111000000000111111111110000000000...(stop condition, low for 3 seconds)..
#
# Usage: <app_name> <socket 0/1>
#
# shellcheck source=/dev/null
source /usr/sbin/gpio-lib.sh
# global variables
error_flag='/tmp/gpio_fault'
# the command "cat /sys/class/gpio/gpio"$gpio_Id"/value" itself, takes 10ms~35ms to complete, depends on CPU loading
polling_minor_byte_rate=0
polling_major_byte_rate=200000
polling_rate=$polling_minor_byte_rate
# the mount of low to ensure that already get out of minor_byte and is in quite gap
# this value depends on the polling_minor_byte_rate
max_low_in_minor_byte=9
# the mount of low to ensure that already get out of major_byte and is in stop condition
# this value depends on the polling_major_byte_rate
max_low_in_major_byte=9
max_low=$max_low_in_minor_byte
# state machines:
# detecting_minor_byte=0
# detecting_major_byte=1
curr_state=0
minor_byte=0
major_byte=0
gpio_status=0
socket=$1
socket1_present=151
socket1_status=1
S0_fault_gpio='s0-fault-alert'
S1_fault_gpio='s1-fault-alert'
map_event_name() {
case $major_byte in
2)
event_major="FAULT_LED_BOOT_ERROR"
case $minor_byte in
1)
event_minor="SOC_BOOTDEV_INIT_SEC_ERROR"
;;
2)
event_minor="SECJMP_FAIL_ERROR"
;;
3)
event_minor="UART_INIT_WARN"
;;
4)
event_minor="UART_TX_WARN"
;;
5)
event_minor="SOC_ROMPATCH_BAD_ERROR"
;;
6)
event_minor="SOC_ROMPATCH_RANGE_ERROR"
;;
7)
event_minor="SPI_INIT_ERROR"
;;
8)
event_minor="SPI_TX_ERROR"
;;
9)
event_minor="SPINOR_UNKNOW_DEVICE_WARN"
;;
10)
event_minor="EEPROM_BAD_NVP_HEADER_WARN"
;;
11)
event_minor="EEPROM_BAD_NVP_FIELD_WARN"
;;
12)
event_minor="EEPROM_BAD_CHECKSUM_ERROR_WARN"
;;
13)
event_minor="I2C_DMA_ERROR"
;;
14)
event_minor="I2C_TIMEOUT_ERROR"
;;
15)
event_minor="SOC_BOOTDEV_SPI_LOAD_ERROR"
;;
16)
event_minor="SOC_BOOTDEV_AUTHENTICATION_ERROR"
;;
17)
event_minor="PCP_POWERUP_FAILED"
;;
18)
event_minor="PCP_POWERDOWN_FAILED"
;;
19)
event_minor="CPUPLL_INIT_FAILED"
;;
20)
event_minor="MESHPLL_INIT_FAILED"
;;
*)
event_minor="NOT_SUPPORT"
esac
;;
3)
event_major="FAULT_LED_FW_LOAD_ERROR"
case $minor_byte in
9)
event_minor="LFS_ERROR"
;;
*)
event_minor="NOT_SUPPORT"
esac
;;
4)
event_major="FAULT_LED_SECURITY_ERROR"
case $minor_byte in
1)
event_minor="SEC_INVALID_KEY_CERT"
;;
2)
event_minor="SEC_INVALID_CONT_CERT"
;;
3)
event_minor="SEC_INVALID_ROOT_KEY"
;;
4)
event_minor="SEC_INVALID_SECPRO_KEY"
;;
5)
event_minor="SEC_INVALID_KEY_CERT_SIG"
;;
6)
event_minor="SEC_INVALID_CONT_CERT_SIG"
;;
7)
event_minor="SEC_INVALID_IMAGE_HASH"
;;
8)
event_minor="SEC_INVALID_PRI_VERSION"
;;
9)
event_minor="SEC_HUK_MISMATCH"
;;
10)
event_minor="SEC_FUSE_BLOW_CERT_WITHOUT_SPECIAL_BOOT_PIN"
;;
11)
event_minor="SEC_INVALID_CERT_SUBTYPE_STRUCT"
;;
12)
event_minor="SEC_TMMCFG_FAIL"
;;
13)
event_minor="SEC_INVALID_LCS_FROM_EFUSE"
;;
14)
event_minor="SEC_EFUSE_WRITE_FAILED"
;;
15)
event_minor="SEC_INVALID_CERT_VALUE"
;;
16)
event_minor="SEC_INVALID_CERT_VERSION"
;;
*)
event_minor="NOT_SUPPORT"
;;
esac
;;
5)
event_major="FAULT_LED_EXCEPTION_ERROR"
case $minor_byte in
1)
event_minor="KERNEL_EXCEPTION_UNKNOWN_REASON_ERROR"
;;
2)
event_minor="KERNEL_EXCEPTION_HARD_FAULT_ERROR"
;;
3)
event_minor="KERNEL_EXCEPTION_BUS_FAULT_ERROR"
;;
4)
event_minor="KERNEL_EXCEPTION_MEMMANAGE_FAULT_ERROR"
;;
5)
event_minor="KERNEL_EXCEPTION_USAGE_FAULT_ERROR"
;;
*)
event_minor="NOT_SUPPORT"
;;
esac
;;
*)
event_major="NOT_SUPPORT"
;;
esac
}
set_unset_gpio_fault_flag() {
if [ ! -f $error_flag ] && [ "$1" == 1 ] ; then
touch $error_flag
elif [ -f $error_flag ] && [ "$1" == 0 ]; then
rm $error_flag
fi
}
toggle_state() {
if [ "$curr_state" == 0 ]; then
curr_state=1
polling_rate=$polling_major_byte_rate
else
curr_state=0
polling_rate=$polling_minor_byte_rate
map_event_name
echo "detected major_byte=$event_major, minor_byte=$event_minor"
set_unset_gpio_fault_flag 1
fi
}
save_pulse_of_byte() {
if [ "$curr_state" == 0 ]; then
minor_byte=$1
#echo "minor_byte=$1"
else
major_byte=$1
#echo "major_byte=$1"
fi
}
# we do not care the pulse is 50ms or 500ms, what we care is that the number of high pulses
cnt_falling_edge_in_byte() {
local cnt_falling_edge=0
local cnt_low=0
local prev=0
local curr=0
while true
do
prev=$curr
curr=$gpio_status
# count the falling edges, if they occur, just reset cnt_low
if [ "$prev" == 1 ] && [ "$curr" == 0 ]; then
cnt_falling_edge=$(( cnt_falling_edge + 1 ))
cnt_low=0
continue
# check if we are in the quite gap or stop condition
elif [ "$prev" == 0 ] && [ "$curr" == 0 ]; then
cnt_low=$(( cnt_low + 1 ))
if [ "$cnt_low" == "$max_low" ]; then
save_pulse_of_byte "$cnt_falling_edge"
toggle_state
break
fi
fi
usleep $polling_rate
gpio_status=$(cat /sys/class/gpio/gpio"$gpio_Id"/value)
done
}
gpio_config_input() {
echo "$gpio_Id" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio"${gpio_Id}"/direction
}
gpio_number() {
local offset
local gpioPin
local str
str=$(gpiofind "$1")
if [ "$?" == '1' ]; then
echo -1
else
gpioid=$(echo "$str"|cut -c 9)
offset=$(echo "$str"|cut -d " " -f 2)
gpioPin=$(("$offset" + ${AST2600_GPIO_BASE[$gpioid]}))
echo "$gpioPin"
fi
}
init_sysfs_fault_gpio() {
gpio_Id=$(gpio_number "$fault_gpio")
if [ "$gpio_Id" == "-1" ]; then
echo "Invalid GPIO number"
exit 1
fi
if [ -d /sys/class/gpio/gpio"$gpio_Id" ]; then
return
fi
gpio_config_input "$gpio_Id"
}
# init
if [ "$socket" == "0" ]; then
fault_gpio="$S0_fault_gpio"
else
socket1_status=$(gpioget 0 "$socket1_present")
if [ "$socket1_status" == 1 ]; then
echo "socket 1 not present"
exit 0
fi
fault_gpio=$S1_fault_gpio
fi
init_sysfs_fault_gpio
# daemon start
while true
do
# detect when pattern starts
if [ "$gpio_status" == 1 ]; then
if [ "$curr_state" == 0 ]; then
# detecting minor byte, set up minor byte variables
max_low=$max_low_in_minor_byte
polling_rate=$polling_minor_byte_rate
else
# detecting major byte, set up major byte variables
max_low=$max_low_in_major_byte
polling_rate=$polling_major_byte_rate
fi
# now, there is something on gpio, check if that is a byte pattern
cnt_falling_edge_in_byte
fi
usleep $polling_rate
gpio_status=$(cat /sys/class/gpio/gpio"$gpio_Id"/value)
done
exit 1
@@ -0,0 +1,218 @@
#!/bin/bash
# This script monitors fan, over-temperature, PSU, CPU/SCP failure and update fault LED status
# shellcheck disable=SC2004
# shellcheck source=/dev/null
source /usr/sbin/gpio-lib.sh
# common variables
on=1
off=0
overtemp_fault_flag='/tmp/fault_overtemp'
# gpio fault
gpio_fault="false"
gpio_fault_flag="/tmp/gpio_fault"
# fan variables
fan_failed="false"
fan_failed_flag='/tmp/fan_failed'
# PSU variables
psu_failed="false"
psu_bus=2
psu0_addr=0x58
psu1_addr=0x59
status_word_cmd=0x79
# Following the PMBus Specification
# Bit[1]: CML faults
# Bit[2]: Over temperature faults
# Bit[3]: Under voltage faults
# Bit[4]: Over current faults
# Bit[5]: Over voltage fault
# Bit[10]: Fan faults
psu_fault_bitmask=0x43e
# led variables
fan_fault_led_status=$off
psu_fault_led_status=$off
led_bus=15
led_addr=0x22
led_port0_config=0x06
led_port0_output=0x02
# functions declaration
check_fan_failed() {
if [[ -f $fan_failed_flag ]]; then
fan_failed="true"
else
fan_failed="false"
fi
}
turn_on_off_fan_fault_led() {
# Control fan fault led via CPLD's I2C at slave address 0x22, I2C16.
# Get Port0 value
p0_val=$(i2cget -f -y $led_bus $led_addr $led_port0_config)
p0_val=$(("$p0_val" & ~1))
# Config CPLD's IOepx Port0[0] from input to output, clear IOepx Port0[0].
i2cset -f -y $led_bus $led_addr $led_port0_config $p0_val
# Get led value
led_st=$(i2cget -f -y $led_bus $led_addr $led_port0_output)
if [ "$1" == $on ]; then
led_st=$(("$led_st" | 1))
else
led_st=$(("$led_st" & ~1))
fi
# Turn on/off fan fault led
i2cset -f -y $led_bus $led_addr $led_port0_output $led_st
}
turn_on_off_psu_fault_led() {
# Control psu fault led via CPLD's I2C at slave address 0x22, I2C16.
# Get Port1 value
p1_val=$(i2cget -f -y $led_bus $led_addr $led_port0_config)
p1_val=$(("$p1_val" & ~2))
# Config CPLD's IOepx Port0[1] from input to output, clear IOepx Port0[1].
i2cset -f -y $led_bus $led_addr $led_port0_config $p1_val
# Get led value
led_st=$(i2cget -f -y $led_bus $led_addr $led_port0_output)
if [ "$1" == $on ]; then
led_st=$(("$led_st" | 2))
else
led_st=$(("$led_st" & ~2))
fi
# Turn on/off psu fault led
i2cset -f -y $led_bus $led_addr $led_port0_output $led_st
}
control_fan_fault_led() {
if [ "$fan_failed" == "true" ]; then
if [ "$fan_fault_led_status" == $off ]; then
turn_on_off_fan_fault_led $on
fan_fault_led_status=$on
fi
else
if [ "$fan_fault_led_status" == $on ]; then
turn_on_off_fan_fault_led $off
fan_fault_led_status=$off
fi
fi
}
check_psu_failed() {
local psu0_presence
local psu1_presence
local psu0_value
local psu1_value
psu0_presence=$(gpio_name_get presence-ps0)
psu0_failed="true"
if [ "$psu0_presence" == "0" ]; then
# PSU0 presence, monitor the PSUs using pmbus, check the STATUS_WORD
psu0_value=$(i2cget -f -y $psu_bus $psu0_addr $status_word_cmd w)
psu0_bit_fault=$(($psu0_value & $psu_fault_bitmask))
if [ "$psu0_bit_fault" == "0" ]; then
psu0_failed="false"
fi
fi
psu1_presence=$(gpio_name_get presence-ps1)
psu1_failed="true"
if [ "$psu1_presence" == "0" ]; then
# PSU1 presence, monitor the PSUs using pmbus, check the STATUS_WORD
psu1_value=$(i2cget -f -y $psu_bus $psu1_addr $status_word_cmd w)
psu1_bit_fault=$(($psu1_value & $psu_fault_bitmask))
if [ "$psu1_bit_fault" == "0" ]; then
psu1_failed="false"
fi
fi
if [ "$psu0_failed" == "true" ] || [ "$psu1_failed" == "true" ]; then
psu_failed="true"
else
psu_failed="false"
fi
}
control_psu_fault_led() {
if [ "$psu_failed" == "true" ]; then
if [ "$psu_fault_led_status" == $off ]; then
turn_on_off_psu_fault_led $on
psu_fault_led_status=$on
fi
else
if [ "$psu_fault_led_status" == $on ]; then
turn_on_off_psu_fault_led $off
psu_fault_led_status=$off
fi
fi
}
check_overtemp_occured() {
if [[ -f $overtemp_fault_flag ]]; then
echo "Over temperature occured, turn on fault LED"
overtemp_occured="true"
else
overtemp_occured="false"
fi
}
check_gpio_fault() {
if [[ -f $gpio_fault_flag ]]; then
echo "GPIO fault event(s) occured, turn on fault LED"
gpio_fault="true"
else
gpio_fault="false"
fi
}
check_fault() {
if [[ "$fan_failed" == "true" ]] || [[ "$psu_failed" == "true" ]] \
|| [[ "$overtemp_occured" == "true" ]] \
|| [[ "$gpio_fault" == "true" ]]; then
fault="true"
else
fault="false"
fi
}
# The System Fault Led turns on upon the system error, update the System Fault Led
# based on the Fan fault status and PSU fault status
control_sys_fault_led() {
# Turn on/off the System Fault Led
if [ "$fault" == "true" ]; then
gpio_name_set led-fault $on
else
gpio_name_set led-fault $off
fi
}
# daemon start
while true
do
# Monitors Fan speeds
check_fan_failed
# Monitors PSU presence
check_psu_failed
check_overtemp_occured
check_gpio_fault
# Check fault to update fail
check_fault
control_sys_fault_led
control_fan_fault_led
control_psu_fault_led
sleep 2
done
exit 1
@@ -0,0 +1,18 @@
SUMMARY = "Ampere Computing LLC Update MAC Address from FRU Inventory Information"
DESCRIPTION = "Update MAC Address from FRU Inventory Information for Ampere systems"
PR = "r1"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
inherit systemd
inherit obmc-phosphor-systemd
DEPENDS = "systemd"
RDEPENDS:${PN} = "bash"
FILESEXTRAPATHS:append := "${THISDIR}/${PN}:"
SYSTEMD_SERVICE:${PN} = "ampere_update_mac.service"
@@ -0,0 +1,16 @@
[Unit]
Description=Updating MAC Address Service From FRU inventory
Requires=xyz.openbmc_project.EntityManager.service
After=xyz.openbmc_project.EntityManager.service
StartLimitInterval=25
StartLimitBurst=5
[Service]
ExecStart=/usr/sbin/ampere_update_mac.sh eth0 14 80
SyslogIdentifier=ampere_update_mac.sh
RemainAfterExit=yes
Restart=on-failure
RestartSec=5
[Install]
WantedBy={SYSTEMD_DEFAULT_TARGET}
@@ -0,0 +1,39 @@
SUMMARY = "Phosphor OpenBMC Platform Init Service"
DESCRIPTION = "Phosphor OpenBMC Platform Init Daemon"
PR = "r1"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
inherit systemd
inherit obmc-phosphor-systemd
DEPENDS += "systemd"
RDEPENDS:${PN} += "libsystemd"
RDEPENDS:${PN} += "bash"
SRC_URI = " \
file://ampere-platform-init.service \
file://ampere-bmc-heartbeat.service \
file://ampere_platform_init.sh \
file://ampere_bmc_heartbeat.sh \
file://mtmitchell_platform_gpios_init.sh \
file://gpio-lib.sh \
file://ampere_uart_console_setup.sh \
file://ampere_uartmux_ctrl.sh \
"
SYSTEMD_PACKAGES = "${PN}"
SYSTEMD_SERVICE:${PN} = "ampere-platform-init.service ampere-bmc-heartbeat.service"
do_install () {
install -d ${D}${sbindir}
install -m 0755 ${WORKDIR}/gpio-lib.sh ${D}${sbindir}/
install -m 0755 ${WORKDIR}/ampere_platform_init.sh ${D}${sbindir}/
install -m 0755 ${WORKDIR}/ampere_bmc_heartbeat.sh ${D}${sbindir}/
install -m 0755 ${WORKDIR}/mtmitchell_platform_gpios_init.sh ${D}${sbindir}/platform_gpios_init.sh
install -m 0755 ${WORKDIR}/ampere_uart_console_setup.sh ${D}${sbindir}/
install -m 0755 ${WORKDIR}/ampere_uartmux_ctrl.sh ${D}/${sbindir}/
install -d ${D}${systemd_unitdir}/system/
install -m 0644 ${WORKDIR}/ampere-platform-init.service ${D}${systemd_unitdir}/system
}
@@ -0,0 +1,12 @@
[Unit]
Description=Ampere BMC heartbeat service
[Service]
Type=simple
Restart=always
ExecStart=/usr/sbin/ampere_bmc_heartbeat.sh
SyslogIdentifier = "ampere-bmc-heartbeat"
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,11 @@
[Unit]
Description = Ampere Platform Initialization
[Service]
Restart=no
RemainAfterExit=true
Type=oneshot
ExecStart=/usr/sbin/ampere_platform_init.sh
[Install]
WantedBy=sysinit.target
@@ -0,0 +1,19 @@
#!/bin/bash
# shellcheck source=meta-ampere/meta-mitchell/recipes-ampere/platform/ampere-platform-init/gpio-lib.sh
source /usr/sbin/gpio-lib.sh
value=0
while true;
do
if [[ $value -eq 0 ]]; then
value=1
gpio_name_set led-sw-hb 1
gpio_name_set led-bmc-hb 0
else
value=0
gpio_name_set led-sw-hb 0
gpio_name_set led-bmc-hb 1
fi
sleep 1s
done
@@ -0,0 +1,52 @@
#!/bin/bash
# shellcheck source=meta-ampere/meta-mitchell/recipes-ampere/platform/ampere-platform-init/gpio-lib.sh
source /usr/sbin/gpio-lib.sh
# shellcheck source=meta-ampere/meta-mitchell/recipes-ampere/platform/ampere-platform-init/mtmitchell_platform_gpios_init.sh
source /usr/sbin/platform_gpios_init.sh
source /usr/sbin/ampere_uart_console_setup.sh
#pre platform init function. implemented in platform_gpios_init.sh
pre-platform-init
# =======================================================
# Setting default value for device sel and mux
bootstatus=$(cat /sys/class/watchdog/watchdog0/bootstatus)
if [ "$bootstatus" == '32' ]; then
echo "CONFIGURE: gpio pins to output high after AC power"
for gpioName in "${output_high_gpios_in_ac[@]}"; do
gpio_name_set "$gpioName" 1
done
echo "CONFIGURE: gpio pins to output low after AC power"
for gpioName in "${output_low_gpios_in_ac[@]}"; do
gpio_name_set "$gpioName" 0
done
echo "CONFIGURE: gpio pins to input after AC power"
for gpioName in "${input_gpios_in_ac[@]}"; do
gpio_name_input "$gpioName"
done
fi
# =======================================================
# Setting default value for others gpio pins
echo "CONFIGURE: gpio pins to output high"
for gpioName in "${output_high_gpios_in_bmc_reboot[@]}"; do
gpio_name_set "$gpioName" 1
done
echo "CONFIGURE: gpio pins to output low"
for gpioName in "${output_low_gpios_in_bmc_reboot[@]}"; do
gpio_name_set "$gpioName" 0
done
echo "CONFIGURE: gpio pins to input"
for gpioName in "${input_gpios_in_bmc_reboot[@]}"; do
gpio_name_input "$gpioName"
done
# =======================================================
# Setting uart muxes to BMC as default
uart_console_setup
#post platform init function. implemented in platform_gpios_init.sh
post-platform-init
exit 0
@@ -0,0 +1,47 @@
#!/bin/sh -e
# shellcheck disable=SC2039
# shellcheck disable=SC2112
# shellcheck disable=SC3010
# shellcheck disable=SC3030
# shellcheck disable=SC3054
export obmc_console_tty=("ttyS0" "ttyS1" "ttyS2" "ttyS3" "ttyS7" "ttyS8")
function get_uart_port()
{
tty=$1
case "${tty}" in
"ttyS0") uart=1
;;
"ttyS1") uart=2
;;
"ttyS2") uart=3
;;
"ttyS3") uart=4
;;
"ttyS7") uart=0
;;
"ttyS8") uart=0
;;
*) echo "Invalid tty passed to $0. Exiting!"
exit 1;
;;
esac
echo $uart
}
function uart_console_setup()
{
# Default the host routing through the mux to use the BMC (2)
# This allows the SoL console in webui, and the ssh port 2200, to work
# upon startup. If UART transcievers are installed on the header and required,
# this value should be set to 1
for tty in "${obmc_console_tty[@]}"; do
uart=$(get_uart_port "$tty")
if [ "${uart}" -ne 0 ]
then
/usr/sbin/ampere_uartmux_ctrl.sh "${uart}" 2
fi
done
}
@@ -0,0 +1,44 @@
#!/bin/bash
#
# shellcheck disable=SC2046
# This can be called to set uart mux manually
if [ $# -lt 2 ]; then
exit 1
fi
case "$1" in
1) GPIO_UARTx_MODE0="uart1-mode0"
GPIO_UARTx_MODE1="uart1-mode1"
;;
2) GPIO_UARTx_MODE0="uart2-mode0"
GPIO_UARTx_MODE1="uart2-mode1"
;;
3) GPIO_UARTx_MODE0="uart3-mode0"
GPIO_UARTx_MODE1="uart3-mode1"
;;
4) GPIO_UARTx_MODE0="uart4-mode0"
GPIO_UARTx_MODE1="uart4-mode1"
;;
*) echo "Invalid UART port selection"
exit 1
;;
esac
echo "Ampere UART MUX CTRL UART port $1 to mode $2"
case "$2" in
# To HDR
1) gpioset $(gpiofind "$GPIO_UARTx_MODE0")=1
gpioset $(gpiofind "$GPIO_UARTx_MODE1")=0
exit 0
;;
# To BMC
2) gpioset $(gpiofind "$GPIO_UARTx_MODE0")=0
gpioset $(gpiofind "$GPIO_UARTx_MODE1")=1
exit 0
;;
*) echo "Invalid UART mode selection"
exit 1
;;
esac
@@ -0,0 +1,69 @@
#!/bin/bash
# Configure GPIO as output and set its value
AST2600_GPIO_BASE=(
816
780
)
function gpio_configure_output() {
echo "$1" > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio"$1"/direction
echo "$2" > /sys/class/gpio/gpio"$1"/value
echo "$1" > /sys/class/gpio/unexport
}
function gpio_get_val() {
echo "$1" > /sys/class/gpio/export
cat /sys/class/gpio/gpio"$1"/value
echo "$1" > /sys/class/gpio/unexport
}
# Configure GPIO as input
function gpio_configure_input() {
echo "$1" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio"$1"/direction
echo "$1" > /sys/class/gpio/unexport
}
function gpio_name_set()
{
str=$(gpiofind "$1")
#Verify error code when run gpiofind
if [ "$?" == '1' ]; then
echo "Invalid gpio name $1"
else
gpioid=$(echo "$str"|cut -c 9)
offset=$(echo "$str"|cut -d " " -f 2)
gpioPin=$(("$offset" + ${AST2600_GPIO_BASE[$gpioid]}))
gpio_configure_output "$gpioPin" "$2"
fi
}
function gpio_name_get()
{
str=$(gpiofind "$1")
#Verify error code when run gpiofind
if [ "$?" == '1' ]; then
echo "Invalid gpio name $1"
else
offset=$(echo "$str"|cut -d " " -f 2)
gpioid=$(echo "$str"|cut -c 9)
gpioPin=$(("$offset" + ${AST2600_GPIO_BASE[$gpioid]}))
gpio_get_val "$gpioPin"
fi
}
function gpio_name_input()
{
str=$(gpiofind "$1")
#Verify error code when run gpiofind
if [ "$?" == '1' ]; then
echo "Invalid gpio name $1"
else
gpioid=$(echo "$str"|cut -c 9)
offset=$(echo "$str"|cut -d " " -f 2)
gpioPin=$(("$offset" + ${AST2600_GPIO_BASE[$gpioid]}))
gpio_configure_input "$gpioPin"
fi
}
@@ -0,0 +1,144 @@
#!/bin/bash
# shellcheck source=meta-ampere/meta-mitchell/recipes-ampere/platform/ampere-platform-init/gpio-lib.sh
source /usr/sbin/gpio-lib.sh
function bind_rtc_driver() {
# If rtc device can not present, bind the device
if [[ ! -e /dev/rtc0 ]]; then
echo "Bind rtc driver"
echo 6-0051 > /sys/bus/i2c/drivers/rtc-pcf85063/bind
fi
}
function pre-platform-init() {
echo "Do pre platform init"
}
function post-platform-init() {
# When BMC is rebooted, because PSON_L has pull up to P3V3_STB, it changes its
# value to HIGH. Add code to check P3V3_STB and recover PSON_L to correct state
# before setting BMC_RDY.
cnt=10
pgood=""
while [ $cnt -gt 0 ];
do
pgood=$(busctl get-property org.openbmc.control.Power /org/openbmc/control/power0 org.openbmc.control.Power pgood | cut -d' ' -f2)
if [[ "$pgood" != '' ]]; then
break;
fi
cnt=$(( cnt - 1 ))
sleep 1
done
if [ "$pgood" == '1' ]; then
echo "PSU is on. Setting PSON to 0"
gpio_name_set power-chassis-control 0
else
echo "pgood D-Bus property response as 0. PSU is off."
# for unknown reason when stress reboot bmc power-control.exe detect power-chassis-good is 1 (power on)
# But "busctl get-property org.openbmc.control.Power /org/openbmc/control/power0 org.openbmc.control.Power pgood" responses 0 (power off)
# Add sleep 3 seconds after the pgood dbus reponse (power off) and recheck the power-chassis-good to confirm about the PSU power state
sleep 3
pgood=$(gpio_name_get power-chassis-good)
if [ "$pgood" == '0' ]; then
echo "power-chassis-good reponse as 0. Confirm PSU is off. Setting PSON to 1."
gpio_name_set power-chassis-control 1
fi
fi
gpio_name_set host0-sysreset-n 1
# gpio-leds is controlling bmc-ready, not by gpio
echo 1 > /sys/class/leds/bmc-ready/brightness
echo "Set default FAN speed to 60%"
for filename in /sys/class/hwmon/*/pwm*
do
echo 153 > "$filename"
done
# Bind rtc driver
bind_rtc_driver
}
export output_high_gpios_in_ac=(
# add device enable, mux setting, device select gpios
"spi0-backup-sel"
"i2c-backup-sel"
)
export output_low_gpios_in_ac=(
# add device enable, mux setting, device select gpios
"spi0-program-sel"
"ocp-main-pwren"
)
export input_gpios_in_ac=(
# add device enable, mux setting, device select gpios
)
export output_high_gpios_in_bmc_reboot=(
"host0-sysreset-n"
"host0-pmin-n"
"bmc-debug-mode"
"vrd-sel"
"spd-sel"
"ext-high-temp-n"
"fpga-program-b"
"wd-disable-n"
"hpm-stby-rst-n"
"jtag-sel-s0"
"cpld-user-mode"
"jtag-srst-n"
"host0-shd-req-n"
)
export output_low_gpios_in_bmc_reboot=(
"rtc-battery-voltage-read-enable"
"s0-rtc-lock"
"hpm-fw-recovery"
"led-fault"
"spi-nor-access"
"host0-special-boot"
)
export input_gpios_in_bmc_reboot=(
"s0-vrd-fault-n"
"s1-vrd-fault-n"
"irq-n"
"presence-ps0"
"presence-ps1"
"hsc-12vmain-alt2-n"
"eth-phy-int-n"
"s0-pcp-oc-warn-n"
"s1-pcp-oc-warn-n"
"cpu-bios-recover"
"s0-heartbeat"
"hs-scout-proc-hot"
"s0-vr-hot-n"
"s1-vr-hot-n"
"hsc-12vmain-alt1-n"
"power-chassis-good"
"s0-ddr-save"
"soc-spi-nor-access"
"presence-cpu0"
"jtag-dbgr-prsnt-n"
"ps0-ac-loss-n"
"ps1-ac-loss-n"
"s1-ddr-save"
"sys-pgood"
"presence-cpu1"
"s0-fault-alert"
"s0-sys-auth-failure-n"
"host0-ready"
"ocp-pgood"
"s1-fault-alert"
"s1-fw-boot-ok"
"s0-spi-auth-fail-n"
"s1-sys-auth-failure-n"
"cpld-s1-spi-auth-fail-n"
"ps0-pgood"
"ps1-pgood"
"s0-soc-pgood"
)
@@ -0,0 +1,24 @@
FILESEXTRAPATHS:append := "${THISDIR}/${PN}:"
INSANE_SKIP:${PN} = "already-stripped"
SRC_URI:append = " \
file://ampere_power_util.sh \
file://ampere_firmware_upgrade.sh \
file://ampere_flash_bios.sh \
file://ampere_power_on_driver_binder.sh \
file://ampere_firmware_version.sh \
file://ampere_fanctrl.sh \
file://ampere_scandump_mode.sh \
"
do_install:append() {
install -d ${D}/usr/sbin
install -m 0755 ${WORKDIR}/ampere_power_util.sh ${D}/${sbindir}/
install -m 0755 ${WORKDIR}/ampere_firmware_upgrade.sh ${D}/${sbindir}/
install -m 0755 ${WORKDIR}/ampere_flash_bios.sh ${D}/${sbindir}/
install -m 0755 ${WORKDIR}/ampere_power_on_driver_binder.sh ${D}/${sbindir}/
install -m 0755 ${WORKDIR}/ampere_firmware_version.sh ${D}/${sbindir}/
install -m 0755 ${WORKDIR}/ampere_fanctrl.sh ${D}/${sbindir}/
install -m 0755 ${WORKDIR}/ampere_scandump_mode.sh ${D}/${sbindir}/
}
@@ -0,0 +1,168 @@
#!/bin/bash
fanSensorService="xyz.openbmc_project.FanSensor"
sensorPath="/xyz/openbmc_project/sensors/fan_tach/"
pwmTargetPath="/xyz/openbmc_project/control/fanpwm/"
sensorValueInterfaceName="xyz.openbmc_project.Sensor.Value"
sensorValuePropertyName="Value"
pwmTargetInterfaceName="xyz.openbmc_project.Control.FanPwm"
pwmTargetPropertyName="Target"
function stop_phosphor_fan_services() {
systemctl stop phosphor-fan-control@0.service
systemctl stop phosphor-fan-monitor@0.service
systemctl stop phosphor-fan-presence-tach@0.service
}
function start_phosphor_fan_services() {
systemctl start phosphor-fan-control@0.service
systemctl start phosphor-fan-monitor@0.service
systemctl start phosphor-fan-presence-tach@0.service
}
function read_speed() {
fan_val=$(busctl get-property "$fanSensorService" "${sensorPath}$1" "$sensorValueInterfaceName" "$sensorValuePropertyName")
busctl_error=$?
if (( busctl_error != 0 )); then
echo "Error: get-property $sensorValuePropertyName failed! "
exit 1
fi
pwm_target=$(busctl get-property "$fanSensorService" "${pwmTargetPath}$2" "$pwmTargetInterfaceName" "$pwmTargetPropertyName")
busctl_error=$?
if (( busctl_error != 0 )); then
echo "Error: get-property $pwmTargetPropertyName failed! "
exit 1
fi
fan_val=$(echo "$fan_val" | cut -d " " -f 2)
pwm_target=$(echo "$pwm_target" | cut -d " " -f 2)
# Convert fan PWM to Duty cycle, adding 127 for rounding.
pwm_duty_cyle=$(((("$pwm_target" * 100) + 127) / 255))
echo "$1, PWM: $pwm_target, Duty cycle: $pwm_duty_cyle%, Speed(RPM): $fan_val"
}
function set_pwm() {
# Convert Fan Duty cycle to PWM, adding 50 for rounding.
fan_pwm=$(((($2 * 255) + 50) / 100))
busctl set-property "$fanSensorService" "${pwmTargetPath}$1" "$pwmTargetInterfaceName" "$pwmTargetPropertyName" t "$fan_pwm"
busctl_error=$?
if (( busctl_error != 0 )); then
echo "Error: set-property $pwmTargetPropertyName failed! "
exit 255
fi
}
function getstatus() {
fan_ctl_stt=$(systemctl is-active phosphor-fan-control@0.service | grep inactive)
fan_monitor_stt=$(systemctl is-active phosphor-fan-monitor@0.service | grep inactive)
if [[ -z "$fan_ctl_stt" && -z "$fan_monitor_stt" ]]; then
echo "Thermal Control operational status: Enabled"
exit 0
else
echo "Thermal Control operational status: Disabled"
exit 1
fi
}
function setstatus() {
if [ "$1" == 0 ]; then
# Enable fan services
start_phosphor_fan_services
else
# Disable fan services
stop_phosphor_fan_services
fi
}
function setspeed() {
# Get fan_pwm value of the fan
case "$1" in
0) fan_pwm=PWM7
;;
1) fan_pwm=PWM5
;;
2) fan_pwm=PWM4
;;
3) fan_pwm=PWM3
;;
4) fan_pwm=PWM1
;;
5) fan_pwm=PWM0
;;
*) echo "fan $1 doesn't exit"
exit 1
;;
esac
set_pwm "$fan_pwm" "$2"
exit 0
}
function getspeed() {
# Mapping fan number to fan_input and fan_pwm index
case "$1" in
0) fan_input_f=FAN0_F
fan_input_r=FAN0_R
fan_pwm=PWM7
;;
1) fan_input_f=FAN1_F
fan_input_r=FAN1_R
fan_pwm=PWM5
;;
2) fan_input_f=FAN2_F
fan_input_r=FAN2_R
fan_pwm=PWM4
;;
3) fan_input_f=FAN3_F
fan_input_r=FAN3_R
fan_pwm=PWM3
;;
4) fan_input_f=FAN4_F
fan_input_r=FAN4_R
fan_pwm=PWM1
;;
5) fan_input_f=FAN5_F
fan_input_r=FAN5_F
fan_pwm=PWM0
;;
*) echo "fan $1 doesn't exit"
exit 1
;;
esac
# Get fan speed, each fan number has two values is front and rear
read_speed "$fan_input_f" "$fan_pwm"
read_speed "$fan_input_r" "$fan_pwm"
exit 0
}
# Usage of this utility
function usage() {
echo "Usage:"
echo " ampere_fanctrl.sh [getstatus] [setstatus <0|1>] [setspeed <fan> <duty>] [getspeed <fan>]"
echo " fan: 0-5"
echo " duty: 1-100"
}
if [ "$1" == "getstatus" ]; then
getstatus
elif [ "$1" == "setstatus" ]; then
setstatus "$2"
elif [ "$1" == "setspeed" ]; then
stop_phosphor_fan_services
setspeed "$2" "$3"
elif [ "$1" == "getspeed" ]; then
getspeed "$2"
else
usage
fi
@@ -0,0 +1,201 @@
#!/bin/bash
# Helper script to flash FRU and Boot EEPROM devices.
#
# Syntax for FRU:
# ampere_firmware_upgrade.sh fru <image> [<dev>]
# dev: 1 for MB FRU (default), 2 for BMC FRU.
#
# Syntax for EEPROM:
# ampere_firmware_upgrade.sh eeprom <image> [<dev>]
# dev: 1 for main Boot EEPROM (default), 2 for secondary Boot EEPROM (if supported)
#
# Syntax for Mainboard CPLD:
# ampere_firmware_upgrade.sh main_cpld <image>
#
# Syntax for BMC CPLD:
# ampere_firmware_upgrade.sh bmc_cpld <image>
#
# Syntax for Backplane CPLD:
# ampere_firmware_upgrade.sh bp_cpld <image> [<target>]
# target: 1 for Front Backplane 1
# 2 for Front Backplane 2
# 3 for Front Backplane 3
# 4 for Rear Backplane 1
# 5 for Rear Backplane 2
#
# shellcheck disable=SC2046
do_eeprom_flash() {
FIRMWARE_IMAGE=$IMAGE
BACKUP_SEL=$2
# Turn off the Host if it is currently ON
chassisstate=$(obmcutil chassisstate | awk -F. '{print $NF}')
echo "Current Chassis State: $chassisstate"
if [ "$chassisstate" == 'On' ];
then
echo "Turning the Chassis off"
obmcutil chassisoff
sleep 15
# Check if HOST was OFF
chassisstate_off=$(obmcutil chassisstate | awk -F. '{print $NF}')
if [ "$chassisstate_off" == 'On' ];
then
echo "Error : Failed turning the Chassis off"
exit 1
fi
fi
# Switch EEPROM control to BMC AST2600 I2C
# BMC_GPIOW6_SPI0_PROGRAM_SEL
gpioset $(gpiofind spi0-program-sel)=1
# BMC_GPIOX0_I2C_BACKUP_SEL (GPIO 184)
if [[ $BACKUP_SEL == 1 ]]; then
echo "Run update Primary EEPROM"
gpioset $(gpiofind i2c-backup-sel)=0
elif [[ $BACKUP_SEL == 2 ]]; then
echo "Run update Failover EEPROM"
gpioset $(gpiofind i2c-backup-sel)=1
else
echo "Please choose Primary EEPROM (1) or Failover EEPROM (2)"
exit 0
fi
# The EEPROM (AT24C64WI) with address 0x50 at BMC_I2C11 bus
# Write Firmware to EEPROM and read back for validation
ampere_eeprom_prog -b 10 -s 0x50 -p -f "$FIRMWARE_IMAGE"
# Switch to primary EEPROM
gpioset $(gpiofind i2c-backup-sel)=0
# Switch EEPROM control to CPU HOST
gpioset $(gpiofind spi0-program-sel)=0
if [ "$chassisstate" == 'On' ];
then
sleep 5
echo "Turn on the Host"
obmcutil poweron
fi
}
do_fru_flash() {
FRU_IMAGE=$1
FRU_DEV=$2
if [[ $FRU_DEV == 1 ]]; then
if [ -f /sys/bus/i2c/devices/4-0050/eeprom ]; then
FRU_DEVICE="/sys/bus/i2c/devices/4-0050/eeprom"
else
FRU_DEVICE="/sys/bus/i2c/devices/3-0050/eeprom"
fi
echo "Flash MB FRU with image $IMAGE at $FRU_DEVICE"
elif [[ $FRU_DEV == 2 ]]; then
FRU_DEVICE="/sys/bus/i2c/devices/14-0050/eeprom"
echo "Flash BMC FRU with image $IMAGE at $FRU_DEVICE"
else
echo "Please select MB FRU (1) or BMC FRU (2)"
exit 0
fi
ampere_fru_upgrade -d "$FRU_DEVICE" -f "$FRU_IMAGE"
systemctl restart xyz.openbmc_project.FruDevice.service
systemctl restart phosphor-ipmi-host.service
echo "Done"
}
do_mb_cpld_flash() {
MB_CPLD_IMAGE=$1
echo "Flashing MB CPLD"
gpioset $(gpiofind hpm-fw-recovery)=1
gpioset $(gpiofind jtag-program-sel)=1
sleep 2
ampere_cpldupdate_jtag -t 1 -p "$MB_CPLD_IMAGE"
gpioset $(gpiofind hpm-fw-recovery)=0
echo "Done"
}
do_bmc_cpld_flash() {
BMC_CPLD_IMAGE=$1
echo "Flashing BMC CPLD"
gpioset $(gpiofind jtag-program-sel)=0
sleep 2
ampere_cpldupdate_jtag -t 1 -p "$BMC_CPLD_IMAGE"
echo "Done"
}
do_bp_cpld_flash() {
BP_CPLD_IMAGE=$1
BP_TARGET=$2
if [[ $BP_TARGET == 1 ]]; then
echo "Flashing Front Backplane 1 CPLD"
ampere_cpldupdate_i2c -b 101 -s 0x40 -t 3 -p "$BP_CPLD_IMAGE"
elif [[ $BP_TARGET == 2 ]]; then
echo "Flashing Front Backplane 2 CPLD"
ampere_cpldupdate_i2c -b 102 -s 0x40 -t 3 -p "$BP_CPLD_IMAGE"
elif [[ $BP_TARGET == 3 ]]; then
echo "Flashing Front Backplane 3 CPLD"
ampere_cpldupdate_i2c -b 100 -s 0x40 -t 3 -p "$BP_CPLD_IMAGE"
elif [[ $BP_TARGET == 4 ]]; then
echo "Flashing Rear Backplane 1 CPLD"
ampere_cpldupdate_i2c -b 103 -s 0x40 -t 3 -p "$BP_CPLD_IMAGE"
elif [[ $BP_TARGET == 5 ]]; then
echo "Flashing Rear Backplane 2 CPLD"
ampere_cpldupdate_i2c -b 104 -s 0x40 -t 3 -p "$BP_CPLD_IMAGE"
fi
echo "Done"
}
if [ $# -eq 0 ]; then
echo "Usage:"
echo " - Flash Boot EEPROM"
echo " $(basename "$0") eeprom <Image file>"
echo " - Flash FRU"
echo " $(basename "$0") fru <Image file> [dev]"
echo " Where:"
echo " dev: 1 - MB FRU, 2 - BMC FRU"
echo " - Flash Mainboard CPLD"
echo " $(basename "$0") mb_cpld <Image file>"
echo " - Flash BMC CPLD (only for DC-SCM BMC board)"
echo " $(basename "$0") bmc_cpld <Image file>"
echo " - Flash Backplane CPLD"
echo " $(basename "$0") bp_cpld <Image file> <Target> "
echo " Where:"
echo " Target: 1 - FrontBP1, 2 - FrontBP2, 3 - FrontBP3"
echo " 4 - RearBP1, 5 - RearBP2"
exit 0
fi
TYPE=$1
IMAGE=$2
TARGET=$3
if [ -z "$3" ]; then
BACKUP_SEL=1
else
BACKUP_SEL=$3
fi
if [[ $TYPE == "eeprom" ]]; then
# Run EEPROM update: write/read/validation with CRC32 checksum
do_eeprom_flash "$IMAGE" "$BACKUP_SEL"
elif [[ $TYPE == "fru" ]]; then
# Run FRU update
do_fru_flash "$IMAGE" "$BACKUP_SEL"
elif [[ $TYPE == "mb_cpld" ]]; then
# Run Mainboard CPLD update
do_mb_cpld_flash "$IMAGE"
elif [[ $TYPE == "bmc_cpld" ]]; then
# Run CPLD BMC update
do_bmc_cpld_flash "$IMAGE"
elif [[ $TYPE == "bp_cpld" ]]; then
# Run Backplane CPLD update
do_bp_cpld_flash "$IMAGE" "$TARGET"
fi
exit 0
@@ -0,0 +1,99 @@
#!/bin/bash
# Helper script to report firmware version for components on the system (MB CPLD, Backplane CPLD, …)
# Author : Hieu Huynh (hieu.huynh@amperecomputing.com)
#
# Get MB CPLD firmware revision:
# ampere_firmware_version.sh mb_cpld
#
# Get BMC CPLD firmware revision:
# ampere_firmware_version.sh bmc_cpld
#
# Get Backplane CPLD firmware revision:
# ampere_firmware_version.sh bp_cpld <id>
# <id>: 1 for Front Backplane 1
# 2 for Front Backplane 2
# 3 for Front Backplane 3
# 4 for Rear Backplane 1
# 5 for Rear Backplane 2
# shellcheck disable=SC2046
do_mb_cpld_firmware_report() {
echo "MB CPLD"
gpioset $(gpiofind hpm-fw-recovery)=1
gpioset $(gpiofind jtag-program-sel)=1
sleep 1
ampere_cpldupdate_jtag -v
ampere_cpldupdate_jtag -i
}
do_bmc_cpld_firmware_report() {
echo "BMC CPLD (Only for DC-SCM board)"
gpioset $(gpiofind jtag-program-sel)=0
sleep 1
ampere_cpldupdate_jtag -v
ampere_cpldupdate_jtag -i
}
do_bp_cpld_firmware_report() {
BP_ID=$1
if [[ $BP_ID == 1 ]]; then
echo "Front Backplane 1 CPLD"
ampere_cpldupdate_i2c -b 101 -s 0x40 -t 3 -v
ampere_cpldupdate_i2c -b 101 -s 0x40 -t 3 -i
elif [[ $BP_ID == 2 ]]; then
echo "Front Backplane 2 CPLD"
ampere_cpldupdate_i2c -b 102 -s 0x40 -t 3 -v
ampere_cpldupdate_i2c -b 102 -s 0x40 -t 3 -i
elif [[ $BP_ID == 3 ]]; then
echo "Front Backplane 3 CPLD"
ampere_cpldupdate_i2c -b 100 -s 0x40 -t 3 -v
ampere_cpldupdate_i2c -b 100 -s 0x40 -t 3 -i
elif [[ $BP_ID == 4 ]]; then
echo "Rear Backplane 1 CPLD"
ampere_cpldupdate_i2c -b 103 -s 0x40 -t 3 -v
ampere_cpldupdate_i2c -b 103 -s 0x40 -t 3 -i
elif [[ $BP_ID == 5 ]]; then
echo "Rear Backplane 2 CPLD"
ampere_cpldupdate_i2c -b 104 -s 0x40 -t 3 -v
ampere_cpldupdate_i2c -b 104 -s 0x40 -t 3 -i
fi
}
if [ $# -eq 0 ]; then
echo "Usage:"
echo " - Get MB CPLD firmware revision"
echo " $(basename "$0") mb_cpld"
echo " - Get BMC CPLD firmware revision"
echo " $(basename "$0") bmc_cpld"
echo " - Get Backplane CPLD firmware revision"
echo " $(basename "$0") bp_cpld <id>"
echo " <id>:"
echo " 1 - FrontBP1"
echo " 2 - FrontBP2"
echo " 3 - FrontBP3"
echo " 4 - RearBP1"
echo " 5 - RearBP2"
exit 0
fi
TYPE=$1
ID=$2
if [[ $TYPE == "mb_cpld" ]]; then
do_mb_cpld_firmware_report
elif [[ $TYPE == "bmc_cpld" ]]; then
do_bmc_cpld_firmware_report
elif [[ $TYPE == "bp_cpld" ]]; then
if [ -z "$ID" ]; then
echo "Please choose backplanes id: 1 - FrontBP1, 2 - FrontBP2, 3 - FrontBP3, 4 - FrontBP4, 5 - FrontBP5"
exit 0
elif [[ "$ID" -ge "1" ]] && [[ "$ID" -le "5" ]]; then
do_bp_cpld_firmware_report "$ID"
else
echo "Backplanes id invalid"
fi
fi
exit 0
@@ -0,0 +1,162 @@
#!/bin/bash
# This script is used to flash the UEFI/EDKII
# Syntax: ampere_flash_bios.sh $image_file $device_sellect
# Where:
# $image_file : the image binary file
# $device_sellect : 1 - Host Main SPI Nor
# 2 - Host Second SPI Nor
# Author : Chanh Nguyen (chnguyen@amperecomputing.com)
# Note:
# BMC_GPIOW6_SPI0_PROGRAM_SEL (GPIO 182): 1 => BMC owns SPI bus for upgrading
# 0 => HOST owns SPI bus for upgrading
# BMC_GPIOW7_SPI0_BACKUP_SEL (GPIO 183) : 1 => to switch SPI_CS0_L to primary SPI Nor device
# 0 => to switch SPI_CS0_L to second SPI Nor device
# shellcheck disable=SC2046
do_flash () {
# Check the HNOR partition available
HOST_MTD=$(< /proc/mtd grep "pnor" | sed -n 's/^\(.*\):.*/\1/p')
if [ -z "$HOST_MTD" ];
then
# Check the ASpeed SMC driver binded before
HOST_SPI=/sys/bus/platform/drivers/spi-aspeed-smc/1e630000.spi
if [ -d "$HOST_SPI" ]; then
echo "Unbind the ASpeed SMC driver"
echo 1e630000.spi > /sys/bus/platform/drivers/spi-aspeed-smc/unbind
sleep 2
fi
# If the HNOR partition is not available, then bind again driver
echo "--- Bind the ASpeed SMC driver"
echo 1e630000.spi > /sys/bus/platform/drivers/spi-aspeed-smc/bind
sleep 2
HOST_MTD=$(< /proc/mtd grep "pnor" | sed -n 's/^\(.*\):.*/\1/p')
if [ -z "$HOST_MTD" ];
then
echo "Fail to probe Host SPI-NOR device"
exit 1
fi
fi
echo "--- Flashing firmware image $IMAGE to @/dev/$HOST_MTD"
flashcp -v "$IMAGE" /dev/"$HOST_MTD"
}
if [ $# -eq 0 ]; then
echo "Usage: $(basename "$0") <UEFI/EDKII image file> <DEV_SEL> [SPECIAL_BOOT]"
echo "Where:"
echo " DEV_SEL 1 is Primary SPI (by default), 2 is Second SPI"
echo " SPECIAL_BOOT: Optional, input '1' to enter & flash SPECIAL_BOOT mode. Default: 0"
exit 0
fi
IMAGE="$1"
if [ ! -f "$IMAGE" ]; then
echo "The image file $IMAGE does not exist"
exit 1
fi
if [ -z "$2" ]; then
DEV_SEL="1" # by default, select primary device
else
DEV_SEL="$2"
fi
SPECIAL_BOOT=0
if [[ "$3" == "1" ]]; then
SPECIAL_BOOT=1
fi
echo "SPECIAL_BOOT mode: $SPECIAL_BOOT"
# Turn off the Host if it is currently ON
chassisstate=$(obmcutil chassisstate | awk -F. '{print $NF}')
echo "--- Current Chassis State: $chassisstate"
if [ "$chassisstate" == 'On' ];
then
echo "--- Turning the Chassis off"
obmcutil chassisoff
sleep 10
# Check if HOST was OFF
chassisstate_off=$(obmcutil chassisstate | awk -F. '{print $NF}')
if [ "$chassisstate_off" == 'On' ];
then
echo "--- Error : Failed turning the Chassis off"
exit 1
fi
fi
# Switch the host SPI bus to BMC"
echo "--- Switch the host SPI bus to BMC."
if ! gpioset $(gpiofind spi0-program-sel)=1; then
echo "ERROR: Switch the host SPI bus to BMC. Please check gpio state"
exit 1
fi
# Switch the host SPI bus (between primary and secondary)
# 183 is BMC_GPIOW7_SPI0_BACKUP_SEL
if [[ $DEV_SEL == 1 ]]; then
echo "Run update Primary Host SPI-NOR"
gpioset $(gpiofind spi0-backup-sel)=1 # Primary SPI
elif [[ $DEV_SEL == 2 ]]; then
echo "Run update Second Host SPI-NOR"
gpioset $(gpiofind spi0-backup-sel)=0 # Second SPI
else
echo "Please choose primary SPI (1) or second SPI (2)"
exit 0
fi
# Restrict to flash Second Host SPI-NOR in case of SPECIAL_BOOT
if [ $SPECIAL_BOOT == 1 ] && [ "$DEV_SEL" == 2 ]; then
echo "Not allow to flash the Second Host SPI-NOR with SPECIAL_BOOT image"
exit
fi
# Flash the firmware
do_flash
# Assert SPECIAL_BOOT GPIO PIN
if [[ $SPECIAL_BOOT == 1 ]]; then
gpioset $(gpiofind host0-special-boot)=1
fi
# Switch the SPI bus to the primary spi device
echo "Switch to the Primary Host SPI-NOR"
gpioset $(gpiofind spi0-backup-sel)=1 # Primary SPI
# Switch the host SPI bus to HOST."
echo "--- Switch the host SPI bus to HOST."
if ! gpioset $(gpiofind spi0-program-sel)=0; then
echo "ERROR: Switch the host SPI bus to HOST. Please check gpio state"
exit 1
fi
if [ "$chassisstate" == 'On' ] || [ $SPECIAL_BOOT == 1 ];
then
sleep 5
echo "Turn on the Host"
obmcutil poweron
fi
# Deassert SPECIAL_BOOT GPIO PIN if it is being asserted
if [[ $SPECIAL_BOOT == 1 ]]; then
# Time out checking for Host ON is 60s
cnt=12
while [ "$cnt" -gt 0 ];
do
cnt=$((cnt - 1))
if systemctl status obmc-host-already-on@0.target | grep "Active: active"; then
echo "Deassert SPECIAL_BOOT GPIO PIN if it is being asserted."
gpioset $(gpiofind host0-special-boot)=0
exit 0
fi
sleep 5
done
fi
@@ -0,0 +1,50 @@
#!/bin/bash
# Each driver include driver name and driver path
declare -a DRIVER_NAMEs=(
"107-0070"
"100-0071"
"101-0071"
"102-0071"
"103-0071"
"104-0071"
"100-0050"
"101-0050"
"102-0050"
"100-004c"
"101-004c"
"102-004c"
)
# Driver path should include / at the end
declare -a DRIVER_PATHs=(
"/sys/bus/i2c/drivers/pca954x/"
"/sys/bus/i2c/drivers/pca954x/"
"/sys/bus/i2c/drivers/pca954x/"
"/sys/bus/i2c/drivers/pca954x/"
"/sys/bus/i2c/drivers/pca954x/"
"/sys/bus/i2c/drivers/pca954x/"
"/sys/bus/i2c/drivers/at24/"
"/sys/bus/i2c/drivers/at24/"
"/sys/bus/i2c/drivers/at24/"
"/sys/bus/i2c/drivers/lm75/"
"/sys/bus/i2c/drivers/lm75/"
"/sys/bus/i2c/drivers/lm75/"
)
# get length of an array
arraylength=${#DRIVER_NAMEs[@]}
# use for loop to read all values and indexes
for (( i=0; i<"${arraylength}"; i++ ));
do
bindFile="${DRIVER_PATHs[$i]}bind"
driverDir="${DRIVER_PATHs[$i]}${DRIVER_NAMEs[$i]}"
echo "binding ${DRIVER_NAMEs[$i]} path ${DRIVER_PATHs[$i]} on Chassi Power On"
if [ -d "$driverDir" ]; then
echo "Driver ${DRIVER_NAMEs[$i]} is already bound."
else
echo "${DRIVER_NAMEs[$i]}" > "$bindFile"
fi
done
exit 0
@@ -0,0 +1,131 @@
#!/bin/bash
# shellcheck source=meta-ampere/meta-mitchell/recipes-ampere/platform/ampere-platform-init/gpio-lib.sh
source /usr/sbin/gpio-lib.sh
# Usage of this utility
function usage() {
echo "usage: power-util mb [status|shutdown_ack|force_reset|soft_off|host_reboot_wa]";
}
power_status() {
st=$(busctl get-property xyz.openbmc_project.State.Chassis /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis CurrentPowerState | cut -d"." -f6)
if [ "$st" == "On\"" ]; then
echo "on"
else
echo "off"
fi
}
shutdown_ack() {
if [ -f "/run/openbmc/host@0-softpoweroff" ]; then
echo "Receive shutdown ACK triggered after softportoff the host."
touch /run/openbmc/host@0-softpoweroff-shutdown-ack
else
echo "Receive shutdown ACK triggered"
sleep 3
systemctl start obmc-chassis-poweroff@0.target
fi
}
soft_off() {
# Trigger shutdown_req
touch /run/openbmc/host@0-softpoweroff
gpio_name_set host0-shd-req-n 0
sleep 0.05
gpio_name_set host0-shd-req-n 1
# Wait for shutdown_ack from the host in 30 seconds
cnt=30
while [ $cnt -gt 0 ];
do
# Wait for SHUTDOWN_ACK and create the host@0-softpoweroff-shutdown-ack
if [ -f "/run/openbmc/host@0-softpoweroff-shutdown-ack" ]; then
break
fi
sleep 1
cnt=$((cnt - 1))
done
# Softpoweroff is successed
sleep 2
rm -rf /run/openbmc/host@0-softpoweroff
if [ -f "/run/openbmc/host@0-softpoweroff-shutdown-ack" ]; then
rm -rf /run/openbmc/host@0-softpoweroff-shutdown-ack
fi
echo 0
}
force_reset() {
if [ -f "/run/openbmc/host@0-softpoweroff" ]; then
# In graceful host reset, after trigger os shutdown,
# the phosphor-state-manager will call force-warm-reset
# in this case the force_reset should wait for shutdown_ack from host
cnt=30
while [ $cnt -gt 0 ];
do
if [ -f "/run/openbmc/host@0-softpoweroff-shutdown-ack" ]; then
break
fi
echo "Waiting for shutdown-ack count down $cnt"
sleep 1
cnt=$((cnt - 1))
done
# The host OS is failed to shutdown
if [ $cnt == 0 ]; then
echo "Shutdown-ack time out after 30s."
exit 0
fi
fi
rm -f /run/openbmc/host@0-on
echo "Triggering sysreset pin"
gpio_name_set host0-sysreset-n 0
sleep 1
gpio_name_set host0-sysreset-n 1
}
host_reboot_wa() {
busctl set-property xyz.openbmc_project.State.Chassis \
/xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis \
RequestedPowerTransition s "xyz.openbmc_project.State.Chassis.Transition.Off"
while ( true )
do
if systemctl status obmc-power-off@0.target | grep "Active: active"; then
break;
fi
sleep 2
done
echo "The power is already Off."
busctl set-property xyz.openbmc_project.State.Host \
/xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host \
RequestedHostTransition s "xyz.openbmc_project.State.Host.Transition.On"
}
if [ ! -d "/run/openbmc/" ]; then
mkdir -p "/run/openbmc/"
fi
if [ "$2" == "shutdown_ack" ]; then
shutdown_ack
elif [ "$2" == "status" ]; then
power_status
elif [ "$2" == "force_reset" ]; then
force_reset
elif [ "$2" == "host_reboot_wa" ]; then
host_reboot_wa
elif [ "$2" == "soft_off" ]; then
ret=$(soft_off)
if [ "$ret" == 0 ]; then
echo "The host is already softoff"
else
echo "Failed to softoff the host"
fi
exit "$ret";
else
echo "Invalid parameter2=$2"
usage;
fi
exit 0;
@@ -0,0 +1,94 @@
#!/bin/bash
# Helper script to support enable/disable Scandump Mode
# Author : Hieu Huynh (hieu.huynh@amperecomputing.com)
#
# To enable Scandump mode:
# ampere_scandump_mode.sh enable
#
# To disable Scandump mode:
# ampere_scandump_mode.sh disable
#
# To get Scandump mode status:
# ampere_scandump_mode.sh getstatus
enable_scandump_mode() {
echo "Enable Scandump mode"
# Disable Mpro hang detection
systemctl stop ampere-sysfw-hang-handler.service
# Disable PLDM service
systemctl stop pldmd.service
# Enable scandump mode in CPLD
# Get Port0 value
p0_val=$(i2cget -f -y 15 0x22 0x02)
p0_val=$(("$p0_val" | (1 << 4)))
# Set Port0[4] value to "1" to mask all CPUs GPIOs, set Port0[4].
i2cset -f -y 15 0x22 0x02 $p0_val
p0_IOexp_val=$(i2cget -f -y 15 0x22 0x06)
p0_IOexp_val=$(("$p0_IOexp_val" & ~(1 << 4)))
# Config CPLD's IOepx Port0[4] from input to output, clear IOepx Port0[4].
i2cset -f -y 15 0x22 0x06 $p0_IOexp_val
}
diable_scandump_mode() {
echo "Disable Scandump mode"
# Disable scandump mode in CPLD
# Get Port0 value
p0_val=$(i2cget -f -y 15 0x22 0x02)
p0_val=$(("$p0_val" & ~(1 << 4)))
# Set Port0[4] value to "0" to unmask all CPUs GPIOs, clear Port0[4].
i2cset -f -y 15 0x22 0x02 $p0_val
p0_IOexp_val=$(i2cget -f -y 15 0x22 0x06)
p0_IOexp_val=$(("$p0_IOexp_val" | (1 << 4)))
# Config CPLD's IOepx Port0[4] from output to input, set IOepx Port0[4].
i2cset -f -y 15 0x22 0x06 $p0_IOexp_val
# Enable Mpro hang detection
systemctl start ampere-sysfw-hang-handler.service
# Enable PLDM service
systemctl start pldmd.service
}
getstatus() {
# Get CPLD's IOepx Port0[4], if this bit is "0" scandump mode is enabled.
p0_IOexp_val=$(i2cget -f -y 15 0x22 0x06)
p0_IOexp_val=$(("$p0_IOexp_val" & (1 << 4)))
if [[ "$p0_IOexp_val" == "0" ]]; then
echo "Scandump mode is enabled"
exit 1
else
echo "Scandump mode is disabled"
exit 0
fi
}
# Usage of this utility
usage() {
echo "Usage:"
echo " - To enable Scandump mode"
echo " $(basename "$0") enable"
echo " - To disable Scandump mode"
echo " $(basename "$0") disable"
echo " - To get Scandump mode status"
echo " $(basename "$0") getstatus"
exit 0
}
if [[ $1 == "enable" ]]; then
enable_scandump_mode
elif [[ $1 == "disable" ]]; then
diable_scandump_mode
elif [[ $1 == "getstatus" ]]; then
getstatus
else
echo "Invalid mode"
usage
fi
exit 0