diff options
Diffstat (limited to 'meta-quanta/meta-gbs/recipes-gbs')
32 files changed, 1321 insertions, 0 deletions
diff --git a/meta-quanta/meta-gbs/recipes-gbs/boot-status-led/files/boot-status-led.service b/meta-quanta/meta-gbs/recipes-gbs/boot-status-led/files/boot-status-led.service new file mode 100644 index 000000000..ea44dda2d --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/boot-status-led/files/boot-status-led.service @@ -0,0 +1,13 @@ +[Unit] +Description=Boot Status LED Manager +After=xyz.openbmc_project.LED.GroupManager.service +Wants=xyz.openbmc_project.LED.GroupManager.service + +[Service] +ExecStart=/usr/bin/boot-status-led.sh +StandardOutput=syslog +Type=simple +Restart=yes + +[Install] +WantedBy=multi-user.target diff --git a/meta-quanta/meta-gbs/recipes-gbs/boot-status-led/files/boot-status-led.sh b/meta-quanta/meta-gbs/recipes-gbs/boot-status-led/files/boot-status-led.sh new file mode 100644 index 000000000..a80082a1c --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/boot-status-led/files/boot-status-led.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +BOOT_SERVICE_NAME="xyz.openbmc_project.State.Host" +BOOT_STATUS_OBJPATH="/xyz/openbmc_project/state/os" +BOOT_INTERFACE_NAME="xyz.openbmc_project.State.OperatingSystem.Status" +BOOT_Property="OperatingSystemState" + +LED_SERVICE_NAME="xyz.openbmc_project.LED.GroupManager" +LED_INACTIVE_OBJPATH="/xyz/openbmc_project/led/groups/boot_status_inactive" +LED_STANDBY_OBJPATH="/xyz/openbmc_project/led/groups/boot_status_standby" +LED_INTERFACE_NAME="xyz.openbmc_project.Led.Group" +LED_Property="Asserted" + +PWR_STATE_SERVICE="xyz.openbmc_project.State.Chassis" +PWR_STATE_OBJPATH="/xyz/openbmc_project/state/chassis0" +PWR_STATE_INTERFACE_NAME="xyz.openbmc_project.State.Chassis" +PWR_STATE_Property="CurrentPowerState" + +boot_status="" +power_state="" +led_status="" + +mapper wait $LED_INACTIVE_OBJPATH +mapper wait $LED_STANDBY_OBJPATH +while true; do + power_state="$(busctl get-property $PWR_STATE_SERVICE $PWR_STATE_OBJPATH $PWR_STATE_INTERFACE_NAME $PWR_STATE_Property | awk '{print $2}')" + + boot_status="$(busctl get-property $BOOT_SERVICE_NAME $BOOT_STATUS_OBJPATH $BOOT_INTERFACE_NAME $BOOT_Property | awk '{print $2}')" + + if [[ $power_state != "\"xyz.openbmc_project.State.Chassis.PowerState.On\"" ]];then + if [[ $led_status != "OFF" ]];then + busctl set-property $LED_SERVICE_NAME $LED_INACTIVE_OBJPATH $LED_INTERFACE_NAME $LED_Property b false + busctl set-property $LED_SERVICE_NAME $LED_STANDBY_OBJPATH $LED_INTERFACE_NAME $LED_Property b false + led_status="OFF" + fi + continue + else + if [[ $boot_status != "\"Standby\"" ]] && [[ $led_status != "BLINKING" ]];then + busctl set-property $LED_SERVICE_NAME $LED_INACTIVE_OBJPATH $LED_INTERFACE_NAME $LED_Property b true + led_status="BLINKING" + elif [[ $boot_status == "\"Standby\"" ]] && [[ $led_status != "ON" ]];then + busctl set-property $LED_SERVICE_NAME $LED_INACTIVE_OBJPATH $LED_INTERFACE_NAME $LED_Property b false + busctl set-property $LED_SERVICE_NAME $LED_STANDBY_OBJPATH $LED_INTERFACE_NAME $LED_Property b true + led_status="ON" + fi + fi + sleep 1 +done + +exit 0 diff --git a/meta-quanta/meta-gbs/recipes-gbs/boot-status-led/gbs-boot-status-led.bb b/meta-quanta/meta-gbs/recipes-gbs/boot-status-led/gbs-boot-status-led.bb new file mode 100644 index 000000000..61c6ed407 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/boot-status-led/gbs-boot-status-led.bb @@ -0,0 +1,25 @@ +SUMMARY = "OpenBMC Quanta Boot Status LED Service" +DESCRIPTION = "OpenBMC Quanta Boot Status LED Daemon." +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit systemd + +DEPENDS += "systemd" +RDEPENDS_${PN} += "bash" + +SRC_URI = " file://boot-status-led.sh \ + file://boot-status-led.service \ + " + +do_install() { + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/boot-status-led.sh ${D}${bindir}/ + + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/boot-status-led.service ${D}${systemd_system_unitdir} +} + +SYSTEMD_PACKAGES = "${PN}" +SYSTEMD_SERVICE_${PN} = "boot-status-led.service" diff --git a/meta-quanta/meta-gbs/recipes-gbs/cpld-ver-check/files/cpld-version.service b/meta-quanta/meta-gbs/recipes-gbs/cpld-ver-check/files/cpld-version.service new file mode 100644 index 000000000..87f42ae05 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/cpld-ver-check/files/cpld-version.service @@ -0,0 +1,10 @@ +[Unit] +Description=Report CPLD Version + +[Service] +RemainAfterExit=yes +Type=oneshot +ExecStart=/usr/bin/cpld_version.sh + +[Install] +WantedBy=multi-user.target diff --git a/meta-quanta/meta-gbs/recipes-gbs/cpld-ver-check/files/cpld_version.sh b/meta-quanta/meta-gbs/recipes-gbs/cpld-ver-check/files/cpld_version.sh new file mode 100644 index 000000000..c69949cc9 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/cpld-ver-check/files/cpld_version.sh @@ -0,0 +1,124 @@ +#!/bin/bash +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +################################################################# +# Prints CPLD version and save it in file /run/cpld0.version +# +# CPLD version format: Major.Minor.Point.Subpoint +# +# Major/Minor: base vendor image version, encoded in register 0x0 of the CPLD +# I2C bus. +# Major = higher 4 bits of register 0x00 +# Minor = lower 4 bits of register 0x00 +# Point/SubPoint: reserved as 0x0 for now +# +# e.g. reg[0] = 0x25 -> ver 2.5.0.0 +# +################################################################# + +CPLD_I2C_BUS_NUM=13 +CPLD_I2C_BUS_ADDR='0x21' +CPLD_I2C_BASEVER_REG='0x00' +VER_ENV_FILE='/run/cpld0.version' + +################################################################# +# Parse the byte value from i2cget and sanity checks the hex format +# Arguments: +# $1: i2c_bus_num +# $2: i2c_bus_addr +# $3: i2c_reg +# Global: +# 'byte_val' will be written with the numeric value from i2cget +# Returns: +# 0 if success, non-zero if failed to get the value or value is malformed +################################################################# +read_and_check_i2c_get() { + if ! (( $# == 3 )); then + echo "Usage: read_and_check_i2c_get i2c_bus_num i2c_bus_addr i2c_reg" + return 1 + fi + + local i2c_bus_num=$1 + local i2c_bus_addr=$2 + local i2c_reg=$3 + + local i2c_val_raw + i2c_val_raw=$(i2cget -y "${i2c_bus_num}" "${i2c_bus_addr}" "${i2c_reg}") || return + + # Verify that it is of format 0x[hex][hex]. + local HEXBYTE_RE='^0x[0-9A-Fa-f]{2}$' + if ! [[ ${i2c_val_raw} =~ ${HEXBYTE_RE} ]]; then + echo "i2cget $* outputs invalid value: ${i2c_val_raw}" + return 1 + fi + + ((byte_val = i2c_val_raw)) + return 0 +} + +################################################################# +# Prints CPLD version in Major.Minor.Point.Subpoint format. +# Each dot separated field is decimal number with no leading zeros. +# Arguments: +# None +# Globals: +# Write parsed version into the following global variables: +# cpld_ver_major +# cpld_ver_minor +# cpld_point +# cpld_subpoint +# Returns: +# 0 if success, non-zero otherwise +################################################################# +parse_cpld_ver() { + # Stores the output of read_and_check_i2c_get + local byte_val + + # Read a byte, assign higher 4 bits to cpld_ver_major and lower 4 bits to + # cpld_ver_minor. + # e.g. cpld_ver_raw = 0x09 => major_hex = 0, minor_hex = 9 + read_and_check_i2c_get ${CPLD_I2C_BUS_NUM} ${CPLD_I2C_BUS_ADDR} ${CPLD_I2C_BASEVER_REG} || + return + local cpld_ver + ((cpld_ver = byte_val)) + ((cpld_ver_major = cpld_ver >> 4)) + ((cpld_ver_minor = cpld_ver & 0xf)) + ((cpld_point = 0)) + ((cpld_subpoint = 0)) + + return 0 +} + +main() { + local cpld_ver_major + local cpld_ver_minor + local cpld_point + local cpld_subpoint + + parse_cpld_ver || return + + # Write CPLD version to file. + cpld_ver="${cpld_ver_major}.${cpld_ver_minor}.${cpld_point}.${cpld_subpoint}" + echo "CPLD version ${cpld_ver}" + echo "${cpld_ver}" > "${VER_ENV_FILE}" + + return 0 +} + +# Exit without running main() if sourced +return 0 2>/dev/null + +main "$@" diff --git a/meta-quanta/meta-gbs/recipes-gbs/cpld-ver-check/gbs-cpld-ver-check.bb b/meta-quanta/meta-gbs/recipes-gbs/cpld-ver-check/gbs-cpld-ver-check.bb new file mode 100644 index 000000000..afe91fc60 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/cpld-ver-check/gbs-cpld-ver-check.bb @@ -0,0 +1,25 @@ +DESCRIPTION = "Report CPLD Version" +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit systemd + +SRC_URI = " file://cpld_version.sh \ + file://cpld-version.service \ + " + +S = "${WORKDIR}" + +DEPENDS = "systemd" +RDEPENDS_${PN} = "bash" + +SYSTEMD_SERVICE_${PN} = "cpld-version.service" + +do_install() { + install -d ${D}${bindir} + install -m 0755 ${S}/cpld_version.sh ${D}${bindir}/ + + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${S}/cpld-version.service ${D}${systemd_system_unitdir} +} diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/bios-update.sh b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/bios-update.sh new file mode 100644 index 000000000..3a215fa50 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/bios-update.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# Copyright 2020 Google LLC +# Copyright 2020 Quanta Computer Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Global variables + +# GPIO to control the host SPI mux +SPI_SW_SELECT=169 + +# Kernel control string for bind/unbind +KERNEL_FIU_ID="c0000000.fiu" + +# Kernel sysfs path for bind/unbind +KERNEL_SYSFS_FIU="/sys/bus/platform/drivers/NPCM-FIU" + +IMAGE_FILE="/tmp/image-bios" + +# Taken from /run/initramfs/update +# Given label name, return mtd node. e.g. `findmtd bmc` returns 'mtd0' +findmtd() { + m=$(grep -xl "$1" /sys/class/mtd/*/name) + m=${m%/name} + m=${m##*/} + echo $m +} + +cleanup() { + if [ -d "${KERNEL_SYSFS_FIU}/${KERNEL_FIU_ID}" ]; then + echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/unbind + fi + echo low > /sys/class/gpio/gpio${SPI_SW_SELECT}/direction # Switch mux to host + rm -f ${IMAGE_FILE} +} +trap cleanup EXIT SIGHUP SIGINT SIGTERM + +main() { + if [ ! -f ${IMAGE_FILE} ]; then + echo "Invalid bios image file!" + exit 1 + fi + + echo "Starting bios update..." + if [ ! -d "/sys/class/gpio/gpio${SPI_SW_SELECT}" ]; then + echo "${SPI_SW_SELECT}" > /sys/class/gpio/export + fi + + echo high > /sys/class/gpio/gpio${SPI_SW_SELECT}/direction # Switch mux to BMC + + if [ -d "${KERNEL_SYSFS_FIU}/${KERNEL_FIU_ID}" ]; then + echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/unbind + fi + echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/bind + + # BIOS flash is labelled 'pnor' + pnor_mtd=$(findmtd pnor) + if [ -z "${pnor_mtd}" ]; then + echo "Cannot find bios flash mtd partition!" + exit 1 + fi + + flashcp -v $IMAGE_FILE /dev/"${pnor_mtd}" + if [ $? -eq 0 ]; then + echo "bios update successfully..." + else + echo "bios update failed..." + exit 1 + fi +} +# Exit without running main() if sourced +return 0 2>/dev/null + +main "$@" diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/bios-verify.sh b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/bios-verify.sh new file mode 100644 index 000000000..3da25e483 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/bios-verify.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +# Copyright (c) 2019-present Lenovo +# Copyright (c) 2020 Quanta Computer Inc. +# Licensed under BSD-3, see COPYING.BSD file for details. + +IMAGE_FILE="/tmp/bios-image" +SIG_FILE="/tmp/bmc.sig" +BURN_IMAGE="/tmp/image-bios" +sha256_image="FFFF" +sha256_file="EEEE" + +echo "Verify bios image..." + +if [ -e $IMAGE_FILE ] && [ -e $SIG_FILE ]; +then + sha256_image=`sha256sum "$IMAGE_FILE" | awk '{print $1}'` + sha256_file=`awk '{print $1}' $SIG_FILE` +fi + +if [[ $sha256_image != $sha256_file ]]; +then + echo "bios image verify fail." + rm -f $IMAGE_FILE + echo "Remove bios image" + exit 1 +else + echo "bios image verify ok." + mv $IMAGE_FILE $BURN_IMAGE + rm -f $SIG_FILE + exit 0 +fi diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/config-bios.json b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/config-bios.json new file mode 100644 index 000000000..efbe6f830 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/config-bios.json @@ -0,0 +1,20 @@ +[{ + "blob": "/flash/bios", + "handler": { + "type": "file", + "path": "/tmp/bios-image" + }, + "actions": { + "preparation": { + "type": "skip" + }, + "verification": { + "type": "systemd", + "unit": "phosphor-ipmi-flash-bios-verify.service" + }, + "update": { + "type": "systemd", + "unit": "phosphor-ipmi-flash-bios-update.service" + } + } +}] diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/phosphor-ipmi-flash-bios-update.service b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/phosphor-ipmi-flash-bios-update.service new file mode 100644 index 000000000..a08816a4c --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/phosphor-ipmi-flash-bios-update.service @@ -0,0 +1,9 @@ +[Unit] +Description=Phosphor-ipmi-flash update BIOS service + +[Service] +ExecStart=/usr/bin/bios-update.sh +Type=oneshot + +[Install] +WantedBy=phosphor-ipmi-flash-bios-update.target diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/phosphor-ipmi-flash-bios-verify.service b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/phosphor-ipmi-flash-bios-verify.service new file mode 100644 index 000000000..af0e196b4 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/files/phosphor-ipmi-flash-bios-verify.service @@ -0,0 +1,9 @@ +[Unit] +Description=Phosphor-ipmi-flash verify BIOS service + +[Service] +ExecStart=/usr/bin/bios-verify.sh +Type=oneshot + +[Install] +WantedBy=phosphor-ipmi-flash-bios-verify.target diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/gbs-bios-update.bb b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/gbs-bios-update.bb new file mode 100644 index 000000000..32b9d512b --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-bios-update/gbs-bios-update.bb @@ -0,0 +1,39 @@ +PR = "r1" +LICENSE = "Apache-2.0 & BSD-3-Clause" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10 \ + file://${COREBASE}/meta/files/common-licenses/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9 \ + " + +inherit systemd +inherit obmc-phosphor-systemd + + +DEPENDS += "systemd" +DEPENDS += "phosphor-ipmi-flash" +RDEPENDS_${PN} += "bash" + +SRC_URI += " file://bios-verify.sh \ + file://bios-update.sh \ + file://phosphor-ipmi-flash-bios-verify.service \ + file://phosphor-ipmi-flash-bios-update.service \ + file://config-bios.json \ + " + +FILES_${PN} += "${datadir}/phosphor-ipmi-flash/config-bios.json" + +do_install() { + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/bios-verify.sh ${D}${bindir}/ + install -m 0755 ${WORKDIR}/bios-update.sh ${D}${bindir}/ + + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/phosphor-ipmi-flash-bios-verify.service ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/phosphor-ipmi-flash-bios-update.service ${D}${systemd_system_unitdir} + + install -d ${D}${datadir}/phosphor-ipmi-flash + install -m 0644 ${WORKDIR}/config-bios.json ${D}${datadir}/phosphor-ipmi-flash +} + + +SYSTEMD_PACKAGES = "${PN}" +SYSTEMD_SERVICE_${PN} = "phosphor-ipmi-flash-bios-verify.service phosphor-ipmi-flash-bios-update.service" diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/files/bmc-verify.sh b/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/files/bmc-verify.sh new file mode 100644 index 000000000..bbaf15d7d --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/files/bmc-verify.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +sigfile="/tmp/bmc.sig" +imagebmc="/run/initramfs/image-bmc" +bmcimage="/run/initramfs/bmc-image" +publickey="/etc/activationdata/OpenBMC/publickey" +bmclog="/tmp/update-bmc.log" + +if [ -f $publickey ];then + r="$(openssl dgst -verify $publickey -sha256 -signature $sigfile $bmcimage)" + echo "$r" > $bmclog + if [[ "Verified OK" == "$r" ]]; then + mv $bmcimage $imagebmc + rm -f $sigfile + exit 0 + else + exit 1 + fi +else + echo "No $publickey file" > $bmclog + exit 1 +fi diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/files/config-bmc.json b/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/files/config-bmc.json new file mode 100644 index 000000000..16c7151ed --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/files/config-bmc.json @@ -0,0 +1,21 @@ +[{ + "blob": "/flash/image", + "handler": { + "type": "file", + "path": "/run/initramfs/bmc-image" + }, + "actions": { + "preparation": { + "type": "skip" + }, + "verification": { + "type": "systemd", + "unit": "phosphor-ipmi-flash-bmc-verify.service" + }, + "update": { + "type": "systemd", + "unit": "reboot.target", + "mode": "replace-irreversibly" + } + } +}] diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/files/phosphor-ipmi-flash-bmc-verify.service b/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/files/phosphor-ipmi-flash-bmc-verify.service new file mode 100644 index 000000000..574b318ef --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/files/phosphor-ipmi-flash-bmc-verify.service @@ -0,0 +1,9 @@ +[Unit] +Description=Phosphor-ipmi-flash bmc verify service + +[Service] +ExecStart=/usr/bin/bmc-verify.sh +Type=oneshot + +[Install] +WantedBy=phosphor-ipmi-flash-bmc-verify.target diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/gbs-bmc-update.bb b/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/gbs-bmc-update.bb new file mode 100644 index 000000000..a177586ca --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-bmc-update/gbs-bmc-update.bb @@ -0,0 +1,34 @@ +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 + + +SRC_URI = " file://phosphor-ipmi-flash-bmc-verify.service \ + file://bmc-verify.sh \ + file://config-bmc.json \ + " + +FILES_${PN} += "${datadir}/phosphor-ipmi-flash/config-bmc.json" + +DEPENDS += "systemd" +DEPENDS += "phosphor-ipmi-flash" +RDEPENDS_${PN} = "bash" + +do_install() { + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/bmc-verify.sh ${D}${bindir}/ + + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/phosphor-ipmi-flash-bmc-verify.service ${D}${systemd_system_unitdir} + + install -d ${D}${datadir}/phosphor-ipmi-flash + install -m 0644 ${WORKDIR}/config-bmc.json ${D}${datadir}/phosphor-ipmi-flash +} + + +SYSTEMD_PACKAGES = "${PN}" +SYSTEMD_SERVICE_${PN} = "phosphor-ipmi-flash-bmc-verify.service" diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-fan-fail/files/gbs-detect-fan-fail.service b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-fan-fail/files/gbs-detect-fan-fail.service new file mode 100644 index 000000000..ecdc95399 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-fan-fail/files/gbs-detect-fan-fail.service @@ -0,0 +1,11 @@ +[Unit] +Description=Detect Fan Fail Manager +After=phosphor-pid-control.service + +[Service] +ExecStart=/usr/bin/gbs-detect-fan-fail.sh +Restart=always +StandardOutput=syslog + +[Install] +WantedBy=multi-user.target diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-fan-fail/files/gbs-detect-fan-fail.sh b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-fan-fail/files/gbs-detect-fan-fail.sh new file mode 100644 index 000000000..56ae7bbc5 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-fan-fail/files/gbs-detect-fan-fail.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +## + # This script is to handle fan fail condition which is described below. + # Fan fail means one fan RPM is under its CriticalLow. If BMC encounters + # such situation, then sets other fans to full speed. + # + +# get fan state +function get_fan_state() { + get_property_path='xyz.openbmc_project.Sensor.Threshold.Critical CriticalAlarmLow' + fan_state="$(busctl get-property $1 $2 $get_property_path | awk '{print $2}')" + echo "$fan_state" +} + +# check fan fail +function is_fan_fail() { + fan_state=("$@") + + for i in "${fan_state[@]}" + do + if [ ! -z "$i" ] + then + if [ $i == "true" ] + then + echo 1 + return + fi + fi + done + echo 0 +} + +fan_tach_path=( '/xyz/openbmc_project/sensors/fan_tach/fan0' + '/xyz/openbmc_project/sensors/fan_tach/fan1' + '/xyz/openbmc_project/sensors/fan_tach/fb_fan0' + '/xyz/openbmc_project/sensors/fan_tach/fb_fan1' + '/xyz/openbmc_project/sensors/fan_tach/fb_fan2' + ) + +check_fail_flag=0 +is_fan_fail_flag=0 +current_fan_state=() + +while true +do + for i in ${!fan_tach_path[@]} + do + mapper wait ${fan_tach_path[$i]} + hwmon_path="$(mapper get-service ${fan_tach_path[0]})" + current_fan_state[$i]=$(get_fan_state $hwmon_path ${fan_tach_path[$i]}) + done + + is_fan_fail_flag=$(is_fan_fail "${current_fan_state[@]}") + + # if fan fails then set all fans to full speed + if [ $is_fan_fail_flag -eq 1 ] && [ $check_fail_flag -eq 0 ] + then + check_fail_flag=1 + systemctl stop phosphor-pid-control.service + + # fans recover to normal state + elif [ $is_fan_fail_flag -eq 0 ] && [ $check_fail_flag -eq 1 ] + then + check_fail_flag=0 + systemctl restart phosphor-pid-control.service + fi + + sleep 2 +done diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-fan-fail/gbs-detect-fan-fail.bb b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-fan-fail/gbs-detect-fan-fail.bb new file mode 100644 index 000000000..5befec8d6 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-fan-fail/gbs-detect-fan-fail.bb @@ -0,0 +1,25 @@ +SUMMARY = "OpenBMC Quanta Detect Fan Fail Service" +DESCRIPTION = "OpenBMC Quanta Detect Fan Fail Daemon." +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit systemd + +DEPENDS += "systemd" +RDEPENDS_${PN} += "bash" + +SRC_URI = " file://gbs-detect-fan-fail.sh \ + file://gbs-detect-fan-fail.service \ + " + +do_install() { + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/gbs-detect-fan-fail.sh ${D}${bindir}/ + + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/gbs-detect-fan-fail.service ${D}${systemd_system_unitdir} +} + +SYSTEMD_PACKAGES = "${PN}" +SYSTEMD_SERVICE_${PN} = "gbs-detect-fan-fail.service" diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-gpio-present/files/detect-gpio-present.service b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-gpio-present/files/detect-gpio-present.service new file mode 100644 index 000000000..982ae6f5a --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-gpio-present/files/detect-gpio-present.service @@ -0,0 +1,12 @@ +[Unit] +Description=Detect GPIO Present Manager +After=phosphor-gpio-presence@.service +Wants=phosphor-gpio-presence@.service + +[Service] +ExecStart=/usr/bin/detect-gpio-present.sh +StandardOutput=syslog +Type=simple + +[Install] +WantedBy=multi-user.target diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-gpio-present/files/detect-gpio-present.sh b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-gpio-present/files/detect-gpio-present.sh new file mode 100644 index 000000000..2bbe46e84 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-gpio-present/files/detect-gpio-present.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +SERVICE_NAME="xyz.openbmc_project.Inventory.Manager" +PRESENT_OBJPATH=("/xyz/openbmc_project/inventory/system/chassis/cable/ss_cab0_prsnt" +"/xyz/openbmc_project/inventory/system/chassis/cable/ss_cab1_prsnt" +"/xyz/openbmc_project/inventory/system/chassis/cable/ss_cab2_prsnt" +"/xyz/openbmc_project/inventory/system/chassis/cable/ss_cab3_prsnt" +"/xyz/openbmc_project/inventory/system/chassis/cable/hsbp_cab_prsnt" +"/xyz/openbmc_project/inventory/system/chassis/cable/fanbd_cab_prsnt" +"/xyz/openbmc_project/inventory/system/chassis/cable/bp12v_cab_prsnt" +"/xyz/openbmc_project/inventory/system/chassis/entity/sata0_prsnt" +"/xyz/openbmc_project/inventory/system/chassis/entity/pe_slot0_prsnt" +"/xyz/openbmc_project/inventory/system/chassis/entity/pe_slot1_prsnt") +INTERFACE_NAME="xyz.openbmc_project.Inventory.Item" + +IPMI_LOG_SERVICE="xyz.openbmc_project.Logging.IPMI" +IPMI_LOG_OBJPATH="/xyz/openbmc_project/Logging/IPMI" +IPMI_LOG_INTERFACE="xyz.openbmc_project.Logging.IPMI" +IPMI_LOG_FUNCT="IpmiSelAdd" +IPMI_LOG_PARA_FORMAT="ssaybq" #5 parameters, s : string, s : string, ay : byte array, b : boolean, y : UINT16 +LOG_ERR="Configuration Error(Incorrect_interconnection)" +LOG_EVENT_DATA="3 0x01 0xff 0xfe" +LOG_ASSERT_FLAG="true" +LOG_DEASSERT_FLAG="false" +LOG_GENID_FLAG="0x0020" +present_state=("true" "true" "true" "true" "true" "true" "true" "true" "true" "true") + +while true; do + for i in ${!PRESENT_OBJPATH[@]} + do + mapper wait ${PRESENT_OBJPATH[$i]} + boot_status="$(busctl get-property $SERVICE_NAME ${PRESENT_OBJPATH[$i]} $INTERFACE_NAME Present | awk '{print $2}')" + + if [ $boot_status == "false" ] && [ ${present_state[$i]} == "true" ];then + echo "Update cable $(($i+1)) state." + present_state[$i]="false" + busctl call $IPMI_LOG_SERVICE $IPMI_LOG_OBJPATH $IPMI_LOG_INTERFACE $IPMI_LOG_FUNCT $IPMI_LOG_PARA_FORMAT "$LOG_ERR" ${PRESENT_OBJPATH[$i]} $LOG_EVENT_DATA $LOG_ASSERT_FLAG $LOG_GENID_FLAG + elif [ $boot_status == "true" ] && [ ${present_state[$i]} == "false" ];then + echo "Update cable $(($i+1)) state." + present_state[$i]="true" + busctl call $IPMI_LOG_SERVICE $IPMI_LOG_OBJPATH $IPMI_LOG_INTERFACE $IPMI_LOG_FUNCT $IPMI_LOG_PARA_FORMAT "$LOG_ERR" ${PRESENT_OBJPATH[$i]} $LOG_EVENT_DATA $LOG_DEASSERT_FLAG $LOG_GENID_FLAG + fi + done + sleep 1 +done + +exit 0 diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-gpio-present/gbs-detect-gpio-present.bb b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-gpio-present/gbs-detect-gpio-present.bb new file mode 100644 index 000000000..3e1a6d8ac --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-detect-gpio-present/gbs-detect-gpio-present.bb @@ -0,0 +1,25 @@ +SUMMARY = "OpenBMC Quanta Detect Present Service" +DESCRIPTION = "OpenBMC Quanta Detect Present Daemon." +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit systemd + +DEPENDS += "systemd" +RDEPENDS_${PN} += "bash" + +SRC_URI = " file://detect-gpio-present.sh \ + file://detect-gpio-present.service \ + " + +do_install() { + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/detect-gpio-present.sh ${D}${bindir}/ + + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/detect-gpio-present.service ${D}${systemd_system_unitdir} +} + +SYSTEMD_PACKAGES = "${PN}" +SYSTEMD_SERVICE_${PN} = "detect-gpio-present.service" diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-ipmi-entity-association-map/files/entity_association_map.json b/meta-quanta/meta-gbs/recipes-gbs/gbs-ipmi-entity-association-map/files/entity_association_map.json new file mode 100644 index 000000000..f4e453a9a --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-ipmi-entity-association-map/files/entity_association_map.json @@ -0,0 +1,29 @@ +{ + "system_board": [ + {"instance": 1, "name": "/"}, + {"instance": 28, "name": "/i2cool_0"}, + {"instance": 29, "name": "/i2cool_1"}, + {"instance": 30, "name": "/i2cool_2"} + ], + "system_internal_expansion_board": [ + {"instance": 1, "name": "/"} + ], + "power_system_board": [ + {"instance": 1, "name": "/"} + ], + "add_in_card": [ + {"instance": 0, "name": "/PE0"}, + {"instance": 1, "name": "/PE1"} + ], + "fan": [ + {"instance": 0, "name": "/fan0"}, + {"instance": 1, "name": "/fan1"}, + {"instance": 2, "name": "/fb_fan0"}, + {"instance": 3, "name": "/fb_fan1"}, + {"instance": 4, "name": "/fb_fan2"} + ], + "cooling_unit": [ + {"instance": 0, "name": "/ZONE0"}, + {"instance": 1, "name": "/ZONE1"} + ] +} diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-ipmi-entity-association-map/gbs-ipmi-entity-association-map.bb b/meta-quanta/meta-gbs/recipes-gbs/gbs-ipmi-entity-association-map/gbs-ipmi-entity-association-map.bb new file mode 100644 index 000000000..8b5551e79 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-ipmi-entity-association-map/gbs-ipmi-entity-association-map.bb @@ -0,0 +1,16 @@ +SUMMARY = "GBS IPMI Entity association mapping." +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +SRC_URI += "file://entity_association_map.json" + +FILES_${PN} = " \ + ${datadir}/ipmi-entity-association/entity_association_map.json \ + " + +do_install() { + install -d ${D}${datadir}/ipmi-entity-association + install -m 0644 -D ${WORKDIR}/entity_association_map.json \ + ${D}${datadir}/ipmi-entity-association/entity_association_map.json +} diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-nvme-pwr-ctrl/gbs-nvme-pwr-ctrl.bb b/meta-quanta/meta-gbs/recipes-gbs/gbs-nvme-pwr-ctrl/gbs-nvme-pwr-ctrl.bb new file mode 100644 index 000000000..a3f0c58d9 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-nvme-pwr-ctrl/gbs-nvme-pwr-ctrl.bb @@ -0,0 +1,19 @@ +SUMMARY = "NVMe Drives Power Control" +DESCRIPTION = "Daemon to monitor and control the power of NVMe drives" +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit meson pkgconfig +inherit systemd + +DEPENDS += "sdbusplus" +DEPENDS += "boost" +DEPENDS += "libgpiod" + +SRC_URI = "git://github.com/quanta-bmc/nvme-power-control;protocol=git" +SRCREV = "f7d2dbd6b48f3992d4a2fb1c0fe2afd746b8428a" + +S = "${WORKDIR}/git" + +SYSTEMD_SERVICE_${PN} = "xyz.openbmc_project.Control.Nvme.Power.service" diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-gpio-common.sh b/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-gpio-common.sh new file mode 100644 index 000000000..55f631a5d --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-gpio-common.sh @@ -0,0 +1,165 @@ +#!/bin/bash +# Copyright 2020 Google LLC +# Copyright 2020 Quanta Computer Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Common GPIO functions. + +# Map names of GPIOs to GPIO number +declare -A GPIO_NAMES_TO_NUMBER=( + ['RST_BMC_PHY_N']=15 + ['BMC_BRD_REV_ID6']=37 + ['BMC_BRD_REV_ID5']=38 + ['BMC_BRD_SKU_ID3']=39 + ['BMC_BRD_SKU_ID2']=40 + ['FM_BMC_CPU_UART_EN']=76 + ['RST_BMC_RSMRST_N']=87 + ['RST_KBRST_BMC_CPLD_N']=94 + ['FAN_BRD_REV_ID0']=122 + ['FAN_BRD_REV_ID1']=123 + ['HSBP_BRD_REV_ID3']=124 + ['HSBP_BRD_REV_ID2']=125 + ['HSBP_BRD_REV_ID1']=126 + ['BMC_BRD_REV_ID0']=136 + ['BMC_BRD_REV_ID1']=137 + ['BMC_BRD_REV_ID2']=138 + ['BMC_BRD_REV_ID3']=139 + ['BMC_BRD_REV_ID4']=140 + ['BMC_BRD_SKU_ID0']=141 + ['BMC_BRD_SKU_ID1']=142 + ['HDD_PRSNT_N']=160 + ['SPI_SW_SELECT']=169 + ['BMC_BRD_REV_ID7']=194 + ['HSBP_BRD_REV_ID0']=196 +) + +# 1 is active_low 0 is active_high +declare -A GPIO_NAMES_TO_ACTIVE_LOW=( + ['RST_BMC_PHY_N']=1 + ['BMC_BRD_REV_ID6']=0 + ['BMC_BRD_REV_ID5']=0 + ['BMC_BRD_SKU_ID3']=0 + ['BMC_BRD_SKU_ID2']=0 + ['FM_BMC_CPU_UART_EN']=0 + ['RST_BMC_RSMRST_N']=1 + ['RST_KBRST_BMC_CPLD_N']=1 + ['FAN_BRD_REV_ID0']=0 + ['FAN_BRD_REV_ID1']=0 + ['HSBP_BRD_REV_ID3']=0 + ['HSBP_BRD_REV_ID2']=0 + ['HSBP_BRD_REV_ID1']=0 + ['BMC_BRD_REV_ID0']=0 + ['BMC_BRD_REV_ID1']=0 + ['BMC_BRD_REV_ID2']=0 + ['BMC_BRD_REV_ID3']=0 + ['BMC_BRD_REV_ID4']=0 + ['BMC_BRD_SKU_ID0']=0 + ['BMC_BRD_SKU_ID1']=0 + ['HDD_PRSNT_N']=1 + ['SPI_SW_SELECT']=0 + ['BMC_BRD_REV_ID7']=0 + ['HSBP_BRD_REV_ID0']=0 +) + +################################################## +# Initializes the gpio state +# This operation is idempotent and can be applied +# repeatedly to the same gpio. It will make sure the +# gpio ends up in the initialized state even if it +# was. +# Arguments: +# $1: GPIO name +# Return: +# 0 if success, non-zero if error +################################################## +init_gpio() { + if (( $# != 1 )); then + echo "Usage: init_gpio name" >&2 + return 1 + fi + + local name=$1 + + local number=${GPIO_NAMES_TO_NUMBER["${name}"]} + if [[ -z ${number} ]]; then + echo "Missing number info for: ${name}" >&2 + return 2 + fi + + local active_low=${GPIO_NAMES_TO_ACTIVE_LOW["${name}"]} + if [[ -z ${active_low} ]]; then + echo "Missing active_low info for: ${name}" >&2 + return 2 + fi + + if [[ ! -e "/sys/class/gpio/gpio${number}" ]]; then + echo "${number}" >'/sys/class/gpio/export' + fi + echo "${active_low}" >"/sys/class/gpio/gpio${number}/active_low" +} + +################################################## +# Set output GPIO direction. +# Arguments: +# $1: GPIO name +# $2: GPIO direction, "high" or "low" +# Return: +# 0 if success, non-zero if error +################################################## +set_gpio_direction() { + if (( $# != 2 )); then + echo 'Usage: set_gpio_direction name direction' >&2 + return 1 + fi + + local name=$1 + local direction=$2 + + local number=${GPIO_NAMES_TO_NUMBER["${name}"]} + if [[ -z ${number} ]]; then + echo "Missing number info for: ${name}" >&2 + return 2 + fi + + init_gpio "${name}" || return + echo "${direction}" >"/sys/class/gpio/gpio${number}/direction" + echo "Set gpio ${name} #${number} to direction ${direction}" >&2 +} + +################################################## +# Get GPIO value +# Arguments: +# $1: GPIO name +# Return: +# 0 if success, non-zero if error +# stdout: The value of the gpio +################################################## +get_gpio_value() { + if (( $# != 1 )); then + echo 'Usage: get_gpio_value name' >&2 + return 1 + fi + + local name=$1 + + local number=${GPIO_NAMES_TO_NUMBER["${name}"]} + if [[ -z ${number} ]]; then + echo "Missing number info for: ${name}" >&2 + return 2 + fi + + init_gpio "${name}" || return + cat "/sys/class/gpio/gpio${number}/value" +} diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-sysinit.service b/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-sysinit.service new file mode 100644 index 000000000..645136b85 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-sysinit.service @@ -0,0 +1,13 @@ +[Unit] +Description = Initialization for GBS boot up +Wants=mapper-wait@-xyz-openbmc_project-inventory.service +After=mapper-wait@-xyz-openbmc_project-inventory.service +Wants=mapper-wait@-xyz-openbmc_project-control-nvme.service +After=mapper-wait@-xyz-openbmc_project-control-nvme.service + +[Service] +Type=oneshot +ExecStart=/usr/bin/gbs-sysinit.sh + +[Install] +WantedBy=multi-user.target diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-sysinit.sh b/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-sysinit.sh new file mode 100644 index 000000000..68adfedef --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-sysinit.sh @@ -0,0 +1,272 @@ +#!/bin/bash +# Copyright 2020 Google LLC +# Copyright 2020 Quanta Computer Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +source /usr/libexec/gbs-gpio-common.sh + +WD1RCR_ADDR=0xf080103c +CORSTC_ADDR=0xf080105c +BOARD_VER="" # Set by check_board_ver +pe_eeprom_addr=( 50 54 ) + +SERVICE_NAME="xyz.openbmc_project.Inventory.Manager" +INTERFACE_NAME="xyz.openbmc_project.Inventory.Item" + +PE_PRESENT_OBJPATH=("/xyz/openbmc_project/inventory/system/chassis/entity/pe_slot0_prsnt" +"/xyz/openbmc_project/inventory/system/chassis/entity/pe_slot1_prsnt") +SATA0_PRESENT_OBJPATH="/xyz/openbmc_project/inventory/system/chassis/entity/sata0_prsnt" + +set_gpio_persistence() { + reg_val=$(devmem ${WD1RCR_ADDR} 32) + # Clear bit 16-23 to perserve all GPIO states across warm resets + reg_val=$(printf "0x%08x" $((reg_val & ~0xff0000))) + echo "Setting WD1RCR_ADDR to ${reg_val}" + devmem "${WD1RCR_ADDR}" 32 "${reg_val}" + + reg_val=$(devmem ${CORSTC_ADDR} 32) + # Clear bit 16-23 of CORSTC + reg_val=$(printf "0x%08x" $((reg_val & ~0xff0000))) + echo "Setting CORSTC_ADDR to ${reg_val}" + devmem "${CORSTC_ADDR}" 32 "${reg_val}" +} + +get_board_rev_id() { + echo $(get_gpio_value 'BMC_BRD_REV_ID7')\ + $(get_gpio_value 'BMC_BRD_REV_ID6')\ + $(get_gpio_value 'BMC_BRD_REV_ID5')\ + $(get_gpio_value 'BMC_BRD_REV_ID4')\ + $(get_gpio_value 'BMC_BRD_REV_ID3')\ + $(get_gpio_value 'BMC_BRD_REV_ID2')\ + $(get_gpio_value 'BMC_BRD_REV_ID1')\ + $(get_gpio_value 'BMC_BRD_REV_ID0')\ + | sed 's/ //g' > ~/board_rev_id.txt +} + +get_board_sku_id() { + echo $(get_gpio_value 'BMC_BRD_SKU_ID3')\ + $(get_gpio_value 'BMC_BRD_SKU_ID2')\ + $(get_gpio_value 'BMC_BRD_SKU_ID1')\ + $(get_gpio_value 'BMC_BRD_SKU_ID0')\ + | sed 's/ //g' > ~/board_sku_id.txt +} + +get_hsbp_board_rev_id() { + echo $(get_gpio_value 'HSBP_BRD_REV_ID3')\ + $(get_gpio_value 'HSBP_BRD_REV_ID2')\ + $(get_gpio_value 'HSBP_BRD_REV_ID1')\ + $(get_gpio_value 'HSBP_BRD_REV_ID0')\ + | sed 's/ //g' > ~/hsbp_board_rev_id.txt +} + +get_fan_board_rev_id() { + echo $(get_gpio_value 'FAN_BRD_REV_ID1')\ + $(get_gpio_value 'FAN_BRD_REV_ID0')\ + | sed 's/ //g' > ~/fan_board_rev_id.txt +} + +check_board_ver() { + # Sets BOARD_VER to either "PREPVT" or "PVT" + # + # BOARD_REV_ID[7:6] = + # 0x00 - EVT + # 0x01 - DVT + # 0x10 - PVT + # 0x11 - MP + + rev7_val=$(get_gpio_value 'BMC_BRD_REV_ID7') + if (( rev7_val == 0 )); then + echo "EVT/DVT rev!" + BOARD_VER="PREPVT" + else + echo "PVT/MP rev!" + BOARD_VER="PVT" + fi +} + +check_board_sku() { + sku1_val=$(get_gpio_value 'BMC_BRD_SKU_ID1') + if (( sku1_val == 1 )); then + echo "GBS SKU!" + BOARD_SKU="GBS" + else + echo "Other SKU!" + BOARD_SKU="TBD" + fi +} + +set_uart_en_low() { + # GPIO76 UART_EN polarity inverted between DVT/PVT + # Pin direction was set high in the kernel. + set_gpio_direction 'FM_BMC_CPU_UART_EN' low +} + +set_hdd_prsnt() { + # On PVT need to forward SATA0_PRSNT_N to HDD_PRSNT_N + # The signal is safe to set on DVT boards so just set universally. + sata_prsnt_n="$(busctl get-property $SERVICE_NAME ${SATA0_PRESENT_OBJPATH} \ + $INTERFACE_NAME Present)" + if [[ "$?" == "0" && ${sata_prsnt_n} == "b false" ]]; then + return 1 + fi + # sata_prsnt_n is active low => value "true" means low + if [[ ${sata_prsnt_n} == "b true" ]]; then + set_gpio_direction 'HDD_PRSNT_N' low + else + set_gpio_direction 'HDD_PRSNT_N' high + fi +} + +KERNEL_FIU_ID="c0000000.fiu" +KERNEL_SYSFS_FIU="/sys/bus/platform/drivers/NPCM-FIU" + +bind_host_mtd() { + set_gpio_direction 'SPI_SW_SELECT' high + if [[ -d ${KERNEL_SYSFS_FIU}/${KERNEL_FIU_ID} ]]; then + echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/unbind + fi + echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/bind +} + +unbind_host_mtd() { + if [[ -d ${KERNEL_SYSFS_FIU}/${KERNEL_FIU_ID} ]]; then + echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/unbind + fi + set_gpio_direction 'SPI_SW_SELECT' low +} +trap unbind_host_mtd EXIT SIGHUP SIGINT SIGTERM + +# Taken from /run/initramfs/update +# Given label name, return mtd node. e.g. `findmtd bmc` returns 'mtd0' +findmtd() { + m=$(grep -xl "$1" /sys/class/mtd/*/name) + m=${m%/name} + m=${m##*/} + echo $m +} + +verify_host_bios() { + echo "BIOS verification start!" + + # placeholder for verifying host BIOS. For now time BIOS read + # with dd + bind_host_mtd || { echo "Failed to bind FIU driver for host MTD"; return 1; } + + pnor_mtd=$(findmtd pnor) + [[ -z "${pnor_mtd}" ]] && { echo "Failed to find host MTD partition!"; return 1; } + + # Test timing by computing SHA256SUM. + sha256sum /dev/${pnor_mtd}ro + + echo "BIOS verification complete!" + unbind_host_mtd +} + +reset_phy() { + ifconfig eth1 down + set_gpio_direction 'RST_BMC_PHY_N' low + set_gpio_direction 'RST_BMC_PHY_N' high + ifconfig eth1 up +} + +parse_pe_fru() { + pe_fruid=3 + for i in {1..2}; + do + pe_prsnt_n="$(busctl get-property $SERVICE_NAME ${PE_PRESENT_OBJPATH[$(($i-1))]} \ + $INTERFACE_NAME Present)" + + if [[ "$?" == "0" && ${pe_prsnt_n} == "b false" ]]; then + pe_fruid=$(($pe_fruid+1)) + continue + fi + + # Output is the i2c bus number for the PCIE cards on PE0/PE1 + # i2c-0 -> i2c mux (addr: 0x71) -> PE0/PE1 + # PE0: channel 0 + # PE1: channel 1 + pe_fru_bus="$(ls -al /sys/bus/i2c/drivers/pca954x/0-0071/ | grep channel \ + | awk -F "/" '{print $(NF)}' | awk -F "-" '{print $2}' | sed -n "${i}p")" + + # If the PE FRU EEPROM syspath does not exist, create it ("24c02" is the + # EEPROM part number) and perform a phosphor-read-eeprom + for ((j=0; j < ${#pe_eeprom_addr[@]}; j++)); + do + i2cget -f -y $pe_fru_bus "0x${pe_eeprom_addr[$j]}" 0x01 > /dev/null 2>&1 + if [ $? -eq 0 ]; then + if [ ! -f "/sys/bus/i2c/devices/$pe_fru_bus-00${pe_eeprom_addr[$j]}/eeprom" ]; then + echo 24c02 "0x${pe_eeprom_addr[$j]}" > "/sys/bus/i2c/devices/i2c-$pe_fru_bus/new_device" + fi + pe_fru_bus="/sys/bus/i2c/devices/$pe_fru_bus-00${pe_eeprom_addr[$j]}/eeprom" + phosphor-read-eeprom --eeprom $pe_fru_bus --fruid $pe_fruid + break + fi + done + pe_fruid=$(($pe_fruid+1)) + done +} + +check_power_status() { + res0="$(busctl get-property -j xyz.openbmc_project.State.Chassis \ + /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis \ + CurrentPowerState | jq -r '.["data"]')" + echo $res0 +} + +main() { + get_board_rev_id + get_board_sku_id + get_hsbp_board_rev_id + get_fan_board_rev_id + + check_board_ver + if [[ "${BOARD_VER}" == "PREPVT" ]]; then + set_uart_en_low + fi + + check_board_sku + + set_hdd_prsnt + + reset_phy + + if [[ $(check_power_status) != \ + 'xyz.openbmc_project.State.Chassis.PowerState.On' ]]; then + verify_host_bios + + echo "Release host from reset!" >&2 + set_gpio_direction 'RST_BMC_RSMRST_N' high + set_gpio_direction 'RST_KBRST_BMC_CPLD_N' high + # TODO: remove the hack once kernel driver is ready + # Set the GPIO states to preserve across reboots + set_gpio_persistence + + echo "Starting host power!" >&2 + 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 + else + echo "Host is already running, doing nothing!" >&2 + fi + + parse_pe_fru +} + +# Exit without running main() if sourced +return 0 2>/dev/null + +main "$@" diff --git a/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/gbs-sysinit.bb b/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/gbs-sysinit.bb new file mode 100644 index 000000000..68a9cf181 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/gbs-sysinit.bb @@ -0,0 +1,31 @@ +SUMMARY = "Phosphor OpenBMC Quanta GBS System Initialization Service" +DESCRIPTION = "Phosphor OpenBMC Quanta GBS System Init" +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit systemd + +DEPENDS += "systemd" +RDEPENDS_${PN} += "bash" +RDEPENDS_${PN} += "libsystemd" +RDEPENDS_${PN} += "jq" + +SRC_URI = "file://gbs-sysinit.sh \ + file://gbs-gpio-common.sh \ + file://gbs-sysinit.service \ + " + +do_install () { + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/gbs-sysinit.sh ${D}${bindir}/ + + install -d ${D}${libexecdir} + install -m 0755 ${WORKDIR}/gbs-gpio-common.sh ${D}${libexecdir}/ + + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/gbs-sysinit.service ${D}${systemd_system_unitdir} +} + +SYSTEMD_PACKAGES = "${PN}" +SYSTEMD_SERVICE_${PN} = "gbs-sysinit.service" diff --git a/meta-quanta/meta-gbs/recipes-gbs/hotswap-power-cycle/files/hotswap-power-cycle.service b/meta-quanta/meta-gbs/recipes-gbs/hotswap-power-cycle/files/hotswap-power-cycle.service new file mode 100644 index 000000000..054b2fe6d --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/hotswap-power-cycle/files/hotswap-power-cycle.service @@ -0,0 +1,10 @@ +[Unit] +Description=Power Cycle by Hotswap Controller + +[Service] +Type=oneshot +EnvironmentFile=-/run/psu_timedelay +ExecStart=/usr/bin/tray_powercycle.sh + +[Install] +WantedBy=gbmc-psu-hardreset.target diff --git a/meta-quanta/meta-gbs/recipes-gbs/hotswap-power-cycle/files/tray_powercycle.sh b/meta-quanta/meta-gbs/recipes-gbs/hotswap-power-cycle/files/tray_powercycle.sh new file mode 100644 index 000000000..5cbf49bb5 --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/hotswap-power-cycle/files/tray_powercycle.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# PSU hard reset (power cycle) script. +# +# Power cycle the entire tray by setting the PSU hotswap reset (GPIO218) to high +# +# Global variable: PSU_HARDRESET_DELAY specifies the number of seconds to wait +# before pulling the trigger. If not specified or zero, the script power cycles +# immediately. +main() { + # Sleep PSU_HARDRESET_DELAY seconds + local psu_delay=$((PSU_HARDRESET_DELAY)) + if ((psu_delay > 0)); then + echo "Sleeping ${psu_delay} seconds before PSU hard reset!" + sleep "${psu_delay}" + fi + + gpioset gpiochip6 26=1 +} + +# Exit without running main() if sourced +return 0 2>/dev/null + +main "$@" diff --git a/meta-quanta/meta-gbs/recipes-gbs/hotswap-power-cycle/gbs-hotswap-power-cycle.bb b/meta-quanta/meta-gbs/recipes-gbs/hotswap-power-cycle/gbs-hotswap-power-cycle.bb new file mode 100644 index 000000000..6bf7bb69f --- /dev/null +++ b/meta-quanta/meta-gbs/recipes-gbs/hotswap-power-cycle/gbs-hotswap-power-cycle.bb @@ -0,0 +1,26 @@ +SUMMARY = "Power Cycle by Hotswap Controller" +DESCRIPTION = "Power Cycle by Hotswap Controller Daemon" +PR = "r1" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" + +inherit systemd + +DEPENDS += "systemd" +RDEPENDS_${PN} += "bash" + +SRC_URI = " file://hotswap-power-cycle.service \ + file://tray_powercycle.sh \ + " + +do_install() { + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/hotswap-power-cycle.service ${D}${systemd_system_unitdir} + + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/tray_powercycle.sh ${D}${bindir} +} + +SYSTEMD_PACKAGES = "${PN}" +SYSTEMD_SERVICE_${PN} = "hotswap-power-cycle.service" + |