vboot: introduce get_gbb_flags.sh

introduce get_gbb_flags.sh command to make automatic annotation
of power measurements easier.

Also, fix issue where declaring local variables on same line
as executing a command would obfuscate error code, thus not
triggering set -c and continuing execution.
https://github.com/koalaman/shellcheck/wiki/SC2155

Usage:
$ /usr/share/vboot/bin/get_gbb_flags.sh
[...]
ChromeOS GBB set flags: 0x00000329.

$ /usr/share/vboot/bin/get_gbb_flags.sh -e
[...]
ChromeOS GBB set flags: 0x00000329.
ChromeOS GBB set flags listed:
GBB_FLAG_DEV_SCREEN_SHORT_DELAY
GBB_FLAG_FORCE_DEV_SWITCH_ON
GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK
GBB_FLAG_FAFT_KEY_OVERIDE
GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC

BUG=chromium:760267
BRANCH=none
TEST=manual
emerge-soraka vboot_reference
cros deploy <IP> vboot_reference
(on DUT)
/usr/share/vboot/bin/get_gbb_flags.sh -e
<same output as above>

Change-Id: Idb3b993706c03e7f2831eed2cef12a04b9469fea
(cherry picked from commit 1c6897da76e9f642fa5505df7cc8b91400fd617d)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1985504
Reviewed-by: Cheng-Han Yang <chenghan@chromium.org>
Commit-Queue: Cheng-Han Yang <chenghan@chromium.org>
Tested-by: Cheng-Han Yang <chenghan@chromium.org>
diff --git a/Makefile b/Makefile
index a5fb328..86bf521 100644
--- a/Makefile
+++ b/Makefile
@@ -647,7 +647,9 @@
 	scripts/image_signing/resign_firmwarefd.sh \
 	scripts/image_signing/make_dev_firmware.sh \
 	scripts/image_signing/make_dev_ssd.sh \
-	scripts/image_signing/set_gbb_flags.sh
+	scripts/image_signing/gbb_flags_common.sh \
+	scripts/image_signing/set_gbb_flags.sh \
+	scripts/image_signing/get_gbb_flags.sh
 
 # Installed, but not made executable.
 SIGNING_COMMON = scripts/image_signing/common_minimal.sh
