1#!/bin/bash 2 3# Disable check for usage of the definitions within mori-lib.sh 4#shellcheck disable=SC2034 5 6# get_gpio_num 7# Dynamically obtains GPIO number from chip base and I2C expanders 8# line-name 9function get_gpio_num() { 10 #shellcheck disable=SC2207 11 CHIP_PIN=($(gpiofind "$1" | awk '{print substr ($1, 9 ), $2 }')) 12 #shellcheck disable=SC2128 13 if [ -z "$CHIP_PIN" ]; then 14 echo "Could not find GPIO with name: $1" 15 return 1 16 fi 17 18 if [ "${CHIP_PIN[0]}" -gt 7 ]; then 19 BUS_ADDR=$(gpiodetect | grep gpiochip"${CHIP_PIN[0]}" | \ 20 grep -o '\[.*]' | tr -d ' \[\]') 21 GPIO_BASE_DIR=$(cd /sys/bus/i2c/devices/"$BUS_ADDR"/gpio/ || \ 22 exit; ls -1 -v) 23 # Check that there is a single gpiobank per i2c device 24 GPIO_BANKS=$(cd /sys/bus/i2c/devices/"$BUS_ADDR"/ || \ 25 exit ; ls -1 -d -v gpiochip*) 26 # Determine which GPIO_BASE to use based on the place of the GPIO_BANK 27 # in comparision to GPIO_BANKS 28 # gpiochip# is set in reverse order of numbering for location of 29 # GPIO_BASE_DIR 30 count=$(echo "$GPIO_BANKS" | wc -w) 31 for X in ${GPIO_BANKS} 32 do 33 if [[ $(gpiofind "$1" | cut -d " " -f 1) == "$X" ]]; then 34 # Used to select the correct GPIO_BASE value 35 #shellcheck disable=SC2086 36 GPIO_BASE_DIR=("$(echo ${GPIO_BASE_DIR} | cut -d " " -f $count)") 37 break 38 fi 39 count=$((count-1)) 40 done 41 tmp="/sys/bus/i2c/devices/$BUS_ADDR/gpio/${GPIO_BASE_DIR[0]}/base" 42 GPIO_BASE=$(cat "$tmp") 43 echo "$((GPIO_BASE+CHIP_PIN[1]))" 44 else 45 echo "$((CHIP_PIN[0]*32+CHIP_PIN[1]))" 46 fi 47} 48 49# set_gpio_ctrl 50# line-name, high(1)/low(0) 51function set_gpio_ctrl() { 52 #shellcheck disable=SC2046 53 gpioset $(gpiofind "$1")="$2" 54} 55 56# get_gpio_ctrl 57# line-name 58function get_gpio_ctrl() { 59 GPIO_NUM=$(get_gpio_num "$1") 60 echo "$GPIO_NUM" > /sys/class/gpio/export 61 # GPIOs added by drivers use different path for value most but not all 62 # drivers follow this trend 63 # Try reading like traditional GPIO, if fails, try reading in driver format 64 if ! cat /sys/class/gpio/gpio"$GPIO_NUM"/value 2> /dev/null ; then 65 cat /sys/class/gpio/"$1"/value 66 fi 67 echo "$GPIO_NUM" > /sys/class/gpio/unexport 68} 69 70 71function Does_File_Exist() { 72 local FILE=$1 73 74 if [[ ! -f "${FILE}" ]]; then 75 echo "${FILE} file does not exist" >&2 76 return 1 77 fi 78} 79 80function cleanup_bios_access() { 81 # Run only if setup_bios_access was previously ran 82 if Does_File_Exist /run/bios_access &> /dev/null ; then 83 # switch the SPI mux from BMC to Host 84 if [ -d "${KERNEL_SYSFS_FIU}/${KERNEL_FIU_ID}" ]; then 85 echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/unbind 86 fi 87 set_gpio_ctrl FM_BIOS_FLASH_SPI_MUX_R_SEL 0 88 89 # Indicate to host that BMC is finished accessing SPI 90 set_gpio_ctrl S0_BMC_SPI_NOR_ACCESS 0 91 92 rm /run/bios_access 93 fi 94} 95 96function setup_bios_access() { 97 # Run only if setup_bios_access was not previously ran without cleanup 98 if ! Does_File_Exist /run/bios_access &> /dev/null ; then 99 echo "BMC is accessing BIOS" > /run/bios_access 100 101 # rescan the spi bus 102 if [ -d "${KERNEL_SYSFS_FIU}/${KERNEL_FIU_ID}" ]; then 103 echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/unbind 104 usleep 100 105 fi 106 107 # Wait until the host is finished accessing the SPI 108 while [[ $(get_gpio_ctrl S0_SOC_SPI_NOR_ACCESS) == 1 ]] 109 do 110 sleep 1 111 done 112 # Indicate to host that BMC is accessing SPI 113 set_gpio_ctrl S0_BMC_SPI_NOR_ACCESS 1 114 115 # switch the SPI mux from Host to BMC 116 set_gpio_ctrl FM_BIOS_FLASH_SPI_MUX_R_SEL 1 117 118 echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/bind 119 fi 120} 121 122# Start definitions 123 124# I2C Definitions 125# The array is (<bus> <address>), where address is in hexadecimal. 126I2C_BMC_CPLD=(13 76) 127I2C_MB_CPLD=(0 76) 128I2C_FANCTRL=(35 2c) 129I2C_BMC_PWRSEQ=(48 59) 130I2C_MB_PWRSEQ=(40 40) 131I2C_CPU_EEPROM=(19 50) 132 133# File Path Definition 134# File path used to prevent hotswapping 135RST_LOCK_FILE="/etc/FW_FLASH_ONGOING" 136 137# Device name and driver path used for BIOS SPI 138KERNEL_FIU_ID="c0000000.spi" 139KERNEL_SYSFS_FIU="/sys/bus/platform/drivers/NPCM-FIU" 140