#!/bin/bash
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

GPIODIR="/sys/class/gpio"
GPIOEXPORT="$GPIODIR/export"
SHADOW_GPIO=/tmp/gpionames
GPIOCLI_CMD=/usr/local/bin/gpiocli

# Name of ASPEED GPIO Controller, usually used by gpiocli command.
ASPEED_GPIO="aspeed-gpio"

gpio_dir() {
    echo "$GPIODIR/gpio$1"
}

gpio_name2value() {
    local first remaining base val
    remaining=$1
    base="${SHADOW_GPIO}/${remaining}"
    if [ -L "${base}" ]; then
        val=$(readlink -f ${base} 2>/dev/null)
        if [ -n "${val}" ]; then
            val=${val##*gpio}
            if [ -n "${val}" ]; then
                echo "$val"
                return
            fi
        fi
    fi
    val=0
    while [ -n "$remaining" ]; do
        first=${remaining:0:1}
        case "$first" in
            [[:lower:]])
                base=$(printf "%d" "'$first'")
                base=$((base - 96))
                val=$((val * 26 + base))
                ;;
            [[:upper:]])
                base=$(printf "%d" "'$first'")
                base=$((base - 64))
                val=$((val * 26 + base))
                ;;
            *)
                if [ $val -gt 0 ]; then
                    val=$((val-1))
                fi
                val=$((val * 8 + $remaining))
                break
                ;;
        esac
        remaining=${remaining:1}
    done
    echo "$val"
}

