chrome_cr50: add ap ro hash support
Add support for getting the ap_ro_info output.
BUG=b:218705748
TEST=none
Change-Id: I0145ad7b715da78bc04ef1b13d1e6eea046e721c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/3652629
Tested-by: Mary Ruthven <mruthven@chromium.org>
Reviewed-by: Jeremy Bettis <jbettis@chromium.org>
Auto-Submit: Mary Ruthven <mruthven@chromium.org>
Commit-Queue: Mary Ruthven <mruthven@chromium.org>
diff --git a/server/cros/servo/chrome_cr50.py b/server/cros/servo/chrome_cr50.py
index 93325b7..ec76dde 100644
--- a/server/cros/servo/chrome_cr50.py
+++ b/server/cros/servo/chrome_cr50.py
@@ -189,6 +189,22 @@
USB_ERROR = 'timer_sof_calibration_overflow_int'
# Message printed during watchdog reset.
WATCHDOG_RST = 'WATCHDOG PC'
+ # ===============================================================
+ # AP_RO strings
+ # Cr50 only supports v2
+ AP_RO_VERSIONS = [1]
+ AP_RO_HASH_RE = r'sha256 (hash) ([0-9a-f]{64})'
+ AP_RO_UNSUPPORTED_UNPROGRAMMED = 'RO verification not programmed'
+ AP_RO_UNSUPPORTED_BID_BLOCKED = 'BID blocked'
+ AP_RO_REASON_RE = r'(ap_ro_check_unsupported): (.*)\]'
+ AP_RO_RESULT_RE = r'(result)\s*: (\d)'
+ AP_RO_SUPPORTED_RE = r'(supported)\s*: (yes|no)'
+ AP_RO_UNSUPPORTED_OUTPUT = [
+ AP_RO_REASON_RE, AP_RO_RESULT_RE, AP_RO_SUPPORTED_RE
+ ]
+ AP_RO_SAVED_OUTPUT = [AP_RO_RESULT_RE, AP_RO_SUPPORTED_RE, AP_RO_HASH_RE]
+
+ # ===============================================================
def __init__(self, servo, faft_config):
"""Initializes a ChromeCr50 object.
@@ -199,7 +215,6 @@
super(ChromeCr50, self).__init__(servo, 'cr50_uart')
self.faft_config = faft_config
-
def wake_cr50(self):
"""Wake up cr50 by sending some linebreaks and wait for the response"""
for i in range(self.MAX_RETRY_COUNT):
@@ -1372,3 +1387,50 @@
if watchdog_count:
raise error.TestFail('Found %r %d times in logs after %s' %
(self.WATCHDOG_RST, watchdog_count, desc))
+
+ def ap_ro_version_is_supported(self, version):
+ """Returns True if GSC supports the given version."""
+ return version in self.AP_RO_VERSIONS
+
+ def ap_ro_supported(self):
+ """Returns True if the hash is saved and AP RO is supported."""
+ return self.send_command_retry_get_output(
+ 'ap_ro_info', [self.AP_RO_SUPPORTED_RE])[0][2] == 'yes'
+
+ def get_ap_ro_info(self):
+ """Returns a dictionary of the AP RO info.
+
+ Get the ap_ro_info output. Convert it to a usable dictionary.
+
+ Returns:
+ A dictionary with the following key value pairs.
+ 'reason': String of unsupported reason or None if ap ro is
+ supported.
+ 'hash': 64 char hash or None if it isn't supported.
+ 'supported': bool whether AP RO verification is supported.
+ 'result': int of the AP RO verification result.
+ """
+ # Cr50 prints different output based on whether ap ro verification is
+ # supported.
+ if self.ap_ro_supported():
+ output = self.AP_RO_SAVED_OUTPUT
+ else:
+ output = self.AP_RO_UNSUPPORTED_OUTPUT
+ # The reason and hash output is optional. Make sure it's in the
+ # dictionary even if it isn't in the output.
+ info = {'hash': None, 'reason': None}
+ rv = self.send_command_retry_get_output('ap_ro_info',
+ output,
+ compare_output=True)
+ for _, k, v in rv:
+ # Make key more usable.
+ if k == 'ap_ro_check_unsupported':
+ k = 'reason'
+ # Convert digit strings to ints
+ if v.isdigit():
+ v = int(v)
+ # Convert yes or no to bool
+ if k == 'supported':
+ v = v == 'yes'
+ info[k] = v
+ return info
diff --git a/server/cros/servo/chrome_ti50.py b/server/cros/servo/chrome_ti50.py
index a8bf9ee..e123198 100644
--- a/server/cros/servo/chrome_ti50.py
+++ b/server/cros/servo/chrome_ti50.py
@@ -28,6 +28,8 @@
'BatteryBypassPP', 'I2C', 'FlashRead', 'OpenNoDevMode',
'OpenFromUSB', 'OverrideBatt'
]
+ # Ti50 only supports v2
+ AP_RO_VERSIONS = [2]
def __init__(self, servo, faft_config):
"""Initializes a ChromeCr50 object.