George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | # Copyright 2020 Google LLC |
| 3 | # Copyright 2020 Quanta Computer Inc. |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 17 | # shellcheck source=meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-gpio-common.sh |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 18 | source /usr/libexec/gbs-gpio-common.sh |
| 19 | |
| 20 | WD1RCR_ADDR=0xf080103c |
| 21 | CORSTC_ADDR=0xf080105c |
| 22 | BOARD_VER="" # Set by check_board_ver |
| 23 | pe_eeprom_addr=( 50 54 ) |
| 24 | |
| 25 | SERVICE_NAME="xyz.openbmc_project.Inventory.Manager" |
| 26 | INTERFACE_NAME="xyz.openbmc_project.Inventory.Item" |
| 27 | |
George Hung | cad1788 | 2020-09-02 22:20:04 +0800 | [diff] [blame] | 28 | PE_PRESENT_OBJPATH=("/xyz/openbmc_project/inventory/system/chassis/entity/pe_slot0_prsnt" |
| 29 | "/xyz/openbmc_project/inventory/system/chassis/entity/pe_slot1_prsnt") |
George Hung | cad1788 | 2020-09-02 22:20:04 +0800 | [diff] [blame] | 30 | SATA0_PRESENT_OBJPATH="/xyz/openbmc_project/inventory/system/chassis/entity/sata0_prsnt" |
| 31 | |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 32 | set_gpio_persistence() { |
| 33 | reg_val=$(devmem ${WD1RCR_ADDR} 32) |
| 34 | # Clear bit 16-23 to perserve all GPIO states across warm resets |
| 35 | reg_val=$(printf "0x%08x" $((reg_val & ~0xff0000))) |
| 36 | echo "Setting WD1RCR_ADDR to ${reg_val}" |
| 37 | devmem "${WD1RCR_ADDR}" 32 "${reg_val}" |
| 38 | |
| 39 | reg_val=$(devmem ${CORSTC_ADDR} 32) |
| 40 | # Clear bit 16-23 of CORSTC |
| 41 | reg_val=$(printf "0x%08x" $((reg_val & ~0xff0000))) |
| 42 | echo "Setting CORSTC_ADDR to ${reg_val}" |
| 43 | devmem "${CORSTC_ADDR}" 32 "${reg_val}" |
| 44 | } |
| 45 | |
| 46 | get_board_rev_id() { |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 47 | echo "$(get_gpio_value 'BMC_BRD_REV_ID7')"\ |
| 48 | "$(get_gpio_value 'BMC_BRD_REV_ID6')"\ |
| 49 | "$(get_gpio_value 'BMC_BRD_REV_ID5')"\ |
| 50 | "$(get_gpio_value 'BMC_BRD_REV_ID4')"\ |
| 51 | "$(get_gpio_value 'BMC_BRD_REV_ID3')"\ |
| 52 | "$(get_gpio_value 'BMC_BRD_REV_ID2')"\ |
| 53 | "$(get_gpio_value 'BMC_BRD_REV_ID1')"\ |
| 54 | "$(get_gpio_value 'BMC_BRD_REV_ID0')"\ |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 55 | | sed 's/ //g' > ~/board_rev_id.txt |
| 56 | } |
| 57 | |
| 58 | get_board_sku_id() { |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 59 | echo "$(get_gpio_value 'BMC_BRD_SKU_ID3')"\ |
| 60 | "$(get_gpio_value 'BMC_BRD_SKU_ID2')"\ |
| 61 | "$(get_gpio_value 'BMC_BRD_SKU_ID1')"\ |
| 62 | "$(get_gpio_value 'BMC_BRD_SKU_ID0')"\ |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 63 | | sed 's/ //g' > ~/board_sku_id.txt |
| 64 | } |
| 65 | |
George Hung | 9058879 | 2020-10-14 18:01:37 +0800 | [diff] [blame] | 66 | get_hsbp_board_rev_id() { |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 67 | echo "$(get_gpio_value 'HSBP_BRD_REV_ID3')"\ |
| 68 | "$(get_gpio_value 'HSBP_BRD_REV_ID2')"\ |
| 69 | "$(get_gpio_value 'HSBP_BRD_REV_ID1')"\ |
| 70 | "$(get_gpio_value 'HSBP_BRD_REV_ID0')"\ |
George Hung | 9058879 | 2020-10-14 18:01:37 +0800 | [diff] [blame] | 71 | | sed 's/ //g' > ~/hsbp_board_rev_id.txt |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 72 | } |
| 73 | |
| 74 | get_fan_board_rev_id() { |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 75 | echo "$(get_gpio_value 'FAN_BRD_REV_ID1')"\ |
| 76 | "$(get_gpio_value 'FAN_BRD_REV_ID0')"\ |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 77 | | sed 's/ //g' > ~/fan_board_rev_id.txt |
| 78 | } |
| 79 | |
| 80 | check_board_ver() { |
| 81 | # Sets BOARD_VER to either "PREPVT" or "PVT" |
| 82 | # |
| 83 | # BOARD_REV_ID[7:6] = |
| 84 | # 0x00 - EVT |
| 85 | # 0x01 - DVT |
| 86 | # 0x10 - PVT |
| 87 | # 0x11 - MP |
| 88 | |
| 89 | rev7_val=$(get_gpio_value 'BMC_BRD_REV_ID7') |
| 90 | if (( rev7_val == 0 )); then |
| 91 | echo "EVT/DVT rev!" |
| 92 | BOARD_VER="PREPVT" |
| 93 | else |
| 94 | echo "PVT/MP rev!" |
| 95 | BOARD_VER="PVT" |
| 96 | fi |
| 97 | } |
| 98 | |
| 99 | check_board_sku() { |
| 100 | sku1_val=$(get_gpio_value 'BMC_BRD_SKU_ID1') |
| 101 | if (( sku1_val == 1 )); then |
| 102 | echo "GBS SKU!" |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 103 | else |
| 104 | echo "Other SKU!" |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 105 | fi |
| 106 | } |
| 107 | |
| 108 | set_uart_en_low() { |
| 109 | # GPIO76 UART_EN polarity inverted between DVT/PVT |
| 110 | # Pin direction was set high in the kernel. |
| 111 | set_gpio_direction 'FM_BMC_CPU_UART_EN' low |
| 112 | } |
| 113 | |
| 114 | set_hdd_prsnt() { |
| 115 | # On PVT need to forward SATA0_PRSNT_N to HDD_PRSNT_N |
| 116 | # The signal is safe to set on DVT boards so just set universally. |
George Hung | 0a2c105 | 2020-11-16 20:31:04 +0800 | [diff] [blame] | 117 | mapper wait ${SATA0_PRESENT_OBJPATH} |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 118 | sata_prsnt_n="$(busctl get-property $SERVICE_NAME ${SATA0_PRESENT_OBJPATH} \ |
George Hung | 9058879 | 2020-10-14 18:01:37 +0800 | [diff] [blame] | 119 | $INTERFACE_NAME Present)" |
George Hung | 0a2c105 | 2020-11-16 20:31:04 +0800 | [diff] [blame] | 120 | |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 121 | # sata_prsnt_n is active low => value "true" means low |
George Hung | 947b9a4 | 2020-11-09 11:20:08 +0800 | [diff] [blame] | 122 | if [[ ${sata_prsnt_n} == "b true" ]]; then |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 123 | set_gpio_direction 'HDD_PRSNT_N' low |
| 124 | else |
| 125 | set_gpio_direction 'HDD_PRSNT_N' high |
| 126 | fi |
| 127 | } |
| 128 | |
George Hung | 8350dd7 | 2021-07-01 12:22:16 +0800 | [diff] [blame] | 129 | KERNEL_FIU_ID="c0000000.spi" |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 130 | KERNEL_SYSFS_FIU="/sys/bus/platform/drivers/NPCM-FIU" |
| 131 | |
George Hung | 8350dd7 | 2021-07-01 12:22:16 +0800 | [diff] [blame] | 132 | # the node of FIU is spi for kernel 5.10, but |
| 133 | # for less than or equal kernel 5.4, the node |
| 134 | # is fiu |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 135 | if ls "$KERNEL_SYSFS_FIU"/*.fiu 1> /dev/null 2>&1; then |
Brandon Kim | cbe8a9f | 2021-07-07 15:08:13 -0700 | [diff] [blame] | 136 | KERNEL_FIU_ID="c0000000.fiu" |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 137 | fi |
George Hung | 8350dd7 | 2021-07-01 12:22:16 +0800 | [diff] [blame] | 138 | |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 139 | bind_host_mtd() { |
| 140 | set_gpio_direction 'SPI_SW_SELECT' high |
| 141 | if [[ -d ${KERNEL_SYSFS_FIU}/${KERNEL_FIU_ID} ]]; then |
| 142 | echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/unbind |
| 143 | fi |
| 144 | echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/bind |
| 145 | } |
| 146 | |
| 147 | unbind_host_mtd() { |
| 148 | if [[ -d ${KERNEL_SYSFS_FIU}/${KERNEL_FIU_ID} ]]; then |
| 149 | echo "${KERNEL_FIU_ID}" > "${KERNEL_SYSFS_FIU}"/unbind |
| 150 | fi |
| 151 | set_gpio_direction 'SPI_SW_SELECT' low |
| 152 | } |
| 153 | trap unbind_host_mtd EXIT SIGHUP SIGINT SIGTERM |
| 154 | |
| 155 | # Taken from /run/initramfs/update |
| 156 | # Given label name, return mtd node. e.g. `findmtd bmc` returns 'mtd0' |
| 157 | findmtd() { |
| 158 | m=$(grep -xl "$1" /sys/class/mtd/*/name) |
| 159 | m=${m%/name} |
| 160 | m=${m##*/} |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 161 | echo "$m" |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 162 | } |
| 163 | |
| 164 | verify_host_bios() { |
| 165 | echo "BIOS verification start!" |
| 166 | |
| 167 | # placeholder for verifying host BIOS. For now time BIOS read |
| 168 | # with dd |
| 169 | bind_host_mtd || { echo "Failed to bind FIU driver for host MTD"; return 1; } |
| 170 | |
| 171 | pnor_mtd=$(findmtd pnor) |
| 172 | [[ -z "${pnor_mtd}" ]] && { echo "Failed to find host MTD partition!"; return 1; } |
| 173 | |
| 174 | # Test timing by computing SHA256SUM. |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 175 | sha256sum "/dev/${pnor_mtd}ro" |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 176 | |
| 177 | echo "BIOS verification complete!" |
| 178 | unbind_host_mtd |
| 179 | } |
| 180 | |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 181 | parse_pe_fru() { |
| 182 | pe_fruid=3 |
| 183 | for i in {1..2}; |
| 184 | do |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 185 | mapper wait "${PE_PRESENT_OBJPATH[$((i-1))]}" |
| 186 | pe_prsnt_n="$(busctl get-property $SERVICE_NAME "${PE_PRESENT_OBJPATH[$((i-1))]}" \ |
George Hung | 9058879 | 2020-10-14 18:01:37 +0800 | [diff] [blame] | 187 | $INTERFACE_NAME Present)" |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 188 | |
George Hung | 0a2c105 | 2020-11-16 20:31:04 +0800 | [diff] [blame] | 189 | if [[ ${pe_prsnt_n} == "b false" ]]; then |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 190 | pe_fruid=$((pe_fruid+1)) |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 191 | continue |
| 192 | fi |
| 193 | |
| 194 | # Output is the i2c bus number for the PCIE cards on PE0/PE1 |
| 195 | # i2c-0 -> i2c mux (addr: 0x71) -> PE0/PE1 |
| 196 | # PE0: channel 0 |
| 197 | # PE1: channel 1 |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 198 | # shellcheck disable=SC2010 |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 199 | pe_fru_bus="$(ls -al /sys/bus/i2c/drivers/pca954x/0-0071/ | grep channel \ |
| 200 | | awk -F "/" '{print $(NF)}' | awk -F "-" '{print $2}' | sed -n "${i}p")" |
| 201 | |
| 202 | # If the PE FRU EEPROM syspath does not exist, create it ("24c02" is the |
| 203 | # EEPROM part number) and perform a phosphor-read-eeprom |
| 204 | for ((j=0; j < ${#pe_eeprom_addr[@]}; j++)); |
| 205 | do |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 206 | if i2cget -f -y "$pe_fru_bus" "0x${pe_eeprom_addr[$j]}" 0x01 > /dev/null 2>&1 ; then |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 207 | if [ ! -f "/sys/bus/i2c/devices/$pe_fru_bus-00${pe_eeprom_addr[$j]}/eeprom" ]; then |
| 208 | echo 24c02 "0x${pe_eeprom_addr[$j]}" > "/sys/bus/i2c/devices/i2c-$pe_fru_bus/new_device" |
| 209 | fi |
| 210 | pe_fru_bus="/sys/bus/i2c/devices/$pe_fru_bus-00${pe_eeprom_addr[$j]}/eeprom" |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 211 | phosphor-read-eeprom --eeprom "$pe_fru_bus" --fruid $pe_fruid |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 212 | break |
| 213 | fi |
| 214 | done |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 215 | pe_fruid=$((pe_fruid+1)) |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 216 | done |
| 217 | } |
| 218 | |
| 219 | check_power_status() { |
George Hung | 76c47ec | 2021-08-19 02:27:09 +0000 | [diff] [blame] | 220 | res0="$(busctl get-property -j xyz.openbmc_project.State.Chassis \ |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 221 | /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis \ |
| 222 | CurrentPowerState | jq -r '.["data"]')" |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 223 | echo "$res0" |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 224 | } |
| 225 | |
George Hung | 8350dd7 | 2021-07-01 12:22:16 +0800 | [diff] [blame] | 226 | clk_buf_bus_switch="11-0076" |
| 227 | clk_buf_driver="/sys/bus/i2c/drivers/pca954x/" |
| 228 | |
| 229 | bind_clk_buf_switch() { |
| 230 | echo "Re-bind i2c bus 11 clk_buf_switch" |
| 231 | echo "${clk_buf_bus_switch}" > "${clk_buf_driver}"/bind |
| 232 | } |
| 233 | |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 234 | main() { |
| 235 | get_board_rev_id |
| 236 | get_board_sku_id |
George Hung | 9058879 | 2020-10-14 18:01:37 +0800 | [diff] [blame] | 237 | get_hsbp_board_rev_id |
| 238 | get_fan_board_rev_id |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 239 | |
| 240 | check_board_ver |
| 241 | if [[ "${BOARD_VER}" == "PREPVT" ]]; then |
| 242 | set_uart_en_low |
| 243 | fi |
| 244 | |
| 245 | check_board_sku |
| 246 | |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 247 | if [[ $(check_power_status) != \ |
| 248 | 'xyz.openbmc_project.State.Chassis.PowerState.On' ]]; then |
| 249 | verify_host_bios |
| 250 | |
| 251 | echo "Release host from reset!" >&2 |
| 252 | set_gpio_direction 'RST_BMC_RSMRST_N' high |
| 253 | set_gpio_direction 'RST_KBRST_BMC_CPLD_N' high |
| 254 | # TODO: remove the hack once kernel driver is ready |
| 255 | # Set the GPIO states to preserve across reboots |
| 256 | set_gpio_persistence |
| 257 | |
| 258 | echo "Starting host power!" >&2 |
George Hung | 76c47ec | 2021-08-19 02:27:09 +0000 | [diff] [blame] | 259 | busctl set-property xyz.openbmc_project.State.Host \ |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 260 | /xyz/openbmc_project/state/host0 \ |
| 261 | xyz.openbmc_project.State.Host \ |
| 262 | RequestedHostTransition s \ |
| 263 | xyz.openbmc_project.State.Host.Transition.On |
George Hung | 8350dd7 | 2021-07-01 12:22:16 +0800 | [diff] [blame] | 264 | |
| 265 | sleep 1 |
| 266 | bind_clk_buf_switch |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 267 | else |
| 268 | echo "Host is already running, doing nothing!" >&2 |
| 269 | fi |
| 270 | |
George Hung | 0a2c105 | 2020-11-16 20:31:04 +0800 | [diff] [blame] | 271 | set_hdd_prsnt |
George Hung | 5f2142e | 2020-06-19 19:45:43 +0800 | [diff] [blame] | 272 | parse_pe_fru |
| 273 | } |
| 274 | |
| 275 | # Exit without running main() if sourced |
Patrick Williams | 8c22623 | 2023-04-15 20:05:21 -0500 | [diff] [blame] | 276 | if ! (return 0 2>/dev/null) ; then |
| 277 | main "$@" |
| 278 | fi |