gpio_export() {
    local gpio
    gpio=$(gpio_name2value $1)
    dir=$(gpio_dir $gpio)
    if [ ! -d ${dir} ]; then
        echo $gpio > $GPIOEXPORT
    fi
    if [ $# -gt 1 ]; then
        if [ ! -d  $SHADOW_GPIO ]; then
            mkdir -p $SHADOW_GPIO
        fi
        ln -s $dir $SHADOW_GPIO/$2
    fi
}

gpio_export_by_name() {
    local chip=$1
    local name=$2
    local shadow=$3

    echo "exporting gpio (${chip}, ${name}), shadow=${shadow}"
    $GPIOCLI_CMD --chip ${chip} --pin-name ${name} --shadow ${shadow} export
}

gpio_export_by_offset() {
    local chip=$1
    local offset=$2
    local shadow=$3

    echo "exporting gpio (${chip}, ${offset}), shadow=${shadow}"
    $GPIOCLI_CMD --chip ${chip} --pin-offset ${offset} --shadow ${shadow} export
}

gpio_unexport() {
    local shadow=$1

    echo "unexporting gpio ${shadow}"
    $GPIOCLI_CMD --shadow ${shadow} unexport
}

gpio_set() {
    local gpio
    local val
    gpio=$(gpio_name2value $1)
    val=$2
    dir=$(gpio_dir $gpio)
    if [ ! -d ${dir} ]; then
        echo $gpio > $GPIOEXPORT
    fi
    if [ $val -eq 0 ]; then
        echo low > ${dir}/direction
    else
        echo high > ${dir}/direction
    fi
}

gpio_get() {
    local gpio
    local val
    local keepdirection
    gpio=$(gpio_name2value $1)
    dir=$(gpio_dir $gpio)
    keepdirection="$2"
    if [ ! -d ${dir} ]; then
        echo $gpio > $GPIOEXPORT
    fi
    if [ "$keepdirection" != "keepdirection" ]; then
        echo in > ${dir}/direction
    fi
    cat ${dir}/value
}

#
# Set gpio pin with the given value.
# $1 - GPIO pin shadow name
# $2 - GPIO value
#
gpio_set_value() {
    local shadow="$1"
    local value="$2"

    "${GPIOCLI_CMD}" --shadow "${shadow}" set-init-value "${value}"
}

#
# Get value of the given gpio pin.
# $1 - GPIO pin shadow name
#
gpio_get_value() {
    local shadow="$1"

    val=$("${GPIOCLI_CMD}" --shadow "${shadow}" get-value)
    if [ "$?" == "0" ]; then
        echo "${val}" | cut -d'=' -f2
    fi
}

#
# Set the GPIO pin with given direction.
# $1 - GPIO pin shadow name
# $2 - GPIO pin direction: "in" or "out"
#
gpio_set_direction() {
    local shadow="$1"
    local direction="$2"

    "${GPIOCLI_CMD}" --shadow "${shadow}" set-direction "${direction}"
}

#
# Get the direction of given GPIO pin.
# $1 - GPIO pin shadow name
#
gpio_get_direction() {
    local shadow="$1"

    dir=$("${GPIOCLI_CMD}" --shadow "${shadow}" get-direction)
    if [ "$?" == "0" ]; then
        echo "${dir}" | cut -d'=' -f2
    fi
}

#
# Lookup sysfs "gpiochip###" directory based on chip label.
# $1 - gpiochip label
#
gpiochip_lookup_by_label() {
    local input_label=${1}
    local label entry

    for entry in "${GPIODIR}"/gpiochip* ; do
        label=$(cat "${entry}/label")
        if [ "${label}" = "${input_label}" ]; then
            basename "$entry"
            return
        fi
    done
}

#
# Lookup sysfs "gpiochip###" directory based on i2c path (of the
# io expander).
# $1 - i2c device path in <bus-addr> format. For example: 30-0021
#
gpiochip_lookup_by_i2c_path() {
    local i2c_path=${1}
    local entry link_path

    for entry in "${GPIODIR}"/gpiochip* ; do
        link_path=$(readlink -f "$entry" 2>/dev/null)
        if [[ ${link_path} == *i2c*/${i2c_path}/* ]]; then
            basename "$entry"
            return
        fi
    done
}

#
# Get base pin number managed by the given gpio chip.
# $1 - gpiochip sysfs directory. For example, "gpiochip400".
#
gpiochip_get_base() {
    local chip=${1}
    local chip_dir="${GPIODIR}/${chip}"

    if [ -L ${chip_dir} ]; then
       cat ${chip_dir}/base
    fi
}


# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

SYSFS_I2C_ROOT="/sys/bus/i2c"
SYSFS_I2C_DEVICES="${SYSFS_I2C_ROOT}/devices"
SYSFS_I2C_DRIVERS="${SYSFS_I2C_ROOT}/drivers"

#
# Return the given i2c device's absolute sysfs path.
# $1 - i2c device in <bus>-00<add> format (for example 0-0050).
#
i2c_device_sysfs_abspath() {
    echo "${SYSFS_I2C_DEVICES}/${1}"
}

#
# instantiate an i2c device.
# $1 - parent bus number
# $2 - device address
# $3 - device name/type
#
i2c_device_add() {
    bus=$"$1"
    addr="$2"
    device="$3"
    echo "$device" "$addr" > "${SYSFS_I2C_DEVICES}/i2c-${bus}/new_device"
}

#
# delete an i2c device.
# $1 - parent bus number
# $2 - device address
#
i2c_device_delete() {
    bus=$"$1"
    addr="$2"
    echo "$addr" > "${SYSFS_I2C_DEVICES}/i2c-${bus}/delete_device"
}

#
# Create message-queue i2c slave backend for the given i2c master.
# $1 - i2c bus number
# $2 - slave device address
#
i2c_mslave_add() {
    bus=$1
    addr=$2

    addr=$((addr | 0x1000))
    i2c_device_add "$bus" "$addr" slave-mqueue
}

#
# instantiate an i2c-mux device and wait untill all its child buses
# are initialized before the function returns.
# $1 - parent bus number
# $2 - i2c-mux device address
# $3 - i2c-mux device name/type
# $4 - total number of channels provided by the i2c-mux
#
i2c_mux_add_sync() {
    bus="$1"
    addr="$2"
    name="$3"
    nchans="$4"

    i2c_device_add "$bus" "$addr" "$name"

    retry=0
    format_addr=$(printf "%04x" "$addr")
    dev_entry="${bus}-${format_addr}"
    nchans=$((nchans - 1))
    last_channel="${SYSFS_I2C_DEVICES}/${dev_entry}/channel-${nchans}"
    until [ -d "${last_channel}" ]; do
        usleep 10000 # sleep for 10 milliseconds

        retry=$((retry + 1))
        if [ "$retry" -ge 10 ]; then
            echo "failed to create child buses for i2c-mux $dev_entry!"
            return 1
        fi
    done

    return 0
}

#
# Lookup i2c driver based on device name.
# $1 - device name
#
i2c_driver_map() {
    local device_name=$1

    case ${device_name} in
        "24c64" | "24c32" | "24c16" | "24c08" | "24c04" | "24c02" | "24c01" | "24c00")
            echo "at24";;
        "adm1278")
            echo "adm1275";;
        "adm1266")
            echo "adm1266";;
        "tmp75" | "lm75" | "tmp1075")
            echo "lm75";;
        "tmp421" | "tmp422")
            echo "tmp421";;
        "pca9505" | "pca9534" | "pca9535")
            echo "pca953x";;
        "pca9548")
            echo "pca954x";;
        "pfe1100" | "pfe3000")
            echo "bel-pfe";;
        "fancpld")
            echo "fancpld";;
        "cmmcpld")
            echo "cmmcpld";;
        "mp2975" | "mp2978")
            echo "mp2975";;
        "lm25066")
            echo "lm25066";;
        "ucd90160" | "ucd90124")
            echo "ucd9000";;
        "xdpe132g5c")
            echo "xdpe132g5c";;
        "ir35215")
            echo "ir35215";;
        "xdpe12284")
            echo "xdpe12284";;
        "pxe1211")
            echo "pxe1610";;
        *)
            echo "";;
    esac
}

#
# Trigger driver binding manually
# $1 - driver name
# $2 - device path in <bus>-00<addr> format.
# $3 - retry count, optional argument (default 1: no retry).
#
i2c_bind_driver() {
    driver_name="$1"
    i2c_device="$2"
    driver_dir="${SYSFS_I2C_DRIVERS}/${driver_name}"

    if [ -n "$3" ]; then
        retries="$3"
    else
        retries=1
    fi

    if [ ! -d ${driver_dir} ]; then
        echo "unable to locate i2c driver ${driver_name} in sysfs"
        return 1
    fi

    retry=0
    while [ "$retry" -lt "$retries" ]; do
        if echo "${i2c_device}" > "${driver_dir}/bind"; then
            return 0
        fi

        usleep 50000  # sleep for 50 milliseconds
        retry=$((retry + 1))
    done

    return 1
}

#
# The function goes through all i2c devices and check if some devices
# are not claimed by drivers (due to scheduling delay, missing drivers,
# intermittent i2c transaction errors in device_probe() function, and
# etc.).
# $1 - "fix-binding" flag. Optional argument: if $1 is "fix-binding",
#      the function will try to lookup drivers and fix driver binding.
#      Otherwise, nothing is done for "missing-driver" devices.
# $2 - retry count. It defines number of retries in case of driver
#      binding failures.
#
i2c_check_driver_binding() {
    errors=0
    errors_fixed=0
    total_devs=0

    if [ -n "$1" ] && [ "$1" = "fix-binding" ]; then
        fix_binding=1
    fi
    if [ -n "$2" ]; then
        retries="$2"
    else
        retries=1
    fi

    echo "checking i2c driver binding status"
    for dev_path in "${SYSFS_I2C_DEVICES}"/*-00*; do
        total_devs=$((total_devs + 1))

        if [ -L "${dev_path}/driver" ]; then
            continue # bound to driver successfully
        fi

        errors=$((errors + 1))
        dev_uid=$(basename "$dev_path")
        dev_name=$(cat "${dev_path}/name")
        echo "${dev_uid} (${dev_name}) - no driver bound"

        # Try to manually bind the device.
        if [ -n "${fix_binding}" ]; then
            driver_name=$(i2c_driver_map "${dev_name}")
            if [ -z "${driver_name}" ]; then
                echo "unable to find driver for ${dev_uid}"
                continue
            fi

            echo "manually bind ${dev_uid} to driver ${driver_name}"
            if i2c_bind_driver "${driver_name}" "${dev_uid}" "$retries"; then
                errors_fixed=$((errors_fixed + 1))
            fi
        fi
    done

    # Dump driver binding summary.
    errors=$((errors - errors_fixed))
    sum_info="total ${total_devs} i2c devices checked"
    if [ ${errors} -eq 0 ]; then
        result_info="all bound to drivers"
    else
        result_info="${errors} devices without drivers"
    fi
    if [ "$errors_fixed" -gt 0 ]; then
        result_info="${result_info} ($errors_fixed manually fixed)"
    fi
    echo "${sum_info}: ${result_info}"
}


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          mount_data0
# Required-Start:    mountvirtfs
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Mount data0 partition from flash chip.
# Description:
### END INIT INFO

# shellcheck disable=SC1091
if [ -f /etc/default/rcS ]; then
    . /etc/default/rcS
fi

#
# The default filesystem type is jffs2, but people can override it by
# adding "mtd-ubifs" to MACHINE_FEATURES.
#
FLASH_FS_TYPE=jffs2

MOUNT_POINT="/mnt/data"

mtd_lookup_data_partition() {
    dev_data0=$(cat /proc/mtd |
                awk '{ if ($4 == "\"data0\"") print $1 }' |
                cut -d ':' -f 1)
    if [ -n "$dev_data0" ]; then
        echo "$dev_data0"
    else
        dev_dataro=$(cat /proc/mtd |
                     awk '{ if ($4 == "\"dataro\"") print $1 }' |
                     cut -d ':' -f 1)
        echo "$dev_dataro"
    fi
}

#
# Sanity check if directories and files are corrupted after mount. The
# function can be called regardless of fs type.
#
mnt_point_health_check() {
    mnt_error=0
    mnt_point="$1"

    #
    # Failing to list root directory is definitely not acceptable.
    #
    if ! ls "$mnt_point" > /dev/null 2>&1; then
        echo "$FLASH_FS_TYPE health check error: unable to list root directory!"
        mnt_error=$((mnt_error+1))
    fi

    #
    # We've seen several instances of corrupted /mnt/data/etc on Minipack
    # and CMM BMC: somehow /mnt/data/etc is interpreted as a regular file
    # instead of a directory, and people lost connection to BMC in this
    # condition because sshd cannot be started.
    #
    persist_etc="${mnt_point}/etc"
    if [ -e "$persist_etc" ] && [ ! -d "$persist_etc" ] ; then
        echo "$FLASH_FS_TYPE health check error: $persist_etc corrupted (not a directory)!"
        mnt_error=$((mnt_error+1))
    fi

    return "$mnt_error"
}

get_reboot_cause_addr() {
    data_type=$1
    soc_model=$(cat /etc/soc_model)

    if [ "$soc_model" == "SOC_MODEL_ASPEED_G6" ]; then
        # ast_g6
        # sram reboot base:     0x10015000
        # sram reboot offset:   0xC00
        # cmd offset:           0x4
        # sig offset:           0x8
        if [ "$data_type" == "cmd" ]; then
            echo "0x10015C04"
        elif [ "$data_type" == "sig" ]; then
            echo "0x10015C08"
        fi
    else
        # ast_g5 & ast_g4
        # sram reboot base:     0x1E721000
        # sram reboot offset:   0x200
        # reboot cmd offset:    0x4
        # sig offset:           0x8
        if [ "$data_type" == "cmd" ]; then
            echo "0x1E721204"
        elif [ "$data_type" == "sig" ]; then
            echo "0x1E721208"
        fi
    fi
}

is_ubifs_error_set() {
    BOOT_MAGIC="0xFB420054"
    reboot_sig_addr=$(get_reboot_cause_addr sig)
    reboot_sig_val=$(devmem $reboot_sig_addr 2>/dev/null)
    if [ "$reboot_sig_val" != "$BOOT_MAGIC" ]; then
        # Power on reset
        return 1
    fi

    # Read reboot command flags
    reboot_cmd_addr=$(get_reboot_cause_addr cmd)
    reboot_cmd_flags=$(devmem $reboot_cmd_addr 2>/dev/null)
    if [ "$((reboot_cmd_flags & 0x4))" -eq 0 ]; then
        # UBIFS_ERROR not set
        return 1
    fi

    # UBIFS_ERROR is set
    return 0
}

ubifs_format() {
    mtd_chardev="$1"
    ubi_dev="$2"

    if ubinfo "$ubi_dev" > /dev/null; then
        if ! ubidetach -p "$mtd_chardev"; then
            return 1
        fi
    fi

    if ! ubiformat -y "$mtd_chardev"; then
        return 1
    fi

    if ! ubiattach -p "$mtd_chardev"; then
        return 1
    fi

    if ! ubimkvol "$ubi_dev" -N data0 -m; then
        return 1
    fi
}

ubifs_mount() {
    ubi_vol="$1"
    mnt_point="$2"

    echo "ubifs_mount $ubi_vol to $mnt_point.."
    mount -t ubifs "$ubi_vol" "$mnt_point" -o sync,compr=zstd
}

do_mount_ubifs() {
    mtd_chardev="$1"
    mnt_point="$2"
    ubi_dev="/dev/ubi0"
    ubi_vol="${ubi_dev}_0"
    need_recovery=0

    #
    # Blindly load ubi module just in case it's compiled as a module.
    # Ignore modprobe failures and we will run more check later.
    #
    modprobe ubi mtd=data0 > /dev/null 2>&1

    #
    # Attached ubi device manually if ubi is compiled into kernel but
    # "ubi.mtd=data0" bootargs is not supplied.
    #
    if ! [ -e "$ubi_dev" ]; then
        ubiattach -p "$mtd_chardev"
        # Fall through regardless of attach results: we will start
        # filesystem recovery if the ubi volume doesn't show up after
        # attach.
    fi

    #
    # ubifs "recovery" is needed when:
    #   1) the mtd partition is never formatted, for example, when people
    #      migrate a BMC from jffs2 to ubifs for the first time.
    #   2) the mtd partition or ubi volume is corrupted for some reasons.
    #
    if is_ubifs_error_set; then
        echo "UBIFS ERROR flag is set, start recovery.."
        need_recovery=1
    elif [ -e "$ubi_vol" ]; then
        if ubifs_mount "$ubi_vol" "$mnt_point"; then
            echo "Check ubifs filesystem health on $ubi_vol.."

            if ! mnt_point_health_check "$mnt_point"; then
                need_recovery=$((need_recovery+1))
            fi

            if [ "$need_recovery" -gt 0 ]; then
                echo "ubifs health check failed. Unmount $ubi_vol and start recovery.."
                umount "$mnt_point"
                ubidetach -p "$mtd_chardev"
            else
                echo "ubifs health check passed: no error found."
            fi
        else
            echo "unable to mount $ubi_vol. Start recovery soon.."
            need_recovery=1
        fi
    else
        echo "$ubi_vol does not exist. Start recovery soon.."
        need_recovery=1
    fi

    if [ "$need_recovery" -gt 0 ]; then
        if ! ubifs_format "$mtd_chardev" "$ubi_dev"; then
            echo "ubifs_format failed. Exiting!"
            exit 1
        fi

        if ! ubifs_mount "$ubi_vol" "$mnt_point"; then
            echo "ubifs_mount failed after recovery. Exiting!"
            exit 1
        fi
    fi
}

jffs2_format() {
    mtd_chardev="$1"

    echo "Create jffs2 filesystem on $mtd_chardev.."
    flash_eraseall -j "$mtd_chardev"
}

jffs2_mount() {
    mtd_blkdev="$1"
    mnt_point="$2"

    echo "jffs2_mount $mtd_blkdev to $mnt_point.."
    mount -t jffs2 "$mtd_blkdev" "$mnt_point"
}

jffs2_health_check() {
    #
    # If JFFS2 prints below messages at mount time, then probably the
    # filesystem is corrupted. Although mount may still return "success",
    # the file structure/content can be corrupted in this case.
    # For details, please refer to:
    # http://www.linux-mtd.infradead.org/faq/jffs2.html
    #
    if dmesg | grep "jffs2.*: Magic bitmask.*not found" > /dev/null 2>&1; then
        echo "jffs2 health check error: <Magic bitmask not found> reported!"
        return 1
    fi

    return 0
}

do_mount_jffs2() {
    mtd_chardev="$1"
    mnt_point="$2"
    need_recovery=0

    #
    # "/proc/mtd" lists partitions using mtd#, but we need to use the
    # according "block" device (/dev/mtdblock#) due to mount.busybox
    # limitations.
    #
    mtd_blkdev=${mtd_chardev/mtd/mtdblock}

    if jffs2_mount "$mtd_blkdev" "$mnt_point"; then
        #
        # Wait a second to make sure filesystem is fully ready.
        #
        sleep 1
        echo "Check jffs2 filesystem health on $mtd_blkdev.."

        if ! jffs2_health_check; then
            need_recovery=$((need_recovery+1))
        fi
        if ! mnt_point_health_check "$mnt_point"; then
            need_recovery=$((need_recovery+1))
        fi

        if [ "$need_recovery" -gt 0 ]; then
            echo "jffs2 health check failed. Unmount $mtd_blkdev and start recovery.."
            umount "$mtd_blkdev"
        else
            echo "jffs2 health check passed: no error found."
        fi
    else
        echo "jffs2_mount $mtd_blkdev failed. Start recovery.."
        need_recovery=1
    fi

    if [ "$need_recovery" -gt 0 ]; then
        if ! jffs2_format "$mtd_chardev"; then
            echo "jffs2_format failed. Exiting!"
            exit 1
        fi

        if ! jffs2_mount "$mtd_blkdev" "$mnt_point"; then
            echo "jffs2_mount failed after recovery. Exiting!"
            exit 1
        fi
    fi
}

is_vboot_recovery_boot(){
   recv_boot=$(/usr/local/bin/vboot-util | awk -F: -e '/recovery_boot/{ print $2 }')
   test $(( "$recv_boot" )) -ne 0
}

if is_vboot_recovery_boot; then
    echo "Recovery boot, skip mounting /mnt/data"
    exit 1
fi

MTD_DATA_DEV=$(mtd_lookup_data_partition)
if [ -z "$MTD_DATA_DEV" ]; then
    echo "No data0/dataro partition found. $MOUNT_POINT not mounted."
    exit 1
fi

MTD_DATA_PATH="/dev/$MTD_DATA_DEV"
[ -d $MOUNT_POINT ] || mkdir -p $MOUNT_POINT

do_mount_$FLASH_FS_TYPE "$MTD_DATA_PATH" "$MOUNT_POINT"

: exit 0


#!/bin/sh
#
# Copyright 2018-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          mount_data1.sh
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Mount persistent storage (currently eMMC) to /mnt/data1
# Description:
### END INIT INFO

MOUNT_POINT="/mnt/data1"
if [ ! -d "$MOUNT_POINT" ]; then
    if ! output=$(mkdir -p "$MOUNT_POINT"); then
        echo "Error: failed to create $MOUNT_POINT directory:"
        echo "$output"
        exit 1
    fi
fi

/usr/local/bin/emmc_auto_mount.sh "$MOUNT_POINT"


# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

DEVMEM=/sbin/devmem

devmem_set_bit() {
    local addr
    local val
    addr=$1
    val=$($DEVMEM $addr)
    val=$((val | (0x1 << $2)))
    $DEVMEM $addr 32 $val
}

devmem_clear_bit() {
    local addr
    local val
    addr=$1
    val=$($DEVMEM $addr)
    val=$((val & ~(0x1 << $2)))
    $DEVMEM $addr 32 $val
}

#
# Test if the given bit is set in register <addr>
# $1 - register address
# $2 - bit position
#
devmem_test_bit() {
    local addr=$1
    local bitpos=$2
    local val

    val=$($DEVMEM $addr)
    val=$(((val >> $bitpos) & 0x1))

    if [ $val -eq 1 ]; then
        # 0 for true
        return 0
    else
        # 1 for false
        return 1
    fi
}

source "/usr/local/bin/shell-utils.sh"
source "/usr/local/bin/i2c-utils.sh"
source "/usr/local/bin/gpio-utils.sh"
source "/usr/local/bin/ast-utils.sh"

if [ -f "/usr/local/bin/soc-utils.sh" ]; then
    source "/usr/local/bin/soc-utils.sh"
fi

if [ -f "/usr/local/bin/board-utils.sh" ]; then
    source "/usr/local/bin/board-utils.sh"
fi


#Remove poweroff command from .bash
echo "Remove poweroff command from .bash"
rm /sbin/poweroff
rm /sbin/poweroff.sysvinit

#Copy modified inittab to change "init 0" action from shutdown to reboot
cp /usr/local/bin/revise_inittab /etc/inittab


#!/bin/sh

# set reboot_ongoing cache to notify other process
/usr/bin/kv set reboot_ongoing 1


#!/bin/sh

soc_model=$(cat /etc/soc_model 2>/dev/null)
sram_reboot="0x1e721204"
if [ "$soc_model" = "SOC_MODEL_ASPEED_G6" ]; then
    sram_reboot="0x10015c04"
fi

# flag for healthd logging reboot cause
val=$(devmem "$sram_reboot" 32 2>/dev/null)
devmem "$sram_reboot" 32 $((val | 0x101)) 2>/dev/null


#!/bin/sh
#
# Copyright 2020-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          setup_persist_log.sh
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Mount persistent storage (currently eMMC) to /var/log
# Description:
### END INIT INFO

MOUNT_POINT="/var/volatile/log/"
if [ ! -d "$MOUNT_POINT" ]; then
    if ! output=$(mkdir -p "$MOUNT_POINT"); then
        echo "Error: failed to create $MOUNT_POINT directory:"
        echo "$output"
        exit 1
    fi
fi

/usr/local/bin/emmc_auto_mount.sh "$MOUNT_POINT"


# Copyright 2018-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

# Run a command given as the second through nth arguments, and report whether
# it succeeded in a pretty fashion to both stdout and syslog, using the action
# message given in the first argument. Examples of good action messages are
# "enabling userver power" and "starting network service".
#
# Note that the command should not produce output of its own, or else the
# stdout message's formatting will be disrupted.
try_and_log() {
    local message ret

    message="$1"; shift
    echo -n "$message ..."
    logger "$message"

    "$@"
    ret="$?"
    if [ "$ret" -eq 0 ]; then
        echo " done"
        logger "finished $message"
    else
        echo " failed"
        logger "failed while $message"
    fi

    return "$ret"
}


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

#shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh

board_type=$(type wedge_board_type >/dev/null 2>&1 && wedge_board_type || echo "no_type")

if [ "$board_type" = "no_type" ]; then
    echo "Unknown board type!"
    exit 1
fi

usage() {
    program=$(basename "$0")
    echo "Usage:"
    echo "  $program <bmc> reset <primary|secondary>"
    echo ""
    echo "Examples:"
    echo "  $program bmc"
    echo "  $program bmc reset primary"
}

board_type=$(type wedge_board_type >/dev/null 2>&1 && wedge_board_type || echo "no_type")

WDT1_STATUS_REG="0x1e785010"
WDT1_CLR_STATUS_REG="0x1e785014"

WDT2_STATUS_REG="0x1e785030"
WDT2_CLR_STATUS_REG="0x1e785034"
WDT2_CNT_RELAOD_REG="0x1e785024"
WDT2_CNT_RESTART_REG="0x1e785028"
WDT2_CTRL_REG="0x1e78502c"

# FMC04 CE Control register
FMC_CE_CTRL_REG="0x1e620004"

check_boot_source(){
    # Please refer to reg WDT1/WDT2 Control Register definition to
    # understand this code block, WDT1 is on page 646 of ast2500v16.pdf
    # and WDT2 is on page 649 of ast2500v16.pdf
    # get watch dog1 timeout status register
    wdt1=$(devmem "$WDT1_STATUS_REG")

    # get watch dog2 timeout status register
    wdt2=$(devmem "$WDT2_STATUS_REG")

    wdt1_timeout_cnt=$(( ((wdt1 & 0xff00) >> 8) ))
    wdt2_timeout_cnt=$(( ((wdt2 & 0xff00) >> 8) ))
    wdt1_boot_code_source=$(( ((wdt1 & 0x2) >> 1) ))
    wdt2_boot_code_source=$(( ((wdt2 & 0x2) >> 1) ))
    boot_code_source=0

    # Check both WDT1 and WDT2 to indicate the boot source
    if [ $wdt1_timeout_cnt -ge 1 ] && [ $wdt1_boot_code_source -eq 1 ]; then
        boot_code_source=1
    elif [ $wdt2_timeout_cnt -ge 1 ] && [ $wdt2_boot_code_source -eq 1 ]; then
        boot_code_source=1
    fi

    echo $boot_code_source
}

bmc_boot_info() {
    # get watch dog1 timeout status register
    wdt1=$(devmem "$WDT1_STATUS_REG")

    # get watch dog2 timeout status register
    wdt2=$(devmem "$WDT2_STATUS_REG")

    wdt1_timeout_cnt=$(( ((wdt1 & 0xff00) >> 8) ))
    wdt2_timeout_cnt=$(( ((wdt2 & 0xff00) >> 8) ))

    boot_code_source=$(check_boot_source)

    boot_source="primary Flash"
    if [ $((boot_code_source)) -eq 1 ]
    then
      boot_source="secondary Flash"
    fi

    echo "WDT1 Timeout Count: " $wdt1_timeout_cnt
    echo "WDT2 Timeout Count: " $wdt2_timeout_cnt
    echo "Current Boot Code Source: $boot_source"
}

bmc_boot_from() {
    # Please refer to reg WDT1/WDT2 Control Register definition to
    # understand this code block, WDT1 is on page 646 of ast2500v16.pdf
    # and WDT2 is on page 649 of ast2500v16.pdf
    # Enable watchdog reset_system_after_timeout bit and WDT_enable_signal bit.
    # Refer to ast2500v16.pdf page 650th.
    boot_source=0x00000013
    boot_code_source=$(check_boot_source)
    if [ "$1" = "primary" ]; then
        if [ $((boot_code_source)) -eq 0 ]; then
            echo "Current boot source is primary, no need to switch."
            return 0
        fi
        # Set bit_7 to 0 : Use default boot code whenever WDT reset.
        boot_source=0x00000033
    elif [ "$1" = "secondary" ]; then
        if [ $((boot_code_source)) -eq 1 ]; then
            echo "Current boot source is secondary, no need to switch."
            return 0
        fi
        # No matter BMC boot from any one of primary and secondary.
        # Set bit_7 to 1 : Use second boot code whenever WDT reset.
        # And the sencond boot code stands for the other boot source.
        boot_source=0x000000b3
    fi
    echo "BMC will switch to $1 after 10 seconds..."
    # Clear WDT1 counter and boot code source status
    devmem "$WDT1_CLR_STATUS_REG" w 0x77
    # Clear WDT2 counter and boot code source status
    devmem "$WDT2_CLR_STATUS_REG" w 0x77
    # Set WDT time out 10s, 0x00989680 = 10,000,000 us
    devmem "$WDT2_CNT_RELAOD_REG" 32 0x00989680
    # WDT magic number to restart WDT counter to decrease.
    devmem "$WDT2_CNT_RESTART_REG" 32 0x4755
    devmem "$WDT2_CTRL_REG" 32 $boot_source

    # Workaround by set default value to FMC04 of "unable to boot 2nd flash issue"
    # only for Wedge400/Wedge400C
    if grep -q "wedge400" /etc/issue; then
        devmem "$FMC_CE_CTRL_REG" w 0x700
    fi
}

if [ $# -lt 1 ]; then
    usage
    exit 1
fi

case $1 in
    "bmc")
        if [ $# -eq 1 ]; then
            bmc_boot_info
            exit 0
        else
            if [ "$2" = "reset" ] && [ $# -ge 3 ]; then
                case $3 in
                    "primary" | "secondary")
                        bmc_boot_from "$3"
                        exit 0
                    ;;
                    *)
                        usage
                        exit 1
                    ;;
                esac
            fi
        fi
    ;;
    *)
        usage
        exit 1
    ;;
esac


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

# shellcheck disable=SC1091
source /usr/local/bin/openbmc-utils.sh

# Disable the dual boot watch dog
devmem_clear_bit 0x1e78502c 0


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

#shellcheck disable=SC1091
. /usr/local/bin/openbmc-utils.sh

board_type=$(type wedge_board_type >/dev/null 2>&1 && wedge_board_type || echo "no_type")

if [ "$board_type" = "no_type" ]; then
    echo "Unkonwn board type!"
    exit 1
fi

usage() {
    program=$(basename "$0")
    echo "Usage:"
    if [ "$board_type" != "CMM" ]; then
        echo "  $program <bmc|bios> reset <master|slave>"
    else
        echo "  $program <bmc> reset <master|slave>"
    fi

    echo ""
    echo "Examples:"
    echo "  $program bmc"
    echo "  $program bmc reset master"
}

board_type=$(type wedge_board_type >/dev/null 2>&1 && wedge_board_type || echo "no_type")

WDT1_STATUS_REG="0x1e785010"
WDT1_CLR_STATUS_REG="0x1e785014"

WDT2_STATUS_REG="0x1e785030"
WDT2_CLR_STATUS_REG="0x1e785034"
WDT2_CNT_RELAOD_REG="0x1e785024"
WDT2_CNT_RESTART_REG="0x1e785028"
WDT2_CTRL_REG="0x1e78502c"

# FMC04 CE Control register
FMC_CE_CTRL_REG="0x1e620004"

check_boot_source(){
    # Please refer to reg WDT1/WDT2 Control Register definition to
    # understand this code block, WDT1 is on page 646 of ast2500v16.pdf
    # and WDT2 is on page 649 of ast2500v16.pdf
    # get watch dog1 timeout status register
    wdt1=$(devmem "$WDT1_STATUS_REG")

    # get watch dog2 timeout status register
    wdt2=$(devmem "$WDT2_STATUS_REG")

    wdt1_timeout_cnt=$(( ((wdt1 & 0xff00) >> 8) ))
    wdt2_timeout_cnt=$(( ((wdt2 & 0xff00) >> 8) ))
    wdt1_boot_code_source=$(( ((wdt1 & 0x2) >> 1) ))
    wdt2_boot_code_source=$(( ((wdt2 & 0x2) >> 1) ))
    boot_code_source=0

    # Check both WDT1 and WDT2 to indicate the boot source
    if [ $wdt1_timeout_cnt -ge 1 ] && [ $wdt1_boot_code_source -eq 1 ]; then
        boot_code_source=1
    elif [ $wdt2_timeout_cnt -ge 1 ] && [ $wdt2_boot_code_source -eq 1 ]; then
        boot_code_source=1
    fi

    echo $boot_code_source
}

bmc_boot_info() {
    # get watch dog1 timeout status register
    wdt1=$(devmem "$WDT1_STATUS_REG")

    # get watch dog2 timeout status register
    wdt2=$(devmem "$WDT2_STATUS_REG")

    wdt1_timeout_cnt=$(( ((wdt1 & 0xff00) >> 8) ))
    wdt2_timeout_cnt=$(( ((wdt2 & 0xff00) >> 8) ))

    boot_code_source=$(check_boot_source)

    boot_source="Master Flash"
    if [ $((boot_code_source)) -eq 1 ]
    then
      boot_source="Slave Flash"
    fi

    echo "WDT1 Timeout Count: " $wdt1_timeout_cnt
    echo "WDT2 Timeout Count: " $wdt2_timeout_cnt
    echo "Current Boot Code Source: $boot_source"
}

bmc_boot_from() {
    # Please refer to reg WDT1/WDT2 Control Register definition to
    # understand this code block, WDT1 is on page 646 of ast2500v16.pdf
    # and WDT2 is on page 649 of ast2500v16.pdf
    # Enable watchdog reset_system_after_timeout bit and WDT_enable_signal bit.
    # Refer to ast2500v16.pdf page 650th.
    boot_source=0x00000013
    boot_code_source=$(check_boot_source)
    if [ "$1" = "master" ]; then
        if [ $((boot_code_source)) -eq 0 ]; then
            echo "Current boot source is master, no need to switch."
            return 0
        fi
        # Set bit_7 to 0 : Use default boot code whenever WDT reset.
        boot_source=0x00000033
    elif [ "$1" = "slave" ]; then
        if [ $((boot_code_source)) -eq 1 ]; then
            echo "Current boot source is slave, no need to switch."
            return 0
        fi
        # No matter BMC boot from any one of master and slave.
        # Set bit_7 to 1 : Use second boot code whenever WDT reset.
        # And the sencond boot code stands for the other boot source.
        boot_source=0x000000b3
    fi
    echo "BMC will switch to $1 after 10 seconds..."
    # Clear WDT1 counter and boot code source status
    devmem "$WDT1_CLR_STATUS_REG" w 0x77
    # Clear WDT2 counter and boot code source status
    devmem "$WDT2_CLR_STATUS_REG" w 0x77
    # Set WDT time out 10s, 0x00989680 = 10,000,000 us
    devmem "$WDT2_CNT_RELAOD_REG" 32 0x00989680
    # WDT magic number to restart WDT counter to decrease.
    devmem "$WDT2_CNT_RESTART_REG" 32 0x4755
    devmem "$WDT2_CTRL_REG" 32 $boot_source

    # Workaround by set default value to FMC04 of "unable to boot 2nd flash issue"
    # only for Wedge400/Wedge400C
    if grep -q "wedge400" /etc/issue; then
        devmem "$FMC_CE_CTRL_REG" w 0x700
    fi
}

bios_boot_info() {
    # CPLD path and related COMe BIOS select bits may differ for different
    # AST2500 based platforms. Additional logic may needed for specific
    # platforms
    master_disable=$(( $(head -n 1 < "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis0_n") ))
    slave_disable=$(( $(head -n 1 < "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis1_n") ))
    boot_source="master"
    if [ $master_disable -eq 0 ]; then
        boot_source="master"
    elif [ $slave_disable -eq 0 ]; then
        boot_source="slave"
    fi
    echo $boot_source
}

bios_boot_from() {
    boot_source=$(bios_boot_info)
    if [ "$1" = "master" ]; then
        if [ "$boot_source" = "master" ]; then
            echo "Current boot source is master, no need to switch."
            return 0
        fi
        echo 0 > "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis0_n"
        echo 0 > "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis1_n"

        echo "uServer will boot from $1 bios at next reboot!!!!"
    elif [ "$1" = "slave" ]; then
        if [ "$boot_source" = "slave" ]; then
            echo "Current boot source is slave, no need to switch."
            return 0
        fi
        echo 1 > "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis0_n"
        echo 0 > "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis1_n"

        echo "uServer will boot from $1 bios at next reboot!!!!"
    else
        echo "Unknown uServer boot source, should be either master or slave!"
    fi
}

if [ $# -lt 1 ]; then
    usage
    exit 1
fi

case $1 in
    "bmc")
        if [ $# -eq 1 ]; then
            bmc_boot_info
            exit 0
        else
            if [ "$2" = "reset" ] && [ $# -ge 3 ]; then
                case $3 in
                    "master" | "slave")
                        bmc_boot_from "$3"
                        exit 0
                    ;;
                    *)
                        usage
                        exit 1
                    ;;
                esac
            fi
        fi
    ;;
    "bios")
        if [ "$board_type" != "CMM" ]; then
            if [ $# -eq 1 ]; then
                bios_boot_info
                exit 0
            else
                if [ "$2" = "reset" ] && [ $# -ge 3 ]; then
                    case $3 in
                        "master" | "slave")
                            bios_boot_from "$3"
                            exit 0
                        ;;
                        *)
                            usage
                            exit 1
                        ;;
                    esac
                fi
            fi
        fi
    ;;
    *)
        usage
        exit 1
    ;;
esac


#!/bin/sh
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

# shellcheck disable=SC1091
source /usr/local/bin/openbmc-utils.sh

#
# WDT2C Register. Check AST2500 Datasheet, Chapter 41 "Watchdog Timer"
# for details.
#
WDT2_CTRL_REG=0x1e78502c
WDT2_ENABLE_BIT=0

# Disable the dual boot watchdog
devmem_clear_bit "$WDT2_CTRL_REG" "$WDT2_ENABLE_BIT"

if devmem_test_bit "$WDT2_CTRL_REG" "$WDT2_ENABLE_BIT"; then
    val=$(devmem "$WDT2_CTRL_REG")
    echo "ALERT: failed to disable the 2nd watchdog: WDT2C=$val!!!"
    logger -p user.crit "failed to disable the 2nd watchdog: WDT2C=$val!!!"
    exit 1
fi

echo "Disabled the 2nd watchdog (WDT2) successfully."


#!/bin/bash
#
# Copyright 2020-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

# shellcheck disable=SC1091
source /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

usage() {
    program=$(basename "$0")
    echo "Usage:"
    echo "  $program <bmc|bios> reset <master|slave>"
    echo ""
    echo "Examples:"
    echo "  $program bmc"
    echo "  $program bmc reset master"
}

WDT1_STATUS_REG="0x1E785010"
FMC_WDT2_RELOAD_VAL_REG="0x1E620068"
FMC_WDT2_RESTART_REG="0x1E62006C"
FMC_WDT2_CTRL_STATUS_REG="0x1E620064"

bmc_boot_info() {
    # Please refer to reg WDT1/WDT2 Control Register definition to
    # understand this code block, WDT1 is on page 758 of ast2620.pdf
    # and WDT2 is on page 232 of ast2620.pdf
    # get watch dog1 timeout status register
    wdt1=$(devmem "$WDT1_STATUS_REG")

    # get watch dog2 timeout status register
    wdt2=$(devmem "$FMC_WDT2_CTRL_STATUS_REG" )

    wdt1_timeout_cnt=$(( ((wdt1 & 0xff00) >> 8) ))
    wdt2_timeout_cnt=$(( ((wdt2 & 0xff00) >> 8) ))
    boot_code_source=$(( ((wdt2 & 0x10) >> 4) ))

    boot_source="Master Flash"
    if [ $boot_code_source -eq 1 ]
    then
      boot_source="Slave Flash"
    fi

    echo "WDT1 Timeout Count: " $wdt1_timeout_cnt
    echo "WDT2 Timeout Count: " $wdt2_timeout_cnt
    echo "Current Boot Code Source: $boot_source"
}

bmc_boot_from() {
    # Please refer to reg WDT2 Control Register definition to
    # understand this code block, WDT2 is on page 232 of ast2620.pdf
    # Enable watchdog reset_system_after_timeout bit and WDT_enable_signal bit.
    # Refer to ast2620.pdf page 232.
    boot_source=0x00000000
    wdt2=$(devmem "$FMC_WDT2_CTRL_STATUS_REG")
    boot_code_source=$(( (wdt2 & 0x10) >> 4 ))
    if [ "$1" = "master" ]; then
        if [ $boot_code_source = 0 ]; then
            echo "Current boot source is master, no need to switch."
            return 0
        fi
        # No matter BMC boot from any one of master and slave.
        # Set bit_7 to 1 : Use second boot code whenever WDT reset.
        # And the sencond boot code stands for the other boot source.
        boot_source=0x00000001
    elif [ "$1" = "slave" ]; then
        if [ $boot_code_source = 1 ]; then
            echo "Current boot source is slave, no need to switch."
            return 0
        fi
        # No matter BMC boot from any one of master and slave.
        # Set bit_7 to 1 : Use second boot code whenever WDT reset.
        # And the sencond boot code stands for the other boot source.
        boot_source=0x00000001
    fi

    # Extend wdt1 timeout value to prevent wdt1 timeout during uboot stage.
    if [ "$(LC_ALL=C type -t wdt_set_timeout)" = function ]; then
        wdt_set_timeout 120
    else
        wdtcli set-timeout 120
    fi
    echo "BMC will switch to $1 after 2 seconds    ..."
    # Set WDT time out 2s, 0x00000014 = 2s
    devmem "$FMC_WDT2_RELOAD_VAL_REG" 32 0x00000014
    # WDT magic number to restart WDT counter to decrease.
    devmem "$FMC_WDT2_RESTART_REG" 32 0x4755
    devmem "$FMC_WDT2_CTRL_STATUS_REG" 32 $boot_source
}

bios_boot_info() {
    master_disable=$(( $(head -n 1 < "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis0_n") ))
    slave_disable=$(( $(head -n 1 < "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis1_n") ))
    boot_source="master"
    if [ $master_disable -eq 0 ]; then
        boot_source="master"
    elif [ $slave_disable -eq 0 ]; then
        boot_source="slave"
    fi
    echo $boot_source
}

bios_boot_from() {
    boot_source=$(bios_boot_info)
    if [ "$1" = "master" ]; then
        if [ "$boot_source" = "master" ]; then
            echo "Current boot source is master, no need to switch."
            return 0
        fi
        echo 0 > "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis0_n"
        echo 0 > "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis1_n"

        echo "uServer will boot from $1 bios at next reboot!!!!"
    elif [ "$1" = "slave" ]; then
        if [ "$boot_source" = "slave" ]; then
            echo "Current boot source is slave, no need to switch."
            return 0
        fi
        echo 1 > "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis0_n"
        echo 0 > "${SCMCPLD_SYSFS_DIR}/iso_buff_brg_com_bios_dis1_n"

        echo "uServer will boot from $1 bios at next reboot!!!!"
    else
        echo "Unknown uServer boot source, should be either master or slave!"
    fi
}

if [ $# -lt 1 ]; then
    usage
    exit 1
fi

case $1 in
    "bmc")
        if [ $# -eq 1 ]; then
            bmc_boot_info
            exit 0
        else
            if [ "$2" = "reset" ] && [ $# -ge 3 ]; then
                case $3 in
                    "master" | "slave")
                        bmc_boot_from "$3"
                        exit 0
                    ;;
                    *)
                        usage
                        exit 1
                    ;;
                esac
            fi
        fi
    ;;
    "bios")
        if [ $# -eq 1 ]; then
            bios_boot_info
            exit 0
        else
            if [ "$2" = "reset" ] && [ $# -ge 3 ]; then
                case $3 in
                    "master" | "slave")
                        bios_boot_from "$3"
                        exit 0
                    ;;
                    *)
                        usage
                        exit 1
                    ;;
                esac
            fi
        fi
    ;;
    *)
        usage
        exit 1
    ;;
esac


#!/bin/bash
#
# Copyright 2019-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

# shellcheck disable=SC1091
source /usr/local/bin/openbmc-utils.sh

#
# FMC64 Register. Check AST2600 Datasheet, Chapter 14 "Firmware SPI Memory
# Controller (BSPI)" for details.
#
FMC_WDT2_REG=0x1e620064
FMC_WDT2_ENABLE_BIT=0

# Disable the fmc dual boot watch dog
devmem_clear_bit "$FMC_WDT2_REG" "$FMC_WDT2_ENABLE_BIT"

if devmem_test_bit 0x1e620064 "$FMC_WDT2_ENABLE_BIT"; then
    val=$(devmem "$FMC_WDT2_REG")
    echo "Error: unable to disable the 2nd watchdog: FMC_WDT2=$val"
    exit 1
fi

echo "Disabled the 2nd watchdog (FMC_WDT2) successfully."


# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

scu_addr() {
    echo $((0x1E6E2000 + 0x$1))
}

ast_config_adc() {
    local ADC_PATH="/sys/devices/platform/ast_adc.0"
    local channel=$1
    local r1=$2
    local r2=$3
    local v2=$4
    echo "$r1" > ${ADC_PATH}/adc${channel}_r1
    echo "$r2" > ${ADC_PATH}/adc${channel}_r2
    echo "$v2" > ${ADC_PATH}/adc${channel}_v2
    echo 1 > ${ADC_PATH}/adc${channel}_en
}

aspeed_g6_chip_ver() {
        chip_ver=$(devmem 0x1e6e2014 | awk '{print substr($0,6,1)}')
        case $chip_ver in
                0)
                        echo "A0"
                        ;;
                1)
                        echo "A1"
                        ;;
                2)
                        echo "A2"
                        ;;
                3)
                        echo "A3"
                        ;;
        esac
}


#!/bin/sh
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#
usage() {
    echo "Usage: $0 [Fan Unit (1..5) (upper: 6...10)] [board type (Mavericks Montara)]" >&2
}

FAN_DIR=/sys/class/i2c-adapter/i2c-8/8-0033
FAN_DIR_UPPER=/sys/class/i2c-adapter/i2c-9/9-0033

show_pwm()
{
    if [ $1 -gt 5 ]; then
        fan=$(( $1 - 5 ))
        pwm="${FAN_DIR_UPPER}/fantray${fan}_pwm"
    else
        pwm="${FAN_DIR}/fantray${1}_pwm"
    fi
    val=$(cat $pwm | head -n 1)
    echo "$((val * 100 / 31))%"
}

show_rpm()
{
    if [ $1 -gt 5 ]; then
        front_rpm="${FAN_DIR_UPPER}/fan$(((($1 - 5) * 2 - 1)))_input"
        rear_rpm="${FAN_DIR_UPPER}/fan$(((($1 - 5) * 2)))_input"
    else
        front_rpm="${FAN_DIR}/fan$((($1 * 2 - 1)))_input"
        rear_rpm="${FAN_DIR}/fan$((($1 * 2)))_input"
    fi
    echo "$(cat $front_rpm), $(cat $rear_rpm)"
}

set -e

# refer to the comments in init_pwn.sh regarding
# the fan unit and tacho mapping
# fixing function to handle maverciks and montara number of fans
# while keeping backward command line compatibility with original FB script
if [ "$#" -eq 0 ]; then
    	FANS="1 2 3 4 5"
elif [ "$#" -eq 1 ]; then
    if [ $1 = "Mavericks" ]; then
    	FANS="1 2 3 4 5 6 7 8 9 10"
    elif [ $1 = "Montara" ]; then
    	FANS="1 2 3 4 5"
    else
	if [ $1 -gt 10 ]; then
      	    usage
            exit 1
	fi
	FANS="$1"
    fi
elif [ "$#" -eq 2 ]; then
    if [ $2 != "Mavericks" ] && [ $2 != "Montara" ]; then
    	usage
    	exit 1
    fi
    if [ $1 -gt 10 ]; then
        usage
        exit 1
    fi
    FANS="$1"
else
    usage
    exit 1
fi

for fan in $FANS; do
    echo "Fan $fan RPMs: $(show_rpm $fan), ($(show_pwm $fan))"
done


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          setup-fan
# Required-Start:    board-id
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Set fan speed
### END INIT INFO

echo -n "Setup fan speed... "
/usr/local/bin/set_fan_speed.sh 50
/usr/local/bin/fand
echo "done."


#!/bin/sh
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#
usage() {
    echo "Usage: $0 <PERCENT (0..100)> <Fan Unit (1..5)(6...10)> <board type (Montara Mavericks)>" >&2
}

FAN_DIR=/sys/class/i2c-adapter/i2c-8/8-0033
FAN_DIR_UPPER=/sys/class/i2c-adapter/i2c-9/9-0033

set -e

if [ "$#" -gt 3 ] || [ "$#" -lt 1 ]; then
    usage
    exit 1
fi

# Adding fix for Mavericks and Montara while keeping backward compatibility with FB command line.
if [ "$#" -eq 1 ]; then
    FANS="1 2 3 4 5"
elif [ "$#" -eq 2 ]; then
    if [ $2 = "Mavericks" ]; then
    	FANS="1 2 3 4 5 6 7 8 9 10"
    elif [ $2 = "Montara" ]; then
    	FANS="1 2 3 4 5"
    else
    	if [ $2 -gt 10 ]; then
       	    usage
            exit 1
    	fi
    	FANS="$2"
    fi
else
    if [ $3 = "Mavericks" ]; then
    	if [ $2 -gt 10 ]; then
       	    usage
            exit 1
    	fi
    elif [ $3 = "Montara" ]; then
    	if [ $2 -gt 5 ]; then
       	    usage
            exit 1
    	fi
    else
        usage
        exit 1
    fi
    FANS="$2"
fi

# Convert the percentage to our 1/32th unit (0-31).
unit=$(( ( $1 * 31 ) / 100 ))

for fan in $FANS; do
    if [ $fan -gt 5 ]; then
        fan_idx=$(( $fan - 5))
        pwm="${FAN_DIR_UPPER}/fantray${fan_idx}_pwm"
    else
        pwm="${FAN_DIR}/fantray${fan}_pwm"
    fi
    echo "$unit" > $pwm
    echo "Successfully set fan ${fan} speed to $1%"
done


#!/bin/sh
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#
usage() {
    echo "Usage: $0 [Fan Unit (1..5)]" >&2
}

FAN_DIR=/sys/class/i2c-adapter/i2c-8/8-0033

show_pwm()
{
    pwm="${FAN_DIR}/fantray${1}_pwm"
    val=$(cat $pwm | head -n 1)
    echo "$((val * 100 / 31))%"
}

show_rpm()
{
    front_rpm="${FAN_DIR}/fan$((($1 * 2 - 1)))_input"
    rear_rpm="${FAN_DIR}/fan$((($1 * 2)))_input"
    echo "$(cat $front_rpm), $(cat $rear_rpm)"
}

set -e

# refer to the comments in init_pwn.sh regarding
# the fan unit and tacho mapping
if [ "$#" -eq 0 ]; then
    FANS="1 2 3 4 5"
elif [ "$#" -eq 1 ]; then
    if [ $1 -gt 5 ]; then
        usage
        exit 1
    fi
    FANS="$1"
else
    usage
    exit 1
fi

for fan in $FANS; do
    echo "Fan $fan RPMs: $(show_rpm $fan), ($(show_pwm $fan))"
done


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          setup-fan
# Required-Start:    board-id
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Set fan speed
### END INIT INFO

. /usr/local/fbpackages/utils/ast-functions

echo -n "Setup fan speed... "
/usr/local/bin/set_fan_speed.sh 50
runsv /etc/sv/fscd > /dev/null 2>&1 &
echo "done."


#!/bin/sh
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#
usage() {
    echo "Usage: $0 <PERCENT (0..100)> <Fan Unit (1..5)> " >&2
}

FAN_DIR=/sys/class/i2c-adapter/i2c-8/8-0033

set -e

if [ "$#" -ne 2 ] && [ "$#" -ne 1 ]; then
    usage
    exit 1
fi

if [ "$#" -eq 1 ]; then
    FANS="1 2 3 4 5"
else
    FANS="$2"
fi

# Convert the percentage to our 1/32th unit (0-31).
unit=$(( ( $1 * 31 ) / 100 ))

for fan in $FANS; do
    pwm="${FAN_DIR}/fantray${fan}_pwm"
    echo "$unit" > $pwm
    echo "Successfully set fan ${fan} speed to $1%"
done


# Copyright 2015-present Facebook. All Rights Reserved.

SYSCPLD_SYSFS_DIR="/sys/class/i2c-adapter/i2c-12/12-0031"
PWR_MAIN_SYSFS="${SYSCPLD_SYSFS_DIR}/pwr_main_n"
PWR_USRV_SYSFS="${SYSCPLD_SYSFS_DIR}/pwr_usrv_en"
PWR_USRV_BTN_SYSFS="${SYSCPLD_SYSFS_DIR}/pwr_usrv_btn_en"
SLOTID_SYSFS="${SYSCPLD_SYSFS_DIR}/slotid"

wedge_iso_buf_enable() {
    # TODO, no isolation buffer
    return 0
}

wedge_iso_buf_disable() {
    # TODO, no isolation buffer
    return 0
}

wedge_is_us_on() {
    local val n retries prog
    if [ $# -gt 0 ]; then
        retries="$1"
    else
        retries=1
    fi
    if [ $# -gt 1 ]; then
        prog="$2"
    else
        prog=""
    fi
    if [ $# -gt 2 ]; then
        default=$3              # value 0 means defaul is 'ON'
    else
        default=1
    fi
    val=$(cat $PWR_USRV_SYSFS 2> /dev/null | head -n 1)
    if [ -z "$val" ]; then
        return $default
    elif [ "$val" == "0x1" ]; then
        return 0            # powered on
    else
        return 1
    fi
}

wedge_board_type() {
    echo 'MAVERICKS'
}

wedge_slot_id() {
    printf "%d\n" $(cat $SLOTID_SYSFS)
}

wedge_board_rev() {
    local val0 val1 val2
    val0=$(gpio_get BOARD_REV_ID0)
    val1=$(gpio_get BOARD_REV_ID1)
    val2=$(gpio_get BOARD_REV_ID2)
    echo $((val0 | (val1 << 1) | (val2 << 2)))
}

# Should we enable OOB interface or not
wedge_should_enable_oob() {
    # wedge100 uses BMC MAC since beginning
    return -1
}

wedge_power_on_board() {
    local val isolbuf
    # power on main power, uServer power, and enable power button
    val=$(cat $PWR_MAIN_SYSFS | head -n 1)
    if [ "$val" != "0x1" ]; then
        echo 1 > $PWR_MAIN_SYSFS
        sleep 2
    fi
    val=$(cat $PWR_USRV_BTN_SYSFS | head -n 1)
    if [ "$val" != "0x1" ]; then
        echo 1 > $PWR_USRV_BTN_SYSFS
        sleep 1
    fi

    # Enable the COME I2C isolation buffer
    val=$(i2cget -f -y 12 0x31 0x28)
    isolbuf=$(($val|0x30))
    i2cset -f -y 12 0x31 0x28 $isolbuf
}


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

CMD='/sys/class/i2c-adapter/i2c-12/12-0031/i2c_flush_en'

echo -n "I2c flush to CP2112..."
echo 1 > $CMD
usleep 50000
echo 0 > $CMD
echo "Done"


#!/bin/bash
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

rev=$(head -1 /sys/class/i2c-adapter/i2c-12/12-0031/cpld_rev)
sub_rev=$(head -1 /sys/class/i2c-adapter/i2c-12/12-0031/cpld_sub_rev)

echo $(($rev)).$(($sub_rev))


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

upgrade_syscpld() {
  echo "Started SYSCPLD upgrade .."
  echo out > /tmp/gpionames/CPLD_JTAG_SEL/direction
  echo 1 > /tmp/gpionames/CPLD_JTAG_SEL/value
  sys_usercode=$(jbi -r -aREAD_USERCODE -gc102 -gi101 -go103 -gs100 $1 | grep -i "USERCODE code is" | awk '{ print $6 }')
  new_usercode=$(jbi -i $1 | grep -i "\"USERCODE"\" | awk -F '"' '{ print $4 }')
  if [ "${sys_usercode}" != "${new_usercode}" ];
  then
      #disable heartbeat
      i2cset -f -y 12 0x31 0x2e 0x18
      #program syscpld
      rc=$(jbi -r -aPROGRAM -gc102 -gi101 -go103 -gs100 $1 | grep -i "Success")
      if [[ $rc == *"Success"* ]];
      then
          echo "Finished SYSCPLD upgrade: Pass"
      else
          echo "Finished SYSCPLD upgrade: Fail (Program failed)"
      fi
  else
    echo "Finished SYSCPLD upgrade: No Action (Same usercode)"
  fi
}

upgrade_fancpld() {
  echo "Started FANCPLD upgrade .."
  echo out > /tmp/gpionames/CPLD_UPD_EN/direction
  echo 0 > /tmp/gpionames/CPLD_UPD_EN/value
  #get usercode from system
  sys_usercode=$(jbi -r -aREAD_USERCODE -gc77 -gi78 -go79 -gs76 $1 | grep -i "USERCODE code is" | awk '{ print $6 }')
  #get usercode from file
  new_usercode=$(jbi -i $1 | grep -i "\"USERCODE"\" | awk -F '"' '{ print $4 }')
  if [ "${sys_usercode}" != "${new_usercode}" ];
  then
      #program fancpld
      rc=$(jbi -aPROGRAM -gc77 -gi78 -go79 -gs76 $1 | grep -i "Success")
      if [[ $rc == *"Success"* ]];
      then
          echo "Finished FANCPLD upgrade: Pass"
      else
          echo "Finished FANCPLD upgrade: Fail (Program failed)"
      fi
  else
    echo "Finished FANCPLD upgrade: No Action (Same usercode)"
  fi
}

# Check the number of arguments provided, should get atleast 1 for file path
if [ $# -lt 1 ]; then
  echo "Provide FAN or SYSCPLD path"
  exit -1
fi

# Check the file path provided is a valid one.
jbcfile="$1"
if [ ! -f $jbcfile ]; then
    echo "$jbcfile does not exist"
    exit -1
fi

# Check the file path extension is .jbc
filename="$(basename $jbcfile)"
if [[ ${filename: -4} != ".jbc" ]]; then
    echo "Must pass in a .jbc file"
    exit -1
fi

# Check the file name and upgrade accordingly
if [[ $filename == *"FAN"* ]];
then
    upgrade_fancpld $jbcfile
else if [[ $filename == *"SYSCPLD"* ]];
then
    upgrade_syscpld $jbcfile
else
  echo "Provide FAN or SYSCPLD path"
  exit -1
fi
fi


#!/bin/bash
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.Â  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

version=$(cat /sys/class/i2c-adapter/i2c-4/4-0033/version)
released_date=$(cat /sys/class/i2c-adapter/i2c-4/4-0033/date)

if [ "${version:(-4)}" == "0x80" ]; then
  echo "EC Test Version"
  echo "EC Released Date: $released_date"
else
  r=$((16#${version:15:2}))
  e=$((16#${version:22:2}))
  echo "EC Released Version: R$(printf '%02d' $r).E$(printf '%02d' $e)"
  echo "EC Released Date: $released_date"
fi


#!/bin/sh

. /usr/local/bin/openbmc-utils.sh

# select WDTRST
devmem_clear_bit $(scu_addr 2C) 1
devmem_set_bit $(scu_addr 84) 4


#!/bin/bash
#
# reconfigure the CPLD<-->COMe UART mux
# useful to force redirect COMe tx/rx data from reaching BMC UART durign COMe boot
# We could not disable the BMC UART from transmitting to COMe and hence this work around.
# usage wedge_tty_block <1:switch | 0: dont switch > [delay in seconds; default no delay]

if [ $# -eq 0 ]; then
  exit 1
fi

switch=$1
if [ $# -gt 1 ]; then
  delay="$2"
else
  delay=0
fi

if [ $delay -gt 0 ]; then
  sleep "$delay"
fi

val=$(i2cget -f -y 12 0x31 0x26)
if [ $switch -eq 1 ]; then
  newval=$(($val|0x01))
  echo "switching COMe uart to dbg port"
else
  newval=$(($val&0xFE))
  echo "switching COMe uart to BMC UART"
fi
i2cset -f -y 12 0x31 0x26 $newval


#!/bin/sh
#
# Copyright 2004-present Facebook. All rights reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

usage() {
    echo "Displays values onto the debug header LEDs."
    echo "Hex and decimal accepted."
    echo "Usage: $0 <value>"
}

. /usr/local/bin/openbmc-utils.sh

display_value() {
    num=0
    input=$1
    while [ $num -lt 8 ]; do  {
        gpio_set $(gpio_name2value LED_POSTCODE_$num) $((input & 1))
        input=$((input >> 1))
        num=$((num + 1))
    }
    done
}

# Check number of parameters
if [ $# -ne 1 ]
then
    usage
    exit 1
fi

# Make sure input is actually numeric
DEC_VALUE=$(printf "%d" $1 2>/dev/null)
if [ $? -eq 1 ]
then
    echo "Unable to parse input as numeric value."
    exit 1
fi

# Make sure input is within proper range
if [ $DEC_VALUE -lt 0 ] || [ $DEC_VALUE -gt 255 ]
then
    echo "Value $DEC_VALUE is outside of displayable range 0 - 0xff (255)."
    exit 1
fi

display_value $DEC_VALUE


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

### BEGIN INIT INFO
# Provides:          power-on
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Power on micro-server
### END INIT INFO
. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

# make power button high to prepare for power on sequence
gpio_set BMC_PWR_BTN_OUT_N 1

#switch COMe tty to dbg port
mav_tty_switch_delay.sh 1

# First power on TH, and if Panther+ is used,
# provide standby power to Panther+.
wedge_power_on_board

echo -n "Checking microserver power status ... "
if wedge_is_us_on 10 "."; then
    echo "on"
    on=1
else
    echo "off"
    on=0
fi

if [ $on -eq 0 ]; then
    # Power on now
    wedge_power.sh on -f
fi

#switch COMe tty to BMC UART after 45 seconds
echo "wait for 45 seconds before connecting to COMe..."
mav_tty_switch_delay.sh 0 45 &

# set the Tofino VDD voltage here before powering-ON COMe
CODE="$(i2cget -f -y 12 0x31 0xb)"
CODE_M=$(($CODE & 0x7))
if [ $CODE_M != 0 ]; then
    tbl=(0 0.83 0.78 0.88 0.755 0.855 0.805 0.905)
    # If not able to access value it is a montara otherwise mavericks
    cat /sys/bus/i2c/drivers/fancpld/9-0033/board_rev >& /dev/null
    if [ $? == 1 ]; then
        btools.py --IR set_vdd_core montara ${tbl[$CODE_M]}
    else
        btools.py --IR set_vdd_core mavericks ${tbl[$CODE_M]}
    fi
    logger "VDD setting: ${tbl[$CODE_M]}"
fi


#!/bin/bash
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/bin/openbmc-utils.sh

PWR_TH_RST_SYSFS="${SYSCPLD_SYSFS_DIR}/th_sys_rst_n"

echo 0 > $PWR_TH_RST_SYSFS
sleep 1
echo 1 > $PWR_TH_RST_SYSFS

logger "Reset Tofino"


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

CMD='/sys/class/i2c-adapter/i2c-12/12-0031/usb2cp2112_rst_n'

echo -n "Reset CP2112 Switch ... "
echo 0 > $CMD
usleep 50000
echo 1 > $CMD

echo "Done"


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

function reset_to_mux
{
  local num=0 val=$1
  while [ $num -lt 4 ]; do
    CMD='/sys/class/i2c-adapter/i2c-12/12-0031/i2c_mux'$num'_rst_n'
    echo $val > $CMD
    (( num++ ))
  done
}

echo -n "Reset QSFP i2c-mux ... "
reset_to_mux 0
usleep 50000
reset_to_mux 1
echo "Done"


#!/bin/sh

SERVICE="rest.py"

check_8080_port(){
	for ((i=0; i<=12; i++)); do
		netstat -tanu | grep 8080 | grep LISTEN
		cmd=$?
		if [ "$cmd" == 0 ]; then
			return
		fi
		sleep 5
	done
}

while [ 1 ]
do
	RESULT=`ps | sed -n /${SERVICE}/p`
	if [ "${RESULT:-null}" = null ]; then
	    echo "rest.py not running"
	    /usr/local/bin/setup-rest-api.sh restart
	    check_8080_port
	    if [ -e "/tmp/btools_lock" ]; then
	      rm -f "/tmp/btools_lock"
	      echo "Stale btools_lock exists. Removing it"
	    fi
	fi
	sleep 5
done


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

### BEGIN INIT INFO
# Provides:          setup_board.sh
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description: Setup the board
### END INIT INFO

. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

board_rev=$(wedge_board_rev)

if [ $board_rev -ge 2 ]; then
    # DVT or later
    # Enable the isolation buffer between BMC and COMe i2c bus
    echo 1 > ${SYSCPLD_SYSFS_DIR}/com-e_i2c_isobuf_en
    # Enable the COM6_BUF_EN to open the isolation buffer between COMe BIOS
    # EEPROM with COMe
    gpio_set COM6_BUF_EN 0
    # Make the BIOS EEPROM connect to COMe instead of BMC
    gpio_set COM_SPI_SEL 0
fi


#!/bin/sh
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

. /usr/local/bin/openbmc-utils.sh

# Bus 3
i2c_device_add 3 0x48 tmp75
i2c_device_add 3 0x49 tmp75
i2c_device_add 3 0x4a tmp75
i2c_device_add 3 0x4b tmp75
i2c_device_add 3 0x4c tmp75

# Bus 4
i2c_device_add 4 0x33 com_e_driver

# Bus 6
i2c_device_add 6 0x2f pcf8574
i2c_device_add 6 0x51 24c64

# Bus 7
i2c_device_add 7 0x50 24c02         # BMC PHY EEPROM
i2c_device_add 7 0x51 24c64         # PFE1100 power supply EEPROM
i2c_device_add 7 0x52 24c64         # PFE1100 power supply EEPROM
i2c_device_add 7 0x6f ltc4151

# Bus 8
i2c_device_add 8 0x33 fancpld
i2c_device_add 8 0x48 tmp75
i2c_device_add 8 0x49 tmp75

# Bus 9
# 9 0x20 tpm_i2c_infineon added by trousers.init.sh

# Bus 12
i2c_device_add 12 0x31 syscpld


#!/bin/bash
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/bin/openbmc-utils.sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

prog="$0"

PWR_BTN_GPIO="BMC_PWR_BTN_OUT_N"
PWR_SYSTEM_SYSFS="${SYSCPLD_SYSFS_DIR}/pwr_cyc_all_n"
PWR_USRV_RST_SYSFS="${SYSCPLD_SYSFS_DIR}/usrv_rst_n"
PWR_TH_RST_SYSFS="${SYSCPLD_SYSFS_DIR}/th_sys_rst_n"
MAIN_PWR="${SYSCPLD_SYSFS_DIR}/pwr_main_n"
PWR_USRV_SYSFS="${SYSCPLD_SYSFS_DIR}/pwr_main_n"

usage() {
    echo "Usage: $prog <command> [command options]"
    echo
    echo "Commands:"
    echo "  status: Get the current microserver power status"
    echo
    echo "  on: Power on microserver if not powered on already"
    echo "    options:"
    echo "      -f: Re-do power on sequence no matter if microserver has "
    echo "          been powered on or not."
    echo
    echo "  off: Power off microserver ungracefully"
    echo
    echo "  reset: Power reset microserver ungracefully"
    echo "    options:"
    echo "      -s: Power reset whole wedge system ungracefully"
    echo
}

main_power_status() {
  status=$(cat $MAIN_PWR | head -1 )
  if [ "$status" == "0x1" ]; then
      return 0            # powered on
  else
      return 1
  fi
}

do_status() {
    echo -n "Microserver power is "
    return_code=0
    if wedge_is_us_on; then
        echo "on"
    else
        echo "off"
        return_code=1
    fi
    main_power_status
    rc=$?
    if [ $rc == "0" ]; then
        echo "System main power is on"
    else
        echo "System main power is off"
        return_code=1
    fi
    return $return_code
}

do_on_com_e() {
    echo 1 > $PWR_USRV_SYSFS
    return $?
}

do_on_main_pwr() {
  main_power_status
  rc=$?
  if [ $rc == "1" ]; then
    echo 1 > $MAIN_PWR
    ret=$?
    if [ $ret -eq 0 ]; then
      echo "Turning on system main power"
      logger "Successfully power on main power"
      return 0
    else
      return 1
    fi
  fi
  return 0
}

do_on() {
    local force opt ret
    force=0
    while getopts "f" opt; do
        case $opt in
            f)
                force=1
                ;;
            *)
                usage
                exit -1
                ;;

        esac
    done
    echo -n "Power on microserver ..."
    if [ $force -eq 0 ]; then
        # need to check if uS is on or not
        if wedge_is_us_on 10 "."; then
            echo " Already on. Skip!"
            return 1
        fi
    fi

    # reset Tofino
    reset_brcm.sh
    # power on sequence
    do_on_main_pwr
    do_on_com_e
    ret=$?
    if [ $ret -eq 0 ]; then
        echo " Done"
	logger "Successfully power on micro-server"
    else
        echo " Failed"
        logger "Failed to power on micro-server"
    fi
    return $ret
}

do_off_com_e() {
    echo 0 > $PWR_USRV_SYSFS
    return $?
}

do_off() {
    local ret
    echo -n "Power off microserver ..."
    do_off_com_e
    ret=$?
    if [ $ret -eq 0 ]; then
        echo " Done"
    else
        echo " Failed"
    fi
    return $ret
}

do_reset() {
    local system opt pulse_us
    system=0
    while getopts "s" opt; do
        case $opt in
            s)
                system=1
                ;;
            *)
                usage
                exit -1
                ;;
        esac
    done
    if [ $system -eq 1 ]; then
        pulse_us=100000             # 100ms
        logger "Power reset the whole system ..."
        echo -n "Power reset the whole system ..."
        sleep 1
        echo 0 > $PWR_SYSTEM_SYSFS
        # Echo 0 above should work already. However, after CPLD upgrade,
        # We need to re-generate the pulse to make this work
        usleep $pulse_us
        echo 1 > $PWR_SYSTEM_SYSFS
        usleep $pulse_us
        echo 0 > $PWR_SYSTEM_SYSFS
        usleep $pulse_us
        echo 1 > $PWR_SYSTEM_SYSFS
    else
        if ! wedge_is_us_on; then
            echo "Power resetting microserver that is powered off has no effect."
            echo "Use '$prog on' to power the microserver on"
            return -1
        fi
        # reset Tofino first
        reset_brcm.sh
        echo -n "Power reset microserver ..."
        echo 0 > $PWR_USRV_RST_SYSFS
        sleep 1
        echo 1 > $PWR_USRV_RST_SYSFS
        logger "Successfully power reset micro-server"
    fi
    echo " Done"
    return 0
}

if [ $# -lt 1 ]; then
    usage
    exit -1
fi

command="$1"
shift

case "$command" in
    status)
        do_status $@
        ;;
    on)
        do_on $@
        ;;
    off)
        do_off $@
        ;;
    reset)
        do_reset $@
        ;;
    *)
        usage
        exit -1
        ;;
esac

exit $?


#!/bin/bash
#
# Copyright 2015-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

. /usr/local/bin/openbmc-utils.sh

if ! wedge_is_us_on; then
    echo "Cannot retrive microserver MAC when microserver is powered off." 1>&2
    exit -2
fi

mac=$(cat /sys/class/i2c-adapter/i2c-4/4-0033/mac)

if [ -n "$mac" -a "${mac/X/}" = "${mac}" ]; then
    echo $mac
    exit 0
else
    echo "Cannot find out the microserver MAC" 1>&2
    exit -1
fi


#!/bin/sh

### BEGIN INIT INFO
# Provides:		tpm2-abrmd
# Required-Start:	$local_fs $remote_fs $network
# Required-Stop:	$local_fs $remote_fs $network
# Should-Start:
# Should-Stop:
# Default-Start:	2 3 4 5
# Default-Stop:		0 1 6
# Short-Description:	starts tpm2-abrmd
# Description:		tpm2-abrmd implements the TCG resource manager
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/tpm2-abrmd
NAME=tpm2-abrmd
DESC="TCG TSS2 Access Broker and Resource Management daemon"
USER="tss"

test -x "${DAEMON}" || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

case "${1}" in
	start)
		echo -n "Starting $DESC: "

		if [ ! -e /dev/tpm? ]
		then
			echo "device driver not loaded, skipping."
			exit 0
		fi

		start-stop-daemon --start --quiet --oknodo --background --pidfile /var/run/${NAME}.pid --user ${USER} --chuid ${USER} --exec ${DAEMON} -- ${DAEMON_OPTS}
		RETVAL="$?"
		echo "$NAME."
		[ "$RETVAL" = 0 ] && pidof $DAEMON > /var/run/${NAME}.pid
		exit $RETVAL
		;;

	stop)
		echo -n "Stopping $DESC: "

		start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/${NAME}.pid --user ${USER} --exec ${DAEMON}
		RETVAL="$?"
                echo  "$NAME."
		rm -f /var/run/${NAME}.pid
		exit $RETVAL
		;;

	restart|force-reload)
		"${0}" stop
		sleep 1
		"${0}" start
		exit $?
		;;
	*)
		echo "Usage: ${NAME} {start|stop|restart|force-reload|status}" >&2
		exit 3
		;;
esac

exit 0


#!/bin/bash
#
# Copyright (c) 2022 Cisco Systems Inc.
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#
# shellcheck disable=SC1091
# shellcheck disable=SC2001

# The Marvell GW swith reset and the Marvell GW switch EEPROM I2C access are controlled by writing to the CPU CPLD registers.
# To write to a CPU CLPD rigister:
# 1- First the CPLD register address is specified by writing to I2C addresses 0x31 to 0x34.
# 2- Then the data is specified by writing to addresses 0x35 to 0x38.
# 3- And finally the write request is triggered by writing to address 0x30 as below:
#
#0x30 is command  1: read,  0: write
#0x31 addr[7:0]
#0x32 addr[15:8]
#0x33 addr[23:16]
#0x34 addr[31:24]
#0x35 data[7:0]
#0x36 data[15:8]
#0x37 data[23:16]
#0x38 data[31:24]"

# To enable I2C access to Marvell GW switch EEPROM we are writing to register 0xC ("Misc. Control Register" in CPLD register map spec.).
# Setting bit 3 ("geSwI2cSel" in CPLD register map spec.) enables EEPROM access. The other bits are not modified from default values.

# enable access to GE switch EEPROM
oob_switch_eeprom_select() {

    i2cset -f -y 12 0x31 0x0c
    i2cset -f -y 12 0x32 0x00
    i2cset -f -y 12 0x33 0x00
    i2cset -f -y 12 0x34 0x00
    i2cset -f -y 12 0x35 0x07
    i2cset -f -y 12 0x36 0x2a
    i2cset -f -y 12 0x30 0x0
}

# To enable I2C access to Marveell GW switch EEPROM we are writing to register 0xC ("Misc. Control Register" in CPLD register map spec.).
# Clearing bit 2 ("geSwI2cSel" in CPLD register map spec.) disable EEPROM access. The other bits are not modified from default values.

# disable access to GE switch EEPROM
oob_switch_eeprom_deselect() {

    i2cset -f -y 12 0x31 0x0c
    i2cset -f -y 12 0x32 0x00
    i2cset -f -y 12 0x33 0x00
    i2cset -f -y 12 0x34 0x00
    i2cset -f -y 12 0x35 0x03
    i2cset -f -y 12 0x36 0x2a
    i2cset -f -y 12 0x30 0x0
}

# For switch reset we are writing to register 0xC ("Misc. Control Register" in CPLD register map spec.).
# 1- First, setting bit 8 ("gwSwRst" in CPLD register map spec.) to put the switch in reset. The other bits are not modified from default values.
# 2- After 0.5 second, bit 8 ("gwSwRst" in CPLD register map spec.) is cleared to bring the switch out of reset.

# GE switch reset
oob_switch_reset() {

    i2cset -f -y 12 0x31 0x0c
    i2cset -f -y 12 0x32 0x00
    i2cset -f -y 12 0x33 0x00
    i2cset -f -y 12 0x34 0x00
    i2cset -f -y 12 0x35 0x03
    i2cset -f -y 12 0x36 0x2b
    i2cset -f -y 12 0x30 0x0
    sleep 0.5
    i2cset -f -y 12 0x31 0x0c
    i2cset -f -y 12 0x32 0x00
    i2cset -f -y 12 0x33 0x00
    i2cset -f -y 12 0x34 0x00
    i2cset -f -y 12 0x35 0x03
    i2cset -f -y 12 0x36 0x2a
    i2cset -f -y 12 0x30 0x0
}

# read bmc mac address from eeprom
read_mac_from_eeprom() {

    mac=00:00:00:00:00:00

    if [  -f  "/opt/cisco/bin/idprom" ]; then

        temp_mac=$(idprom /sys/bus/i2c/devices/8-0054/eeprom | grep MACADDR_BASE | awk '{print $2}' | cut -c1-12)
        if [ -z "$temp_mac" ]; then
            echo "mac address not found"
        else
            mac=$(sed -e "s/\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1:\2:\3:\4:\5:\6/" <<< "$temp_mac")
        fi

    else

        # Temporary workaround until we get the idprom utility via PR for BSP
        hexdump -ve '1/1 "%.2x"' /sys/bus/i2c/devices/8-0054/eeprom > /tmp/eeprom_data

        ((i = 0))
        while [[ $i -lt 512 ]]
        do
            var=$( dd skip=$i count=4 if=/tmp/eeprom_data bs=1 2> /dev/null )
            if [ "$var" = "cf06" ];then
                ((i = i + 4))
                mac1=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)
                ((i = i + 2))
                mac2=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)
                ((i = i + 2))
                mac3=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)
                ((i = i + 2))
                mac4=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)
                ((i = i + 2))
                mac5=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)
                ((i = i + 2))
                mac6=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)

                mac=$mac1:$mac2:$mac3:$mac4:$mac5:$mac6
                break
            fi
            ((i = i + 1))
        done
        rm /tmp/eeprom_data
    fi

    echo "$mac"
}

# read x86 mac address from eeprom
read_x86_mac_from_eeprom() {

    mac=00:00:00:00:00:00

    if [  -f  "/opt/cisco/bin/idprom" ]; then

            # This would provide the output for x86 mac address
	    temp_mac=$(idprom /sys/bus/i2c/devices/8-0054/eeprom | grep MACADDR_BASE | awk '{print $3}')
        if [ -z "$temp_mac" ]; then
            echo "mac address not found"
        else
            mac=$(sed -e "s/\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1:\2:\3:\4:\5:\6/" <<< "$temp_mac")
        fi

    else

        # Temporary workaround until we get the idprom utility via PR for BSP
        hexdump -ve '1/1 "%.2x"' /sys/bus/i2c/devices/8-0054/eeprom > /tmp/eeprom_data

        ((i = 0))
        ((j = 0))
        while [[ $i -lt 512 ]]
        do
            var=$( dd skip=$i count=4 if=/tmp/eeprom_data bs=1 2> /dev/null )
            if [ "$var" = "cf06" ];then
                ((j = j + 1))
                if [[ $j -eq 1 ]];then
                    ((i = i + 4))
                    continue
                fi
                ((i = i + 4))
                mac1=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)
                ((i = i + 2))
                mac2=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)
                ((i = i + 2))
                mac3=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)
                ((i = i + 2))
                mac4=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)
                ((i = i + 2))
                mac5=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)
                ((i = i + 2))
                mac6=$( dd skip=$i count=2 if=/tmp/eeprom_data bs=1 2> /dev/null)

                mac=$mac1:$mac2:$mac3:$mac4:$mac5:$mac6
                break
            fi
            ((i = i + 1))
        done
        rm /tmp/eeprom_data
    fi

    echo "$mac"
}


#!/bin/bash
#
# Copyright (c) 2022 Cisco Systems Inc.
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

### BEGIN INIT INFO
# Provides:          eth0_mac_fixup.sh
# Required-Start:
# Required-Stop:
# Default-Start:     S
# Default-Stop:
# Short-Description:  Fixup the MAC address for eth0 based on BMC EEPROM
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/opt/cisco/bin
. /usr/local/bin/board-utils.sh

# get the MAC from EEPROM
mac=$(read_mac_from_eeprom)
echo "mac is $mac"

# get the MAC from u-boot environment
ethaddr=$(fw_printenv | grep "^ethaddr=" | cut -d'=' -f2)

if [ "$mac" = "00:00:00:00:00:00" ] || [ "$mac" = "ff:ff:ff:ff:ff:ff" ]; then
    if [ -n "$ethaddr" ]; then
        # no MAC from EEPROM, use the one from u-boot environment
        echo "No MAC address from EEPROM: use $ethaddr from uboot-env"
        mac="$ethaddr"
    else
        echo "Error: unable to read MAC address from EEPROM or uboot-env!"
        mac=ba:d0:4a:9c:4e:ce
    fi
fi

if [ "$ethaddr" != "$mac" ]; then
    # set the MAC from EEPROM back to u-boot environment so that
    # u-boot can use it
    fw_setenv "ethaddr" "$mac"
fi

echo "Update BMC eth0 MAC address to $mac"
ip link set dev eth0 address "$mac"
exit $?