blob: 67636c19243ab400d48f5dacb029995259b57e2d [file] [log] [blame]
George Hung5f2142e2020-06-19 19:45:43 +08001#!/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 Williams8c226232023-04-15 20:05:21 -050017# shellcheck source=meta-quanta/meta-gbs/recipes-gbs/gbs-sysinit/files/gbs-gpio-common.sh
George Hung5f2142e2020-06-19 19:45:43 +080018source /usr/libexec/gbs-gpio-common.sh
19
20WD1RCR_ADDR=0xf080103c
21CORSTC_ADDR=0xf080105c
22BOARD_VER="" # Set by check_board_ver
23pe_eeprom_addr=( 50 54 )
24
25SERVICE_NAME="xyz.openbmc_project.Inventory.Manager"
26INTERFACE_NAME="xyz.openbmc_project.Inventory.Item"
27
George Hungcad17882020-09-02 22:20:04 +080028PE_PRESENT_OBJPATH=("/xyz/openbmc_project/inventory/system/chassis/entity/pe_slot0_prsnt"
29"/xyz/openbmc_project/inventory/system/chassis/entity/pe_slot1_prsnt")
George Hungcad17882020-09-02 22:20:04 +080030SATA0_PRESENT_OBJPATH="/xyz/openbmc_project/inventory/system/chassis/entity/sata0_prsnt"
31
George Hung5f2142e2020-06-19 19:45:43 +080032set_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
46get_board_rev_id() {
Patrick Williams8c226232023-04-15 20:05:21 -050047 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 Hung5f2142e2020-06-19 19:45:43 +080055 | sed 's/ //g' > ~/board_rev_id.txt
56}
57
58get_board_sku_id() {
Patrick Williams8c226232023-04-15 20:05:21 -050059 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 Hung5f2142e2020-06-19 19:45:43 +080063 | sed 's/ //g' > ~/board_sku_id.txt
64}
65
George Hung90588792020-10-14 18:01:37 +080066get_hsbp_board_rev_id() {
Patrick Williams8c226232023-04-15 20:05:21 -050067 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 Hung90588792020-10-14 18:01:37 +080071 | sed 's/ //g' > ~/hsbp_board_rev_id.txt
George Hung5f2142e2020-06-19 19:45:43 +080072}
73
74get_fan_board_rev_id() {
Patrick Williams8c226232023-04-15 20:05:21 -050075 echo "$(get_gpio_value 'FAN_BRD_REV_ID1')"\
76 "$(get_gpio_value 'FAN_BRD_REV_ID0')"\
George Hung5f2142e2020-06-19 19:45:43 +080077 | sed 's/ //g' > ~/fan_board_rev_id.txt
78}
79
80check_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
99check_board_sku() {
100 sku1_val=$(get_gpio_value 'BMC_BRD_SKU_ID1')
101 if (( sku1_val == 1 )); then
102 echo "GBS SKU!"
George Hung5f2142e2020-06-19 19:45:43 +0800103 else
104 echo "Other SKU!"
George Hung5f2142e2020-06-19 19:45:43 +0800105 fi
106}
107
108set_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
114set_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 Hung0a2c1052020-11-16 20:31:04 +0800117 mapper wait ${SATA0_PRESENT_OBJPATH}
George Hung5f2142e2020-06-19 19:45:43 +0800118 sata_prsnt_n="$(busctl get-property $SERVICE_NAME ${SATA0_PRESENT_OBJPATH} \
George Hung90588792020-10-14 18:01:37 +0800119 $INTERFACE_NAME Present)"
George Hung0a2c1052020-11-16 20:31:04 +0800120
George Hung5f2142e2020-06-19 19:45:43 +0800121 # sata_prsnt_n is active low => value "true" means low
George Hung947b9a42020-11-09 11:20:08 +0800122 if [[ ${sata_prsnt_n} == "b true" ]]; then
George Hung5f2142e2020-06-19 19:45:43 +0800123 set_gpio_direction 'HDD_PRSNT_N' low
124 else
125 set_gpio_direction 'HDD_PRSNT_N' high
126 fi
127}
128
George Hung8350dd72021-07-01 12:22:16 +0800129KERNEL_FIU_ID="c0000000.spi"
George Hung5f2142e2020-06-19 19:45:43 +0800130KERNEL_SYSFS_FIU="/sys/bus/platform/drivers/NPCM-FIU"
131
George Hung8350dd72021-07-01 12:22:16 +0800132# 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 Williams8c226232023-04-15 20:05:21 -0500135if ls "$KERNEL_SYSFS_FIU"/*.fiu 1> /dev/null 2>&1; then
Brandon Kimcbe8a9f2021-07-07 15:08:13 -0700136 KERNEL_FIU_ID="c0000000.fiu"
Patrick Williams8c226232023-04-15 20:05:21 -0500137fi
George Hung8350dd72021-07-01 12:22:16 +0800138
George Hung5f2142e2020-06-19 19:45:43 +0800139bind_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
147unbind_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}
153trap 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'
157findmtd() {
158 m=$(grep -xl "$1" /sys/class/mtd/*/name)
159 m=${m%/name}
160 m=${m##*/}
Patrick Williams8c226232023-04-15 20:05:21 -0500161 echo "$m"
George Hung5f2142e2020-06-19 19:45:43 +0800162}
163
164verify_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 Williams8c226232023-04-15 20:05:21 -0500175 sha256sum "/dev/${pnor_mtd}ro"
George Hung5f2142e2020-06-19 19:45:43 +0800176
177 echo "BIOS verification complete!"
178 unbind_host_mtd
179}
180
George Hung5f2142e2020-06-19 19:45:43 +0800181parse_pe_fru() {
182 pe_fruid=3
183 for i in {1..2};
184 do
Patrick Williams8c226232023-04-15 20:05:21 -0500185 mapper wait "${PE_PRESENT_OBJPATH[$((i-1))]}"
186 pe_prsnt_n="$(busctl get-property $SERVICE_NAME "${PE_PRESENT_OBJPATH[$((i-1))]}" \
George Hung90588792020-10-14 18:01:37 +0800187 $INTERFACE_NAME Present)"
George Hung5f2142e2020-06-19 19:45:43 +0800188
George Hung0a2c1052020-11-16 20:31:04 +0800189 if [[ ${pe_prsnt_n} == "b false" ]]; then
Patrick Williams8c226232023-04-15 20:05:21 -0500190 pe_fruid=$((pe_fruid+1))
George Hung5f2142e2020-06-19 19:45:43 +0800191 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 Williams8c226232023-04-15 20:05:21 -0500198 # shellcheck disable=SC2010
George Hung5f2142e2020-06-19 19:45:43 +0800199 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 Williams8c226232023-04-15 20:05:21 -0500206 if i2cget -f -y "$pe_fru_bus" "0x${pe_eeprom_addr[$j]}" 0x01 > /dev/null 2>&1 ; then
George Hung5f2142e2020-06-19 19:45:43 +0800207 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 Williams8c226232023-04-15 20:05:21 -0500211 phosphor-read-eeprom --eeprom "$pe_fru_bus" --fruid $pe_fruid
George Hung5f2142e2020-06-19 19:45:43 +0800212 break
213 fi
214 done
Patrick Williams8c226232023-04-15 20:05:21 -0500215 pe_fruid=$((pe_fruid+1))
George Hung5f2142e2020-06-19 19:45:43 +0800216 done
217}
218
219check_power_status() {
George Hung76c47ec2021-08-19 02:27:09 +0000220 res0="$(busctl get-property -j xyz.openbmc_project.State.Chassis \
George Hung5f2142e2020-06-19 19:45:43 +0800221 /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis \
222 CurrentPowerState | jq -r '.["data"]')"
Patrick Williams8c226232023-04-15 20:05:21 -0500223 echo "$res0"
George Hung5f2142e2020-06-19 19:45:43 +0800224}
225
George Hung8350dd72021-07-01 12:22:16 +0800226clk_buf_bus_switch="11-0076"
227clk_buf_driver="/sys/bus/i2c/drivers/pca954x/"
228
229bind_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 Hung5f2142e2020-06-19 19:45:43 +0800234main() {
235 get_board_rev_id
236 get_board_sku_id
George Hung90588792020-10-14 18:01:37 +0800237 get_hsbp_board_rev_id
238 get_fan_board_rev_id
George Hung5f2142e2020-06-19 19:45:43 +0800239
240 check_board_ver
241 if [[ "${BOARD_VER}" == "PREPVT" ]]; then
242 set_uart_en_low
243 fi
244
245 check_board_sku
246
George Hung5f2142e2020-06-19 19:45:43 +0800247 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 Hung76c47ec2021-08-19 02:27:09 +0000259 busctl set-property xyz.openbmc_project.State.Host \
George Hung5f2142e2020-06-19 19:45:43 +0800260 /xyz/openbmc_project/state/host0 \
261 xyz.openbmc_project.State.Host \
262 RequestedHostTransition s \
263 xyz.openbmc_project.State.Host.Transition.On
George Hung8350dd72021-07-01 12:22:16 +0800264
265 sleep 1
266 bind_clk_buf_switch
George Hung5f2142e2020-06-19 19:45:43 +0800267 else
268 echo "Host is already running, doing nothing!" >&2
269 fi
270
George Hung0a2c1052020-11-16 20:31:04 +0800271 set_hdd_prsnt
George Hung5f2142e2020-06-19 19:45:43 +0800272 parse_pe_fru
273}
274
275# Exit without running main() if sourced
Patrick Williams8c226232023-04-15 20:05:21 -0500276if ! (return 0 2>/dev/null) ; then
277 main "$@"
278fi