diff options
Diffstat (limited to 'util/flash_fp_mcu')
-rw-r--r-- | util/flash_fp_mcu | 750 |
1 files changed, 0 insertions, 750 deletions
diff --git a/util/flash_fp_mcu b/util/flash_fp_mcu deleted file mode 100644 index 679478f1e2..0000000000 --- a/util/flash_fp_mcu +++ /dev/null @@ -1,750 +0,0 @@ -#!/bin/bash -# Copyright 2019 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -. /usr/share/misc/shflags - -readonly DEFAULT_RETRIES=${DEFAULT_RETRIES:-4} -readonly STM32MON_CONNECT_RETRIES=${STM32MON_CONNECT_RETRIES:-6} -readonly STM32MON_SERIAL_BAUDRATE=${STM32MON_SERIAL_BAUDRATE:-115200} - -DEFINE_boolean 'read' "${FLAGS_FALSE}" 'Read instead of write' 'r' -# Both flash read and write protection are removed by default, but you -# can optionally enable them (for testing purposes). -DEFINE_boolean 'remove_flash_read_protect' "${FLAGS_TRUE}" \ - 'Remove flash read protection while performing command' 'U' -DEFINE_boolean 'remove_flash_write_protect' "${FLAGS_TRUE}" \ - 'Remove flash write protection while performing command' 'u' -DEFINE_integer 'retries' "${DEFAULT_RETRIES}" 'Specify number of retries' 'R' -DEFINE_integer 'baudrate' "${STM32MON_SERIAL_BAUDRATE}" 'Specify UART baudrate' 'B' -DEFINE_boolean 'hello' "${FLAGS_FALSE}" 'Only ping the bootloader' 'H' -DEFINE_boolean 'services' "${FLAGS_TRUE}" \ - 'Stop and restart conflicting fingerprint services' 's' -FLAGS_HELP="Usage: ${0} [flags] [ec.bin]" - -# EXIT_SUCCESS=0 -# EXIT_FAILURE=1 -# EXIT_BASHBUILTIN=2 -readonly EXIT_ARGUMENT=3 -readonly EXIT_CONFIG=4 -readonly EXIT_PRECONDITION=5 -readonly EXIT_RUNTIME=6 - -# Process commandline flags -FLAGS "${@}" || exit "${EXIT_ARGUMENT}" -eval set -- "${FLAGS_ARGV}" - -readonly CROS_EC_SPI_MODALIAS_STR="of:NcrfpTCgoogle,cros-ec-spi" - -readonly CROS_EC_UART_MODALIAS_STR="of:NcrfpTCgoogle,cros-ec-uart" - -klog() { - echo "flash_fp_mcu: $*" > /dev/kmsg -} - -check_hardware_write_protect_disabled() { - local hardware_write_protect_state - if ! hardware_write_protect_state="$(crossystem wpsw_cur)"; then - echo "Failed to get hardware write protect status" >&2 - exit "${EXIT_PRECONDITION}" - fi - if [[ "${hardware_write_protect_state}" != "0" ]]; then - echo "Please make sure hardware write protect is disabled." - echo "See https://www.chromium.org/chromium-os/firmware-porting-guide/firmware-ec-write-protection" - exit "${EXIT_PRECONDITION}" - fi -} - -# Get the spiid for the fingerprint sensor based on the modalias -# string: https://crbug.com/955117 -get_spiid() { - # TODO(b/179533783): Fix modalias on strongbad and remove this bypass. - if [[ -n "${DEVICEID}" ]]; then - echo "${DEVICEID}" - return 0 - fi - - for dev in /sys/bus/spi/devices/*; do - if [[ "$(cat "${dev}/modalias")" == "${CROS_EC_SPI_MODALIAS_STR}" ]]; then - basename "${dev}" - return 0 - fi - done - - return 1 -} - -# Get the uartid for the fingerprint sensor based on the modalias -get_uartid() { - for dev in /sys/bus/serial/devices/*; do - if [ -f "${dev}/modalias" ]; then - if [[ "$(cat "${dev}/modalias")" == "${CROS_EC_UART_MODALIAS_STR}" ]]; then - basename "${dev}" - return 0 - fi - fi - done - - return 1 -} - -# Usage: gpio <unexport|export|in|out|0|1|get> <signal> [signal...] -gpio() { - local cmd="$1" - shift - - for signal in "$@"; do - case "${cmd}" in - unexport|export) - klog "Set gpio ${signal} to ${cmd}" - echo "${signal}" > "/sys/class/gpio/${cmd}" - ;; - in|out) - local direction="${cmd}" - klog "Set gpio ${signal} direction to ${direction}" - echo "${direction}" > "/sys/class/gpio/gpio${signal}/direction" - ;; - 0|1) - local value="${cmd}" - klog "Set gpio ${signal} to ${value}" - echo "${value}" > "/sys/class/gpio/gpio${signal}/value" - ;; - get) - local value="${cmd}" - klog "Get gpio ${signal}" - cat "/sys/class/gpio/gpio${signal}/value" - ;; - *) - echo "Invalid gpio command: ${cmd}" >&2 - exit "${EXIT_RUNTIME}" - ;; - esac - done -} - -# Usage: warn_gpio <signal> <expected_value> <msg> -warn_gpio() { - local signal=$1 - local expected_value=$2 - local msg=$3 - - local value - if ! value="$(gpio get "${signal}")"; then - echo "Error fetching gpio value ${signal}" >&2 - exit "${EXIT_RUNTIME}" - fi - - if [[ "${value}" != "${expected_value}" ]]; then - echo "${msg}" >&2 - return 1 - fi -} - -# Taken verbatim from -# https://chromium.googlesource.com/chromiumos/docs/+/master/lsb-release.md#shell -# This should not be used by anything except get_platform_name. -# See https://crbug.com/98462. -lsbval() { - local key="$1" - local lsbfile="${2:-/etc/lsb-release}" - - if ! echo "${key}" | grep -Eq '^[a-zA-Z0-9_]+$'; then - return 1 - fi - - sed -E -n -e \ - "/^[[:space:]]*${key}[[:space:]]*=/{ - s:^[^=]+=[[:space:]]*:: - s:[[:space:]]+$:: - p - }" "${lsbfile}" -} - -# Get the underlying board (reference design) that we're running on (not the -# FPMCU or sensor). -# This may be an extended platform name, like nami-kernelnext, hatch-arc-r, -# or hatch-borealis. -get_platform_name() { - local platform_name - - # We used to use "cros_config /identity platform-name", but that is specific - # to mosys and does not actually provide the board name in all cases. - # cros_config intentionally does not provide a way to get the board - # name: b/156650654. - - # If there was a way to get the board name from cros_config, it's possible - # that it could fail in the following cases: - # - # 1) We're running on a non-unibuild device (the only one with FP is nocturne) - # 2) We're running on a proto device during bringup and the cros_config - # settings haven't yet been setup. - # - # In all cases we can fall back to /etc/lsb-release. It's not recommended - # to do this, but we don't have any other options in this case. - echo "Getting platform name from /etc/lsb-release." 1>&2 - platform_name="$(lsbval "CHROMEOS_RELEASE_BOARD")" - if [[ -z "${platform_name}" ]]; then - return 1 - fi - - echo "${platform_name}" -} - -# Given a full platform name, extract the base platform. -# -# Tests are also run on modified images, like hatch-arc-r, hatch-borealis, or -# hatch-kernelnext. These devices still have fingerprint and are expected to -# pass tests. The full platform name reflects these modifications and might -# be needed to apply an alternative configuration (kernelnext). Other modified -# tests (arc-r) just need to default to the base platform config, which is -# identified by this function. -# See b/186697064. -# -# Examples: -# * platform_base_name "hatch-kernelnext" --> "hatch" -# * platform_base_name "hatch-arc-r" --> "hatch" -# * platform_base_name "hatch-borealis" --> "hatch" -# * platform_base_name "hatch" --> "hatch" -# -# Usage: platform_base_name <platform_name> -platform_base_name() { - local platform_name="$1" - - # We remove any suffix starting at the first '-'. - echo "${platform_name%%-*}" -} - -get_default_fw() { - local board - board="$(cros_config /fingerprint board)" - - # If cros_config returns "", that is okay assuming there is only - # one firmware file on disk. - - local -a fws - mapfile -t fws < <(find /opt/google/biod/fw -name "${board}*.bin") - - if [[ "${#fws[@]}" -ne 1 ]]; then - return 1 - fi - - echo "${fws[0]}" -} - -# Find processes that have the named file, active or deleted, open. -# -# Deleted files are important because unbinding/rebinding cros-ec -# with biod/timberslide running will result in the processes holding open -# a deleted version of the files. Issues can arise if the process continue -# to interact with the deleted files (ex kernel panic) while the raw driver -# is being used in flash_fp_mcu. The lsof and fuser tools can't seem to -# identify usages of the deleted named file directly, without listing all -# files. This takes a large amount out time on Chromebooks, thus we need this -# custom search routine. -# -# Usage: proc_open_file [file_pattern] -proc_open_file() { - local file_pattern="$1" - - # Avoid overloading kernel max arguments with the number of file names. - local -a FDS=( /proc/*/fd/* ) - xargs ls -l <<<"${FDS[*]}" 2>/dev/null | grep "${file_pattern}" | \ - awk '{split($9,p,"/"); print "PID", p[3], "->", $11, $12}' - return "${PIPESTATUS[1]}" -} - -flash_fp_mcu_stm32() { - local transport="${1}" - local device="${2}" - local gpio_nrst="${3}" - local gpio_boot0="${4}" - local gpio_pwren="${5}" - local file="${6}" - local deviceid - - local stm32mon_flags="-p --retries ${STM32MON_CONNECT_RETRIES}" - - if [[ "${transport}" == "UART" ]]; then - stm32mon_flags+=" --baudrate ${FLAGS_baudrate} --device ${device}" - else - stm32mon_flags+=" -s ${device}" - fi - - if [[ "${FLAGS_hello}" -eq "${FLAGS_FALSE}" ]]; then - if [[ "${FLAGS_remove_flash_write_protect}" -eq "${FLAGS_TRUE}" ]]; then - stm32mon_flags+=" -u" - fi - - if [[ "${FLAGS_remove_flash_read_protect}" -eq "${FLAGS_TRUE}" ]]; then - stm32mon_flags+=" -U" - fi - - if [[ "${FLAGS_read}" -eq "${FLAGS_TRUE}" ]]; then - # Read from FPMCU to file - if [[ -e "${file}" ]]; then - echo "Output file already exists: ${file}" - return "${EXIT_PRECONDITION}" - fi - echo "# Reading to '${file}' over ${transport}" - stm32mon_flags+=" -r ${file}" - else - # Write to FPMCU from file - if [[ ! -f "${file}" ]]; then - echo "Invalid image file: ${file}" - return "${EXIT_PRECONDITION}" - fi - echo "# Flashing '${file}' over ${transport}" - stm32mon_flags+=" -e -w ${file}" - fi - else - echo "# Saying hello over ${transport}" - fi - - - check_hardware_write_protect_disabled - - if [[ "${transport}" == "UART" ]]; then - if ! deviceid="$(get_uartid)"; then - echo "Unable to find FP sensor UART device: ${CROS_EC_UART_MODALIAS_STR}" - return "${EXIT_PRECONDITION}" - fi - else - - if ! deviceid="$(get_spiid)"; then - echo "Unable to find FP sensor SPI device: ${CROS_EC_SPI_MODALIAS_STR}" - return "${EXIT_PRECONDITION}" - fi - fi - - echo "Flashing ${transport} device ID: ${deviceid}" - - # Remove cros_fp if present - klog "Unbinding cros-ec driver" - if [[ "${transport}" == "UART" ]]; then - echo "${deviceid}" > /sys/bus/serial/drivers/cros-ec-uart/unbind - else - echo "${deviceid}" > /sys/bus/spi/drivers/cros-ec-spi/unbind - fi - - # Configure the MCU Boot0 and NRST GPIOs - gpio export "${gpio_boot0}" "${gpio_nrst}" - gpio out "${gpio_boot0}" "${gpio_nrst}" - - # Reset sequence to enter bootloader mode - gpio 1 "${gpio_boot0}" - gpio 0 "${gpio_nrst}" - sleep 0.001 - - klog "Binding raw driver" - if [[ "${transport}" == "UART" ]]; then - # load AMDI0020:01 ttyS1 - echo AMDI0020:01 > /sys/bus/platform/drivers/dw-apb-uart/unbind; - echo AMDI0020:01 > /sys/bus/platform/drivers/dw-apb-uart/bind; - else - echo spidev > "/sys/bus/spi/devices/${deviceid}/driver_override" - echo "${deviceid}" > /sys/bus/spi/drivers/spidev/bind - # The following sleep is a workaround to mitigate the effects of a - # poorly behaved chip select line. See b/145023809. - fi - sleep 0.5 - - # We do not expect the drivers to change the pin state when binding. - # If you receive this warning, the driver needs to be fixed on this board - # and this flash attempt will probably fail. - warn_gpio "${gpio_boot0}" 1 \ - "WARNING: One of the drivers changed BOOT0 pin state on bind attempt." - warn_gpio "${gpio_nrst}" 0 \ - "WARNING: One of the drivers changed NRST pin state on bind attempt." - - if [[ ! -c "${device}" ]]; then - echo "Failed to bind raw device driver." >&2 - return "${EXIT_RUNTIME}" - fi - - local attempt=0 - local cmd_exit_status=1 - local cmd="stm32mon ${stm32mon_flags}" - - for attempt in $(seq "${FLAGS_retries}"); do - # Reset sequence to enter bootloader mode - gpio 0 "${gpio_nrst}" - sleep 0.01 - - # Release reset as the SPI bus is now ready - gpio 1 "${gpio_nrst}" - - # As per section '68: Bootloader timings' from application note below: - # https://www.st.com/resource/en/application_note/cd00167594-stm32-microcontroller-system-memory-boot-mode-stmicroelectronics.pdf - # bootloader startup time is 16.63 ms for STM32F74xxx/75xxx and 53.975 ms - # for STM32H74xxx/75xxx. SPI needs 1 us delay for one SPI byte sending. - # Keeping some margin, add delay of 100 ms to consider minimum bootloader - # startup time after the reset for stm32 devices. - sleep 0.1 - - # Print out the actual underlying command we're running and run it - echo "# ${cmd}" - ${cmd} - cmd_exit_status=$? - - if [[ "${cmd_exit_status}" -eq 0 ]]; then - break - fi - echo "# Attempt ${attempt} failed." - echo - sleep 1 - done - - # unload device - if [[ "${transport}" != "UART" ]]; then - klog "Unbinding raw driver" - echo "${deviceid}" > /sys/bus/spi/drivers/spidev/unbind - fi - - # Go back to normal mode - gpio out "${gpio_nrst}" - gpio 0 "${gpio_boot0}" "${gpio_nrst}" - gpio 1 "${gpio_nrst}" - - # Give up GPIO control, unless we need to keep these driving as - # outputs because they're not open-drain signals. - # TODO(b/179839337): Make this the default and properly support - # open-drain outputs on other platforms. - if [[ "${PLATFORM_NAME}" != "strongbad" ]] && - [[ "${PLATFORM_NAME}" != "herobrine" ]]; then - gpio in "${gpio_boot0}" "${gpio_nrst}" - fi - gpio unexport "${gpio_boot0}" "${gpio_nrst}" - - # Dartmonkey's RO has a flashprotect logic issue that forces reboot loops - # when SW-WP is enabled and HW-WP is disabled. It is avoided if a POR is - # detected on boot. We force a POR here to ensure we avoid this reboot loop. - # See to b/146428434. - if [[ "${gpio_pwren}" -gt 0 ]]; then - echo "Power cycling the FPMCU." - gpio export "${gpio_pwren}" - gpio out "${gpio_pwren}" - gpio 0 "${gpio_pwren}" - # Must outlast hardware soft start, which is typically ~3ms. - sleep 0.5 - gpio 1 "${gpio_pwren}" - # Power enable line is externally pulled down, so leave as output-high. - gpio unexport "${gpio_pwren}" - fi - - # Put back cros_fp driver if transport is SPI - if [[ "${transport}" != "UART" ]]; then - # wait for FP MCU to come back up (including RWSIG delay) - sleep 2 - klog "Binding cros-ec driver" - echo "" > "/sys/bus/spi/devices/${deviceid}/driver_override" - echo "${deviceid}" > /sys/bus/spi/drivers/cros-ec-spi/bind - fi - - if [[ "${cmd_exit_status}" -ne 0 ]]; then - return "${EXIT_RUNTIME}" - fi - - # Inform user to reboot if transport is UART. - # Display fw version is transport is SPI - if [[ "${transport}" == "UART" ]]; then - echo "Please reboot this device." - else - # Test it - klog "Query version and reset flags" - ectool --name=cros_fp version - ectool --name=cros_fp uptimeinfo - fi -} - -config_hatch() { - readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev1.1" - # See - # third_party/coreboot/src/soc/intel/cannonlake/include/soc/gpio_soc_defs.h - # for pin name to number mapping. - # Examine `cat /sys/kernel/debug/pinctrl/INT34BB:00/gpio-ranges` on a hatch - # device to determine gpio number from pin number. - readonly GPIO_CHIP="gpiochip200" - # FPMCU RST_ODL is on GPP_A12 = 200 + 12 = 212 - readonly GPIO_NRST=212 - # FPMCU BOOT0 is on GPP_A22 = 200 + 22 = 222 - readonly GPIO_BOOT0=222 - # FP_PWR_EN is on GPP_C11 = 456 + (192 - 181) = 456 + 11 = 467 - readonly GPIO_PWREN=467 -} - -config_herobrine() { - readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev11.0" - # TODO(b/179533783): Fix this script to look for non-ACPI modalias - readonly DEVICEID="spi11.0" - - readonly GPIO_CHIP="gpiochip336" - # FPMCU RST_ODL is $(gpiofind FP_RST_L) is gpiochip0 78 - readonly GPIO_NRST=$((336 + $(gpiofind FP_RST_L|cut -f2 -d" "))) - # FPMCU BOOT0 is $(gpiofind FPMCU_BOOT0) is gpiochip0 77 - readonly GPIO_BOOT0=$((336 + $(gpiofind FPMCU_BOOT0|cut -f2 -d" "))) - # EN FP RAILS is $(gpiofind EN_FP_RAILS) is gpiochip0 42 - readonly GPIO_PWREN=$((336 + $(gpiofind EN_FP_RAILS|cut -f2 -d" "))) -} - -config_nami() { - readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev32765.0" - - readonly GPIO_CHIP="gpiochip360" - # FPMCU RST_ODL is on GPP_C9 = 360 + 57 = 417 - readonly GPIO_NRST=417 - # FPMCU BOOT0 is on GPP_D5 = 360 + 77 = 437 - readonly GPIO_BOOT0=437 - # FP_PWR_EN is on GPP_B11 = 360 + 35 = 395 - readonly GPIO_PWREN=395 -} - -config_nami-kernelnext() { - readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev1.0" - - readonly GPIO_CHIP="gpiochip360" - # FPMCU RST_ODL is on GPP_C9 = 360 + 57 = 417 - readonly GPIO_NRST=417 - # FPMCU BOOT0 is on GPP_D5 = 360 + 77 = 437 - readonly GPIO_BOOT0=437 - # FP_PWR_EN is on GPP_B11 = 360 + 35 = 395 - readonly GPIO_PWREN=395 -} - -config_nocturne() { - readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev32765.0" - - readonly GPIO_CHIP="gpiochip360" - # FPMCU RST_ODL is on GPP_C10 = 360 + 58 = 418 - readonly GPIO_NRST=418 - # FPMCU BOOT0 is on GPP_C8 = 360 + 56 = 416 - readonly GPIO_BOOT0=416 - # FP_PWR_EN is on GPP_A11 = 360 + 11 = 371 - readonly GPIO_PWREN=371 -} - -config_nocturne-kernelnext() { - readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev1.0" - - readonly GPIO_CHIP="gpiochip360" - # FPMCU RST_ODL is on GPP_C10 = 360 + 58 = 418 - readonly GPIO_NRST=418 - # FPMCU BOOT0 is on GPP_C8 = 360 + 56 = 416 - readonly GPIO_BOOT0=416 - # FP_PWR_EN is on GPP_A11 = 360 + 11 = 371 - readonly GPIO_PWREN=371 -} - -config_strongbad() { - readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev10.0" - # TODO(b/179533783): Fix modalias on strongbad and remove this bypass. - readonly DEVICEID="spi10.0" - - readonly GPIO_CHIP="gpiochip392" - # FPMCU RST_ODL is $(gpiofind FP_RST_L) is gpiochip0 22 - readonly GPIO_NRST=$((392 + $(gpiofind FP_RST_L|cut -f2 -d" "))) - # FPMCU BOOT0 is $(gpiofind FPMCU_BOOT0) is gpiochip0 10 - readonly GPIO_BOOT0=$((392 + $(gpiofind FPMCU_BOOT0|cut -f2 -d" "))) - # TODO(b/179839337): Hardware currently doesn't support PWREN, but the - # next revision will. Add a comment here about the power enable gpio. - readonly GPIO_PWREN=-1 -} - -config_volteer() { - readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev1.0" - - # See kernel/v5.4/drivers/pinctrl/intel/pinctrl-tigerlake.c - # for pin name and pin number. - # Examine `cat /sys/kernel/debug/pinctrl/INT34C5:00/gpio-ranges` on a - # volteer device to determine gpio number from pin number. - # For example: GPP_C23 is UART2_CTS which can be queried from EDS - # the pin number is 194. From the gpio-ranges, the gpio value is - # 408 + (194-171) = 431 - - readonly GPIO_CHIP="gpiochip152" - # FPMCU RST_ODL is on GPP_C23 = 408 + (194 - 171) = 431 - readonly GPIO_NRST=431 - # FPMCU BOOT0 is on GPP_C22 = 408 + (193 - 171) = 430 - readonly GPIO_BOOT0=430 - # FP_PWR_EN is on GPP_A21 = 216 + (63 - 42) = 237 - readonly GPIO_PWREN=237 -} - -config_brya() { - readonly TRANSPORT="SPI" - readonly DEVICE="/dev/spidev0.0" - - # See kernel/v5.10/drivers/pinctrl/intel/pinctrl-tigerlake.c - # for pin name and pin number. - # Examine `cat /sys/kernel/debug/pinctrl/INTC1055:00/gpio-ranges` on a - # brya device to determine gpio number from pin number. - # For example: GPP_D1 is ISH_GP_1 which can be queried from EDS - # the pin number is 100 from the pinctrl-tigerlake.c. - # From the gpio-ranges, the gpio value is 312 + (100-99) = 313 - - readonly GPIO_CHIP="gpiochip152" - # FPMCU RST_ODL is on GPP_D1 = 312 + (100 - 99) = 313 - readonly GPIO_NRST=313 - # FPMCU BOOT0 is on GPP_D0 = 312 + (99 - 99) = 312 - readonly GPIO_BOOT0=312 - # FP_PWR_EN is on GPP_D2 = 312 + (101 - 99) = 314 - readonly GPIO_PWREN=314 -} - -config_zork() { - readonly TRANSPORT="UART" - readonly DEVICE="/dev/ttyS1" - - readonly GPIO_CHIP="gpiochip256" - # FPMCU RST_ODL is on AGPIO 11 = 256 + 11 = 267 - readonly GPIO_NRST=267 - # FPMCU BOOT0 is on AGPIO 69 = 256 + 69 = 325 - readonly GPIO_BOOT0=325 - # FPMCU PWR_EN is on AGPIO 32 = 256 + 32 = 288, but should not be - # necessary for flashing. Set invalid value. - readonly GPIO_PWREN=-1 -} - -config_guybrush() { - readonly TRANSPORT="UART" - - readonly DEVICE="/dev/ttyS1" - - readonly GPIO_CHIP="gpiochip256" - # FPMCU RST_ODL is on AGPIO 11 = 256 + 11 = 267 - readonly GPIO_NRST=267 - # FPMCU BOOT0 is on AGPIO 144 = 256 + 144 = 400 - readonly GPIO_BOOT0=400 - # FPMCU PWR_EN is on AGPIO 32 = 256 + 32 = 288, but should not be - # necessary for flashing. Set invalid value. - readonly GPIO_PWREN=-1 -} - -main() { - local filename="$1" - - # print out canonical path to differentiate between /usr/local/bin and - # /usr/bin installs - readlink -f "$0" - - # The "platform name" corresponds to the underlying board (reference design) - # that we're running on (not the FPMCU or sensor). At the moment all of the - # reference designs use the same GPIOs. If for some reason a design differs in - # the future, we will want to add a nested check in the config_<platform_name> - # function. Doing it in this manner allows us to reduce the number of - # configurations that we have to maintain (and reduces the amount of testing - # if we're only updating a specific config_<platform_name>). - if ! PLATFORM_NAME="$(get_platform_name)"; then - echo "Failed to get platform name" - exit "${EXIT_CONFIG}" - fi - readonly PLATFORM_NAME - - if ! PLATFORM_BASE_NAME="$(platform_base_name "${PLATFORM_NAME}")"; then - echo "Failed to get platform base name" - exit "${EXIT_CONFIG}" - fi - readonly PLATFORM_BASE_NAME - - echo "Platform name is ${PLATFORM_NAME} (${PLATFORM_BASE_NAME})." - - # Check that the config function exists - if [[ "$(type -t "config_${PLATFORM_NAME}")" == "function" ]]; then - readonly PLATFORM_CONFIG="${PLATFORM_NAME}" - elif [[ "$(type -t "config_${PLATFORM_BASE_NAME}")" == "function" ]]; then - readonly PLATFORM_CONFIG="${PLATFORM_BASE_NAME}" - else - echo "No config for platform ${PLATFORM_NAME}." >&2 - exit "${EXIT_CONFIG}" - fi - - echo "Using config for ${PLATFORM_CONFIG}." - - if ! "config_${PLATFORM_CONFIG}"; then - echo "Configuration failed for platform ${PLATFORM_CONFIG}." >&2 - exit "${EXIT_CONFIG}" - fi - - # Help the user out with defaults, if no *file* was given. - if [[ "$#" -eq 0 ]]; then - # If we are actually reading, set to a timestamped temp file. - if [[ "${FLAGS_read}" -eq "${FLAGS_TRUE}" ]]; then - filename="/tmp/fpmcu-fw-$(date --iso-8601=seconds).bin" - else - # Assume we are "writing" the default firmware to the FPMCU. - if ! filename="$(get_default_fw)"; then - echo "Failed to identify a default firmware file" >&2 - exit "${EXIT_CONFIG}" - fi - fi - fi - - # Check that the gpiochip exists - if [[ ! -e "/sys/class/gpio/${GPIO_CHIP}" ]]; then - echo "Cannot find GPIO chip: ${GPIO_CHIP}" - exit "${EXIT_CONFIG}" - fi - - if [[ "${FLAGS_services}" -eq "${FLAGS_TRUE}" ]]; then - echo "# Stopping biod and timberslide" - stop biod - stop timberslide LOG_PATH=/sys/kernel/debug/cros_fp/console_log - fi - - # If cros-ec driver isn't bound on startup, this means the final rebinding - # may fail. - if [[ ! -c "/dev/cros_fp" ]]; then - echo "WARNING: The cros-ec driver was not bound on startup." >&2 - fi - if [[ -c "${DEVICE}" ]]; then - echo "WARNING: The raw driver was bound on startup." >&2 - fi - local files_open - # Ensure no processes have cros_fp device or debug device open. - # This might be biod and/or timberslide. - if files_open=$(proc_open_file "/dev/cros_fp\|/sys/kernel/debug/cros_fp/*") - then - echo "WARNING: Another process has a cros_fp device file open." >&2 - echo "${files_open}" >&2 - echo "Try 'stop biod' and" >&2 - echo "'stop timberslide LOG_PATH=/sys/kernel/debug/cros_fp/console_log'" >&2 - echo "before running this script." >&2 - echo "See b/188985272." >&2 - fi - # Ensure no processes are using the raw driver. This might be a wedged - # stm32mon process spawned by this script. - if files_open=$(proc_open_file "${DEVICE}"); then - echo "WARNING: Another process has ${DEVICE} open." >&2 - echo "${files_open}" >&2 - echo "Try 'fuser -k ${DEVICE}' before running this script." >&2 - echo "See b/188985272." >&2 - fi - - local ret - flash_fp_mcu_stm32 \ - "${TRANSPORT}" \ - "${DEVICE}" \ - "${GPIO_NRST}" \ - "${GPIO_BOOT0}" \ - "${GPIO_PWREN}" \ - "${filename}" - ret=$? - - if [[ "${FLAGS_services}" -eq "${FLAGS_TRUE}" ]]; then - echo "# Restarting biod and timberslide" - start timberslide LOG_PATH=/sys/kernel/debug/cros_fp/console_log - start biod - fi - - exit "${ret}" -} - -main "$@" |