diff --git a/scripts/image_signing/gbb_flags_common.sh b/scripts/image_signing/gbb_flags_common.sh
new file mode 100644
index 0000000..9a8d1cb
--- /dev/null
+++ b/scripts/image_signing/gbb_flags_common.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+#
+# Copyright 2017 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.
+#
+# This script provides tools to read or change GBB flags on a live system.
+
+SCRIPT_BASE="$(dirname "$0")"
+. "${SCRIPT_BASE}/common_minimal.sh"
+load_shflags || exit 1
+
+# Globals
+# ----------------------------------------------------------------------------
+
+# Values from vboot_reference/firmware/include/gbb_header.h
+GBBFLAGS_DESCRIPTION_PREFIX="
+  Defined flags (some values may be not supported by all systems):
+
+  "
+GBBFLAGS_LIST="
+  GBB_FLAG_DEV_SCREEN_SHORT_DELAY            0x00000001
+  GBB_FLAG_LOAD_OPTION_ROMS                  0x00000002
+  GBB_FLAG_ENABLE_ALTERNATE_OS               0x00000004
+  GBB_FLAG_FORCE_DEV_SWITCH_ON               0x00000008
+  GBB_FLAG_FORCE_DEV_BOOT_USB                0x00000010
+  GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK         0x00000020
+  GBB_FLAG_ENTER_TRIGGERS_TONORM             0x00000040
+  GBB_FLAG_FORCE_DEV_BOOT_LEGACY             0x00000080
+  GBB_FLAG_FAFT_KEY_OVERIDE                  0x00000100
+  GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC          0x00000200
+  GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY           0x00000400
+  GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC          0x00000800
+  GBB_FLAG_DISABLE_LID_SHUTDOWN              0x00001000
+  GBB_FLAG_FORCE_DEV_BOOT_FASTBOOT_FULL_CAP  0x00002000
+  GBB_FLAG_ENABLE_SERIAL                     0x00004000
+  "
+
+GBBFLAGS_DESCRIPTION_SUFFIX="
+  To get a developer-friendly device, try 0x11 (short_delay + boot_usb).
+  For factory-related tests (always DEV), try 0x39.
+  For early development (disable EC/PD software sync), try 0xa39.
+  "
+GBBFLAGS_DESCRIPTION="${GBBFLAGS_DESCRIPTION_PREFIX}${GBBFLAGS_LIST}"
+GBBFLAGS_DESCRIPTION="${GBBFLAGS_DESCRIPTION}${GBBFLAGS_DESCRIPTION_SUFFIX}"
+
+FLAGS_HELP="Manages Chrome OS Firmware GBB Flags value.
+
+  Usage: $0 [option_flags] GBB_FLAGS_VALUE
+  ${GBBFLAGS_DESCRIPTION}"
+
+flashrom_read() {
+  flashrom -p host -i GBB -r "$@"
+}
+
+flashrom_write() {
+  flashrom -p host -i GBB --fast-verify -w "$@"
+}
diff --git a/scripts/image_signing/get_gbb_flags.sh b/scripts/image_signing/get_gbb_flags.sh
new file mode 100755
index 0000000..a6aa89a
--- /dev/null
+++ b/scripts/image_signing/get_gbb_flags.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+#
+# Copyright 2017 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.
+#
+# This script can change GBB flags in system live firmware or a given image
+# file.
+
+SCRIPT_BASE="$(dirname "$0")"
+. "${SCRIPT_BASE}/gbb_flags_common.sh"
+
+# DEFINE_string name default_value description flag
+DEFINE_string file "" "Path to firmware image. Default to system firmware." "f"
+DEFINE_boolean explicit ${FLAGS_FALSE} "Print list of what flags are set." "e"
+
+set -e
+
+main() {
+  if [ $# -ne 0 ]; then
+    flags_help
+    exit 1
+  fi
+
+  local image_file="${FLAGS_file}"
+
+  if [ -z "${FLAGS_file}" ]; then
+    image_file="$(make_temp_file)"
+    flashrom_read "${image_file}"
+  fi
+
+  # Process file.
+
+  # Keep 'local' declaration split from assignment so return code is checked.
+  local gbb_flags
+  gbb_flags="$(futility gbb -g --flags "${image_file}")"
+  local raw_gbb_flags="$(echo "${gbb_flags}" | egrep -o "0x[0-9]+")"
+  printf "Chrome OS GBB set ${gbb_flags}\n"
+
+  if [ "${FLAGS_explicit}" = "${FLAGS_TRUE}" ]; then
+    printf "Chrome OS GBB set flags listed:\n"
+    echo "${GBBFLAGS_LIST}" | while read -r flag code; do
+      if [ $((code & raw_gbb_flags)) -ne 0 ]; then
+        printf "${flag}\n"
+      fi
+    done
+  fi
+}
+
+# Parse command line.
+FLAGS "$@" || exit 1
+eval set -- "${FLAGS_ARGV}"
+
+main "$@"
diff --git a/scripts/image_signing/set_gbb_flags.sh b/scripts/image_signing/set_gbb_flags.sh
index cadb39b..11da707 100755
--- a/scripts/image_signing/set_gbb_flags.sh
+++ b/scripts/image_signing/set_gbb_flags.sh
@@ -8,51 +8,14 @@
 # file.
 
 SCRIPT_BASE="$(dirname "$0")"
-. "$SCRIPT_BASE/common_minimal.sh"
-load_shflags || exit 1
+. "${SCRIPT_BASE}/gbb_flags_common.sh"
 
 # DEFINE_string name default_value description flag
 DEFINE_string file "" "Path to firmware image. Default to system firmware." "f"
-DEFINE_boolean check_wp $FLAGS_TRUE "Check write protection states first." ""
+DEFINE_boolean check_wp ${FLAGS_TRUE} "Check write protection states first." ""
 
-# Globals
-# ----------------------------------------------------------------------------
 set -e
 
-# Values from vboot_reference/firmware/include/gbb_header.h
-GBBFLAGS_DESCRIPTION="
-  Defined flags (some values may be not supported by all systems):
-
-  GBB_FLAG_DEV_SCREEN_SHORT_DELAY            0x00000001
-  GBB_FLAG_LOAD_OPTION_ROMS                  0x00000002
-  GBB_FLAG_ENABLE_ALTERNATE_OS               0x00000004
-  GBB_FLAG_FORCE_DEV_SWITCH_ON               0x00000008
-  GBB_FLAG_FORCE_DEV_BOOT_USB                0x00000010
-  GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK         0x00000020
-  GBB_FLAG_ENTER_TRIGGERS_TONORM             0x00000040
-  GBB_FLAG_FORCE_DEV_BOOT_LEGACY             0x00000080
-  GBB_FLAG_FAFT_KEY_OVERIDE                  0x00000100
-  GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC          0x00000200
-  GBB_FLAG_DEFAULT_DEV_BOOT_LEGACY           0x00000400
-  GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC          0x00000800
-  GBB_FLAG_DISABLE_LID_SHUTDOWN              0x00001000
-  GBB_FLAG_FORCE_DEV_BOOT_FASTBOOT_FULL_CAP  0x00002000
-  GBB_FLAG_ENABLE_SERIAL		     0x00004000
-
-  To get a developer-friendly device, try 0x11 (short_delay + boot_usb).
-  For factory-related tests (always DEV), try 0x39.
-  For early development (disable EC/PD software sync), try 0xa39.
-"
-
-FLAGS_HELP="Changes ChromeOS Firmware GBB Flags value.
-
-  Usage: $0 [option_flags] GBB_FLAGS_VALUE
-  $GBBFLAGS_DESCRIPTION"
-
-FLASHROM_COMMON_OPT="-p host"
-FLASHROM_READ_OPT="$FLASHROM_COMMON_OPT -i GBB -r"
-FLASHROM_WRITE_OPT="$FLASHROM_COMMON_OPT -i GBB --fast-verify -w"
-
 # Check write protection
 # ----------------------------------------------------------------------------
 check_write_protection() {
@@ -60,17 +23,18 @@
   if ! crossystem "wpsw_boot?0"; then
     hw_wp="on"
   fi
-  local wp_states="$(flashrom $FLASHROM_COMMON_OPT --wp-status 2>/dev/null \
-    | grep WP)"
-  local wp_disabled="$(echo "$wp_states" | grep "WP:.*is disabled.")"
-  local wp_zero_len="$(echo "$wp_states" | grep "WP:.*, len=0x00000000")"
-  if [ -z "$wp_disabled" -a -z "$wp_zero_len" ]; then
+  # Keep 'local' declaration split from assignment so return code is checked.
+  local wp_states
+  wp_states="$(flashrom -p host --wp-status 2>/dev/null | grep WP)"
+  local wp_disabled="$(echo "${wp_states}" | grep "WP:.*is disabled.")"
+  local wp_zero_len="$(echo "${wp_states}" | grep "WP:.*, len=0x00000000")"
+  if [ -z "${wp_disabled}" -a -z "${wp_zero_len}" ]; then
     sw_wp="on"
   fi
-  if [ -n "$hw_wp" -a -n "$sw_wp" ]; then
-    return $FLAGS_FALSE
+  if [ -n "${hw_wp}" -a -n "${sw_wp}" ]; then
+    return ${FLAGS_FALSE}
   fi
-  return $FLAGS_TRUE
+  return ${FLAGS_TRUE}
 }
 
 # Main
@@ -82,20 +46,22 @@
   fi
 
   local value="$(($1))"
-  local image_file="$FLAGS_file"
+  local image_file="${FLAGS_file}"
 
-  if [ -z "$FLAGS_file" ]; then
+  if [ -z "${FLAGS_file}" ]; then
     image_file="$(make_temp_file)"
-    flashrom $FLASHROM_READ_OPT "$image_file"
+    flashrom_read "${image_file}"
   fi
 
   # Process file
-  local old_value="$(futility gbb -g --flags "$image_file")"
-  printf "Setting GBB flags from %s to 0x%x.." "$old_value" "$value" >&2
-  futility gbb -s --flags="$value" "$image_file"
+  # Keep 'local' declaration split from assignment so return code is checked.
+  local old_value
+  old_value="$(futility gbb -g --flags "${image_file}")"
+  printf "Setting GBB flags from %s to 0x%x.." "${old_value}" "${value}"
+  futility gbb -s --flags="${value}" "${image_file}"
 
-  if [ -z "$FLAGS_file" ]; then
-    if [ "$FLAGS_check_wp" = "$FLAGS_TRUE" ]; then
+  if [ -z "${FLAGS_file}" ]; then
+    if [ "${FLAGS_check_wp}" = "${FLAGS_TRUE}" ]; then
       if ! check_write_protection; then
         echo ""
         echo "WARNING: System GBB Flags are NOT changed!!!"
@@ -103,13 +69,12 @@
         exit 1
       fi
     fi
-    flashrom $FLASHROM_WRITE_OPT "$image_file"
+    flashrom_write "$image_file"
   fi
 }
 
 # Parse command line
 FLAGS "$@" || exit 1
-ORIGINAL_PARAMS="$@"
 eval set -- "$FLAGS_ARGV"
 
 main "$@"