Wilco: Test Wilco-specific EC reset Cr50 behavior
Much of firmware_Cr50ECReset doesn't make sense without a Chrome EC. The
ecrst Cr50 command should still work, so test it. Wilco's EC requires a
longer reset pulse than the Chrome EC, so make sure 'ecrst pulse' works.
BUG=b:132070766
TEST=Ran the test against Arcada and Sarien
Change-Id: Ice849a595ba9c2393bc97f82758f5f81005bf02d
Reviewed-on: https://chromium-review.googlesource.com/1601392
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Abe Levkoy <alevkoy@chromium.org>
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
diff --git a/server/site_tests/firmware_Cr50WilcoEcrst/control b/server/site_tests/firmware_Cr50WilcoEcrst/control
new file mode 100644
index 0000000..7d2ddaa
--- /dev/null
+++ b/server/site_tests/firmware_Cr50WilcoEcrst/control
@@ -0,0 +1,36 @@
+# Copyright 2019 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.
+
+from autotest_lib.server import utils
+
+AUTHOR = "alevkoy"
+NAME = "firmware_Cr50WilcoEcrst"
+PURPOSE = "Verify Cr50 EC reset."
+ATTRIBUTES = "suite:faft_wilco, suite:faft_cr50_prepvt, suite:faft_cr50_pvt"
+TIME = "SHORT"
+TEST_TYPE = "server"
+DEPENDENCIES = "servo, board:sarien"
+JOB_RETRIES = 0
+
+DOC = """Make sure Cr50's ecrst command works as intended on Wilco.
+
+EC_RST_L needs to be able to hold the EC in reset. This test verifies the
+hardware works as intended.
+"""
+
+if 'args_dict' not in locals():
+ args_dict = {}
+
+args_dict.update(utils.args_to_dict(args))
+servo_args = hosts.CrosHost.get_servo_arguments(args_dict)
+
+def run(machine):
+ host = hosts.create_host(machine, servo_args=servo_args)
+
+ iterations = int(args_dict.get("iterations", 1))
+
+ job.run_test("firmware_Cr50WilcoEcrst", host=host, cmdline_args=args,
+ full_args=args_dict, iterations=iterations)
+
+parallel_simple(run, machines)
diff --git a/server/site_tests/firmware_Cr50WilcoEcrst/firmware_Cr50WilcoEcrst.py b/server/site_tests/firmware_Cr50WilcoEcrst/firmware_Cr50WilcoEcrst.py
new file mode 100644
index 0000000..0bff15f
--- /dev/null
+++ b/server/site_tests/firmware_Cr50WilcoEcrst/firmware_Cr50WilcoEcrst.py
@@ -0,0 +1,94 @@
+# Copyright 2019 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.
+
+import logging
+import time
+
+from autotest_lib.client.common_lib import error
+from autotest_lib.server.cros.faft.cr50_test import Cr50Test
+
+
+class firmware_Cr50WilcoEcrst(Cr50Test):
+ """Make sure Cr50's ecrst command works as intended.
+
+ EC_RST_L needs to be able to hold the EC in reset. This test verifies the
+ hardware works as intended.
+ """
+ version = 1
+
+ # How long to hold 'ecrst on', in seconds
+ SHORT_PULSE = 1
+
+
+ def initialize(self, host, cmdline_args, full_args):
+ super(firmware_Cr50WilcoEcrst, self).initialize(host, cmdline_args,
+ full_args)
+ if not self.faft_config.gsc_can_wake_ec_with_reset:
+ raise error.TestNAError("This DUT has a hardware limitation that "
+ "prevents cr50 from waking the EC with "
+ "EC_RST_L.")
+ # This test only makes sense with a Wilco EC.
+ if self.check_ec_capability():
+ raise error.TestNAError("Nothing needs to be tested on this device")
+
+ # Open Cr50, so the test has access to ecrst.
+ self.fast_open(True)
+
+
+ def cr50_ecrst(self, state):
+ """Set ecrst on Cr50."""
+ self.cr50.send_command('ecrst ' + state)
+
+
+ def make_ec_reset_bring_up_ap(self):
+ """Force the AP to come back up after the next EC reset.
+
+ This is not the default behavior on Wilco. The AFTERG3_EN bit in the
+ GEN_PMCON_A register is set by default, which causes the AP to remain
+ down after an EC reset. Clearing it will cause the AP to come after the
+ next EC reset, at which point Coreboot will set it again, making the
+ change in behavior temporary.
+ """
+ GEN_PMCON_A_ADDRESS = 0xfe001020
+ AFTERG3_EN_BIT = 0x1
+ orig_reg_string = self.faft_client.system.run_shell_command_get_output(
+ 'iotools mmio_read32 %#x' % (GEN_PMCON_A_ADDRESS))
+ logging.info('iotools output: %s', orig_reg_string)
+ orig_reg_value = int(orig_reg_string[0], 0)
+ if orig_reg_value > 0xffffffff:
+ raise error.TestError(
+ 'iotools mmio_read32 returned a value larger than 32 bits')
+ new_reg_value = orig_reg_value & ~AFTERG3_EN_BIT
+ self.faft_client.system.run_shell_command('iotools mmio_write32 %#x %#x'
+ % (GEN_PMCON_A_ADDRESS, new_reg_value))
+
+
+ def check_ecrst_on_off(self):
+ """Verify Cr50 can hold the EC in reset."""
+ self.make_ec_reset_bring_up_ap()
+
+ self.cr50_ecrst('on')
+ # There isn't a good way to directly tell if the EC is in reset, so
+ # verify that the AP has gone down.
+ self.switcher.wait_for_client_offline()
+ time.sleep(self.SHORT_PULSE)
+
+ self.cr50_ecrst('off')
+ self.switcher.wait_for_client()
+
+
+ def check_ecrst_pulse(self):
+ """Verify Cr50 can reset the EC with a pulse."""
+ self.make_ec_reset_bring_up_ap()
+
+ orig_boot_id = self.get_bootid()
+ self.cr50_ecrst('pulse')
+ self.switcher.wait_for_client_offline(orig_boot_id=orig_boot_id)
+ self.switcher.wait_for_client()
+
+
+ def run_once(self):
+ """Run the test."""
+ self.check_ecrst_on_off()
+ self.check_ecrst_pulse()