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