xref: /aosp_15_r20/external/gsc-utils/util/brescue.sh (revision 4f2df630800bdcf1d4f0decf95d8a1cb87344f5f)
1#!/bin/bash
2# Copyright 2021 The ChromiumOS Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5#
6# A script to facilitate rescue update of GSC targets, supports both Cr50 and
7# Ti50.
8#
9# The two input parameters are the file name of the full binary mage (both ROs
10# and both RWs) and the name of the UART device connected to the GSC console.
11#
12# The script carves out the RW_A from the binary, converts it into hex format
13# and starts the rescue utility to send the RW to the chip. The user is
14# supposed to reset the chip to trigger the rescue session.
15#
16# If invoked with RESCUE environment variable set to a path, the script will try
17# to use the rescue binary at that path.
18#
19# If invoked with nonempty NOCLEAN environment variable, the script preserves
20# the hex RW image it creates.
21#
22# If invoked with nonempty EARLY environment variable, the script passes the
23# --early option to rescue.
24
25TMPD="$(mktemp -d "/tmp/$(basename "$0").XXXXX")"
26
27for r in ${RESCUE} rescue cr50-rescue; do
28  if type "${r}" > /dev/null 2>&1; then
29    RESCUE="${r}"
30    break
31  fi
32done
33
34if [[ -z ${RESCUE} ]]; then
35  echo "rescue utility is not found, can not continue" >&2
36  exit 1
37fi
38if [[ -z "${NOCLEAN}" ]]; then
39  trap 'rm -rf "${TMPD}"' EXIT
40fi
41
42# --early could help to improve success rate depending on setup.
43early=''
44if [[ -n "${EARLY}" ]]; then
45  early='--early'
46fi
47
48dest_hex="${TMPD}/rw.hex"
49dest_bin="${TMPD}/rw.bin"
50errorf="${TMPD}/error"
51
52usage() {
53  cat >&2 <<EOF
54Two parameters are required, the name of the valid GSC binary image
55and the name of the H1 console tty device
56EOF
57  exit 1
58}
59
60# Determine RW_A offset of the Ti50 image. The header magic pattern is used to
61# find headers in the binary.
62rw_offset() {
63  local src
64  local base
65
66  src="$1"
67  # The second grep term filters out the 'fake' cryptolib header, which does
68  # not contain a valid signature, the signature field is filled with SSSSS
69  # (0x53...).
70  base=$(/usr/bin/od -Ax -t x1 -v "${src}" |
71    grep -E '^....00 fd ff ff ff' | grep -v '00 fd ff ff ff 53 53 53' |
72    head -2 |
73    tail -1 |
74    sed 's/ .*//')
75  printf '%d' "0x${base}"
76}
77
78if [[ $# != 2 ]]; then
79  usage
80fi
81
82source="$1"
83device="$2"
84
85if [[ ! -f ${source} ]]; then
86  usage
87fi
88
89if [[ ${device} != /dev/*  || ! -e ${device} ]]; then
90  usage
91fi
92
93pid="$(lsof "${device}" | awk -v v="${device}" '/v/ {print $2}')"
94if [[ -n ${pid} ]]; then
95  echo -n "${device} is in use, will try to kill process ${pid} "
96  deadline=$(( $(date '+%s') + 5 ))
97  kill -HUP "${pid}"
98  while [[ $(date '+%s') -le ${deadline} ]]; do
99    echo -n '.'
100    if [[ -z $(lsof "${device}") ]]; then
101      break
102    fi
103  done
104  if [[ -n $(lsof "${device}") ]]; then
105    printf "\nFailed to kill process using %s\n"  "${device}" >&2
106    exit 1
107  fi
108  echo " succeeded"
109fi
110
111# Use Cr50 or Ti50 options base on the file size.
112case "$(stat -c '%s' "${source}")" in
113  (524288)
114    skip=16384
115    count=233472
116    chip_extension=''
117    addr=0x44000
118    ;;
119  (1048576)
120    skip=$(rw_offset "${source}")
121    count=$(( 1048576/2 - "${skip}" ))
122    chip_extension='--dauntless'
123    addr="$(printf '0x%x' $(( 0x80000 + "${skip}" )))"
124    ;;
125  (*)
126    echo "Unrecognized input file" >&2
127    exit 1
128    ;;
129esac
130
131# Carve out RW_A in binary form.
132if ! dd if="${source}" of="${dest_bin}" skip="${skip}" count="${count}" bs=1 \
133  2>"${errorf}"; then
134  echo "Failed to carve out the RW bin:" >&2
135  cat "${errorf}" >&2
136  exit 1
137fi
138echo "carved out binary ${dest_bin} mapped to ${addr}"
139
140# Convert binary to hex.
141if ! objcopy -I binary -O ihex --change-addresses "${addr}" \
142  "${dest_bin}" "${dest_hex}"; then
143  echo "Failed to convert to hex" >&2
144  exit 1
145fi
146echo "converted to ${dest_hex}, waiting for target reset"
147
148echo "${RESCUE}"  "${chip_extension}" -d "${device}" "${early}" -v -i \
149  "${dest_hex}"
150"${RESCUE}"  "${chip_extension}" -d "${device}" "${early}" -v -i "${dest_hex}"
151