northbridge: Remove unneeded include <pc80/mc146818rtc.h>
[coreboot.git] / util / board_status / board_status.sh
blob0dc96e8bd79f9645d858aa528db822ea53f7ec41
1 #!/bin/sh
3 # This file is part of the coreboot project.
5 # Copyright (C) 2013 Google Inc.
6 # Copyright (C) 2014 Sage Electronic Engineering, LLC.
9 EXIT_SUCCESS=0
10 EXIT_FAILURE=1
12 # Stuff from command-line switches
13 COREBOOT_IMAGE="build/coreboot.rom"
14 REMOTE_HOST=""
15 REMOTE_PORT_OPTION=""
16 CLOBBER_OUTPUT=0
17 UPLOAD_RESULTS=0
18 SERIAL_PORT_SPEED=115200
20 # Used to specify whether a command should always be run locally or
21 # if command should be run remoteley when a remote host is specified.
22 LOCAL=0
23 REMOTE=1
24 FATAL=0
25 NONFATAL=1
27 # Used if cbmem is not in default $PATH, e.g. not installed or when using `sudo`
28 CBMEM_PATH=""
30 # test a command
32 # $1: 0 ($LOCAL) to run command locally,
33 # 1 ($REMOTE) to run remotely if remote host defined
34 # $2: command to test
35 # $3: 0 ($FATAL) Exit with an error if the command fails
36 # 1 ($NONFATAL) Don't exit on command test failure
37 test_cmd()
39 local rc
41 if [ -e "$2" ]; then
42 return
45 if [ "$1" -eq "$REMOTE" ] && [ -n "$REMOTE_HOST" ]; then
46 ssh $REMOTE_PORT_OPTION root@${REMOTE_HOST} command -v "$2" > /dev/null
47 rc=$?
48 else
49 command -v "$2" >/dev/null
50 rc=$?
53 if [ $rc -eq 0 ]; then
54 return 0
57 if [ "$3" = "1" ]; then
58 return 1
61 echo "$2 not found"
62 exit $EXIT_FAILURE
65 _cmd()
67 if [ -e "$2" ]; then
68 return $EXIT_FAILURE
71 if [ -n "$3" ]; then
72 pipe_location="${3}"
73 else
74 pipe_location="/dev/null"
77 if [ "$1" -eq "$REMOTE" ] && [ -n "$REMOTE_HOST" ]; then
78 ssh $REMOTE_PORT_OPTION "root@${REMOTE_HOST}" "$2" > "$pipe_location" 2>&1
79 else
80 $2 > "$pipe_location" 2>&1
83 return $?
86 # run a command
88 # $1: 0 ($LOCAL) to run command locally,
89 # 1 ($REMOTE) to run remotely if remote host defined
90 # $2: command
91 # $3: filename to direct output of command into
92 cmd()
94 _cmd $1 "$2" "$3"
96 if [ $? -eq 0 ]; then
97 return
100 echo "Failed to run \"$2\", aborting"
101 rm -f "$3" # don't leave an empty file
102 exit $EXIT_FAILURE
105 # run a command where failure is considered to be non-fatal
107 # $1: 0 ($LOCAL) to run command locally,
108 # 1 ($REMOTE) to run remotely if remote host defined
109 # $2: command
110 # $3: filename to direct output of command into
111 cmd_nonfatal()
113 _cmd $1 "$2" "$3"
115 if [ $? -eq 0 ]; then
116 return
119 echo "Failed to run \"$2\", ignoring"
120 rm -f "$3" # don't leave an empty file
123 # read from a serial port device
125 # $1: serial device to read from
126 # $2: serial port speed
127 # $3: filename to direct output of command into
128 get_serial_bootlog () {
130 local TTY=$1
131 local SPEED=$2
132 local FILENAME=$3
134 if [ ! -c "$TTY" ]; then
135 echo "$TTY is not a valid serial device"
136 exit $EXIT_FAILURE
139 # make the text more noticible
140 test_cmd $LOCAL "tput" $NONFATAL
141 tput_not_available=$?
142 if [ $tput_not_available -eq 0 ]; then
143 tput bold
144 tput setaf 10 # set bright green
147 echo
148 echo "Waiting to receive boot log from $TTY"
149 echo "Press [Enter] when the boot is complete."
150 echo
152 if [ $tput_not_available -eq 0 ]; then
153 tput sgr0
156 # set up the serial port
157 stty -F $TTY $SPEED cs8 -cstopb -parenb clocal
159 # read from the serial port - user must press enter when complete
160 test_cmd $LOCAL "tee"
161 while read LINE; do
162 echo "$LINE" | tee -a "$FILENAME"
163 done < "$SERIAL_DEVICE" &
164 PID=$!
166 read foo
167 kill "$PID" 2>/dev/null
169 echo "Finished reading boot log."
172 show_help() {
173 echo "Usage:
174 ${0} <option>
176 Options
177 -c, --cbmem
178 Path to cbmem on device under test (DUT).
179 -C, --clobber
180 Clobber temporary output when finished. Useful for debugging.
181 -h, --help
182 Show this message.
183 -i, --image <image>
184 Path to coreboot image (Default is $COREBOOT_IMAGE).
185 -r, --remote-host <host>
186 Obtain machine information from remote host (using ssh).
187 -s, --serial-device </dev/xxx>
188 Obtain boot log via serial device.
189 -S, --serial-speed <speed>
190 Set the port speed for the serial device (Default is $SERIAL_PORT_SPEED).
191 -u, --upload-results
192 Upload results to coreboot.org.
194 Long options:
195 --ssh-port <port>
196 Use a specific SSH port.
200 getopt -T
201 if [ $? -ne 4 ]; then
202 echo "GNU-compatible getopt(1) required."
203 exit $EXIT_FAILURE
206 LONGOPTS="cbmem:,clobber,help,image:,remote-host:,upload-results"
207 LONGOPTS="${LONGOPTS},serial-device:,serial-speed:"
208 LONGOPTS="${LONGOPTS},ssh-port:"
210 ARGS=$(getopt -o c:Chi:r:s:S:u -l "$LONGOPTS" -n "$0" -- "$@");
211 if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
212 eval set -- "$ARGS"
213 while true ; do
214 case "$1" in
215 # generic options
216 -c|--cbmem)
217 shift
218 CBMEM_PATH="$1"
220 -C|--clobber)
221 CLOBBER_OUTPUT=1
223 -h|--help)
224 show_help
225 exit $EXIT_SUCCESS
227 -i|--image)
228 shift
229 COREBOOT_IMAGE="$1"
231 -r|--remote-host)
232 shift
233 REMOTE_HOST="$1"
235 -u|--upload-results)
236 UPLOAD_RESULTS=1
239 # serial port options
240 -s|--serial-device)
241 shift
242 SERIAL_DEVICE="$1"
244 -S|--serial-speed)
245 shift
246 SERIAL_PORT_SPEED="$1"
249 # ssh options
250 --ssh-port)
251 shift
252 REMOTE_PORT_OPTION="-p $1"
255 # error handling
257 shift
258 if [ -n "$*" ]; then
259 echo "Non-option parameters detected: '$*'"
260 exit $EXIT_FAILURE
262 break
265 echo "error processing options at '$1'"
266 exit $EXIT_FAILURE
267 esac
268 shift
269 done
271 grep -rH 'coreboot.org' .git/config >/dev/null 2>&1
272 if [ $? -ne 0 ]; then
273 echo "Script must be run from root of coreboot directory"
274 exit $EXIT_FAILURE
277 if [ ! -e "$COREBOOT_IMAGE" ]; then
278 echo "board_status needs $COREBOOT_IMAGE, but it does not exist."
279 echo "Use \"-i IMAGE_FILE\" to select a different image, or \"--help\" for more options."
280 exit $EXIT_FAILURE
283 # Results will be placed in a temporary location until we're ready to upload.
284 # If the user does not wish to upload, results will remain in /tmp.
285 tmpdir=$(mktemp -d --tmpdir coreboot_board_status.XXXXXXXX)
287 # Obtain coreboot config by running cbfstool on the ROM image. cbfstool may
288 # already exist in build/ or util/cbfstool/, but if not then we'll build it
289 # now and clean it when we're done.
290 cbfstool_cmd="build/cbfstool"
291 do_clean_cbfstool=0
292 if [ ! -x $cbfstool_cmd ]; then
293 cbfstool_cmd="util/cbfstool/cbfstool"
294 if [ -e $cbfstool_cmd ]; then
295 if test ! -x $cbfstool_cmd; then
296 echo "Cannot execute $cbfstool_cmd."
297 exit $EXIT_FAILURE
299 else
300 make -C util/cbfstool/
301 do_clean_cbfstool=1
304 test_cmd $LOCAL "$cbfstool_cmd"
306 tmpcfg=$(mktemp coreboot_config.XXXXXX)
307 echo "Extracting config.txt from $COREBOOT_IMAGE"
308 $cbfstool_cmd "$COREBOOT_IMAGE" extract -n config -f "${tmpdir}/config.txt" >/dev/null 2>&1
309 mv "${tmpdir}/config.txt" "${tmpdir}/config.short.txt"
310 cp "${tmpdir}/config.short.txt" "${tmpcfg}"
311 yes "" | make "DOTCONFIG=${tmpcfg}" oldconfig 2>/dev/null >/dev/null
312 mv "${tmpcfg}" "${tmpdir}/config.txt"
313 rm -f "${tmpcfg}.old"
314 $cbfstool_cmd "$COREBOOT_IMAGE" print > "${tmpdir}/cbfs.txt"
315 rom_contents=$($cbfstool_cmd "$COREBOOT_IMAGE" print 2>&1)
316 if [ -n "$(echo $rom_contents | grep payload_config)" ]; then
317 echo "Extracting payload_config from $COREBOOT_IMAGE"
318 $cbfstool_cmd "$COREBOOT_IMAGE" extract -n payload_config -f "${tmpdir}/payload_config.txt" >/dev/null 2>&1
320 if [ -n "$(echo $rom_contents | grep payload_version)" ]; then
321 echo "Extracting payload_version from $COREBOOT_IMAGE"
322 $cbfstool_cmd "$COREBOOT_IMAGE" extract -n payload_version -f "${tmpdir}/payload_version.txt" >/dev/null 2>&1
324 md5sum -b "$COREBOOT_IMAGE" > "${tmpdir}/rom_checksum.txt"
326 if test $do_clean_cbfstool -eq 1; then
327 make -C util/cbfstool clean
330 # Obtain board and revision info to form the directory structure:
331 # <vendor>/<board>/<revision>/<timestamp>
332 mainboard_dir="$(grep CONFIG_MAINBOARD_DIR "${tmpdir}/config.txt" | awk -F '"' '{ print $2 }')"
333 vendor=$(echo "$mainboard_dir" | awk -F '/' '{ print $1 }')
334 mainboard=$(echo "$mainboard_dir" | awk -F '/' '{ print $2 }')
336 getrevision="util/board_status/getrevision.sh"
337 test_cmd $LOCAL $getrevision
338 tagged_version=$($getrevision -T)
339 timestamp=$($getrevision -t)
341 results="${vendor}/${mainboard}/${tagged_version}/${timestamp}"
343 if [ -n "$(echo $tagged_version | grep dirty)" ]; then
344 echo "The repository is in a dirty state. Please see the output of"
345 echo "'git status' below."
346 git status
347 exit $EXIT_FAILURE
350 echo "Temporarily placing output in ${tmpdir}/${results}"
351 mkdir -p "${tmpdir}/${results}"
353 mv "${tmpdir}/config.txt" "${tmpdir}/${results}"
354 test -f "${tmpdir}/payload_config.txt" && mv "${tmpdir}/payload_config.txt" "${tmpdir}/${results}"
355 test -f "${tmpdir}/payload_version.txt" && mv "${tmpdir}/payload_version.txt" "${tmpdir}/${results}"
356 mv "${tmpdir}/config.short.txt" "${tmpdir}/${results}"
357 mv "${tmpdir}/cbfs.txt" "${tmpdir}/${results}"
358 mv "${tmpdir}/rom_checksum.txt" "${tmpdir}/${results}"
360 touch "${tmpdir}/${results}/revision.txt"
361 printf "Local revision: %s\n" "$($getrevision -l)" >> "${tmpdir}/${results}/revision.txt"
362 printf "Tagged revision: %s\n" "${tagged_version}" >> "${tmpdir}/${results}/revision.txt"
363 printf "Upstream revision: %s\n" "$($getrevision -u)" >> "${tmpdir}/${results}/revision.txt"
364 printf "Upstream URL: %s\n" "$($getrevision -U)" >> "${tmpdir}/${results}/revision.txt"
365 printf "Timestamp: %s\n" "$timestamp" >> "${tmpdir}/${results}/revision.txt"
367 if [ -n "$CBMEM_PATH" ]; then
368 cbmem_cmd="$CBMEM_PATH"
369 else
370 cbmem_cmd="cbmem"
373 if [ -n "$SERIAL_DEVICE" ]; then
374 get_serial_bootlog "$SERIAL_DEVICE" "$SERIAL_PORT_SPEED" "${tmpdir}/${results}/coreboot_console.txt"
375 elif [ -n "$REMOTE_HOST" ]; then
376 echo "Verifying that CBMEM is available on remote device"
377 test_cmd $REMOTE "$cbmem_cmd"
378 echo "Getting coreboot boot log"
379 cmd $REMOTE "$cbmem_cmd -1" "${tmpdir}/${results}/coreboot_console.txt"
380 echo "Getting timestamp data"
381 cmd_nonfatal $REMOTE "$cbmem_cmd -t" "${tmpdir}/${results}/coreboot_timestamps.txt"
383 echo "Getting remote dmesg"
384 cmd $REMOTE dmesg "${tmpdir}/${results}/kernel_log.txt"
385 else
386 echo "Verifying that CBMEM is available"
387 if [ $(id -u) -ne 0 ]; then
388 command -v "$cbmem_cmd" >/dev/null
389 if [ $? -ne 0 ]; then
390 echo "Failed to run $cbmem_cmd. Check \$PATH or" \
391 "use -c to specify path to cbmem binary."
392 exit $EXIT_FAILURE
393 else
394 cbmem_cmd="sudo $cbmem_cmd"
396 else
397 test_cmd $LOCAL "$cbmem_cmd"
400 echo "Getting coreboot boot log"
401 cmd $LOCAL "$cbmem_cmd -1" "${tmpdir}/${results}/coreboot_console.txt"
402 echo "Getting timestamp data"
403 cmd_nonfatal $LOCAL "$cbmem_cmd -t" "${tmpdir}/${results}/coreboot_timestamps.txt"
405 echo "Getting local dmesg"
406 cmd $LOCAL "sudo dmesg" "${tmpdir}/${results}/kernel_log.txt"
410 # Finish up.
412 coreboot_dir=$(pwd)
413 if [ $UPLOAD_RESULTS -eq 1 ]; then
414 # extract username from ssh://<username>@review.coreboot.org/blah
415 bsrepo=$(git config --get remote.origin.url | sed "s,\(.*\)/coreboot,\1/board-status,")
417 cd "util/board_status/"
418 if [ ! -e "board-status" ]; then
419 # FIXME: the board-status directory might get big over time.
420 # Is there a way we can push the results without fetching the
421 # whole repo?
422 git clone "$bsrepo"
423 if [ $? -ne 0 ]; then
424 echo "Error cloning board-status repo, aborting."
425 exit $EXIT_FAILURE
429 cd "board-status"
431 echo "Checking for duplicate results"
432 # get any updates to board-status
433 git pull
435 echo "${tagged_version}" | grep dirty >/dev/null 2>&1
436 clean_version=$?
437 existing_results=$(git ls-files "${mainboard_dir}/${tagged_version}")
439 # reject duplicate results of non-dirty versions
440 if [ "${clean_version}" -eq 1 ] && [ -n "${existing_results}" ] ; then
441 echo "Result is a duplicate, aborting"
442 exit $EXIT_FAILURE
445 echo "Copying results to $(pwd)/${results}"
447 # Note: Result directory should be unique due to the timestamp.
448 cp -R "${tmpdir}/${vendor}" .
450 echo "Uploading results"
451 git add "${vendor}"
452 git commit -a -m "${mainboard_dir}/${tagged_version}/${timestamp}"
453 count=0
454 until git push origin master || test $count -eq 3; do
455 git pull --rebase
456 count=$((count + 1))
457 done
459 # Results have been uploaded so it's pointless to keep the
460 # temporary files around.
461 rm -rf "${tmpdir}"
462 if test $count -eq 3; then
463 echo "Error uploading to board-status repo, aborting."
464 exit $EXIT_FAILURE
467 cd "$coreboot_dir"
469 if [ $CLOBBER_OUTPUT -eq 1 ]; then
470 rm -rf "${tmpdir}"
471 else
472 if [ $UPLOAD_RESULTS -eq 1 ]; then
473 echo
474 echo "output files are in $(dirname $0)/board-status/${mainboard_dir}/${tagged_version}/${timestamp}"
475 else
476 echo
477 echo "output files are in ${tmpdir}/${results}"
481 exit $EXIT_SUCCESS