Convert all boards to use the servod 'power_state' control.
All boards now provide the standard board-independent interface for
power off, power on, recovery mode, and cold reset operations.
BUG=chromium:342875,chromium:326738
TEST=Pending
Change-Id: Ic68017a598df3745347ceff90cc8d8faf8e344fe
Reviewed-on: https://chromium-review.googlesource.com/202720
Tested-by: Richard Barnette <jrbarnette@chromium.org>
Reviewed-by: Kris Rambish <krisr@chromium.org>
Reviewed-by: Dan Shi <dshi@chromium.org>
Commit-Queue: Richard Barnette <jrbarnette@chromium.org>
diff --git a/server/cros/faft/faft_classes.py b/server/cros/faft/faft_classes.py
index cd6c20f..b91ea65 100644
--- a/server/cros/faft/faft_classes.py
+++ b/server/cros/faft/faft_classes.py
@@ -1351,14 +1351,7 @@
A wrapper for underlying servo cold reset.
"""
- if self.faft_config.broken_warm_reset:
- self.servo.set('pwr_button', 'press')
- self.servo.set('cold_reset', 'on')
- self.servo.set('cold_reset', 'off')
- time.sleep(self.faft_config.ec_boot_to_pwr_button)
- self.servo.set('pwr_button', 'release')
- else:
- self.servo.get_power_state_controller().cold_reset()
+ self.servo.get_power_state_controller().reset()
def sync_and_warm_reboot(self):
"""Request the client sync and do a warm reboot.
diff --git a/server/cros/faft/firmware_test.py b/server/cros/faft/firmware_test.py
index cfaa9dd..23de9a2 100644
--- a/server/cros/faft/firmware_test.py
+++ b/server/cros/faft/firmware_test.py
@@ -1191,14 +1191,7 @@
A wrapper for underlying servo cold reset.
"""
- if self.faft_config.broken_warm_reset:
- self.servo.set('pwr_button', 'press')
- self.servo.set('cold_reset', 'on')
- self.servo.set('cold_reset', 'off')
- time.sleep(self.faft_config.ec_boot_to_pwr_button)
- self.servo.set('pwr_button', 'release')
- else:
- self.servo.get_power_state_controller().cold_reset()
+ self.servo.get_power_state_controller().reset()
def sync_and_warm_reboot(self):
"""Request the client sync and do a warm reboot.
diff --git a/server/cros/servo/power_state_controller.py b/server/cros/servo/power_state_controller.py
index 1e7c835..a8601bf 100644
--- a/server/cros/servo/power_state_controller.py
+++ b/server/cros/servo/power_state_controller.py
@@ -2,39 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import time
-
-
-def _inherit_docstring(cls):
- """Decorator to propagate a docstring to a subclass's method.
-
- @param cls Class with the method whose docstring is to be
- inherited. The class must contain a method with
- the same name as the name of the function to be
- decorated.
-
- """
- def _copy_docstring(methfunc):
- """Actually copy the parent docstring to the child.
-
- @param methfunc Function that will inherit the docstring.
-
- """
- methfunc.__doc__ = getattr(cls, methfunc.__name__).__doc__
- return methfunc
- return _copy_docstring
-
-
-# Constants acceptable to be passed for the `rec_mode` parameter
-# to power_on().
-#
-# REC_ON: Boot the DUT in recovery mode, i.e. boot from USB or
-# SD card.
-# REC_OFF: Boot in normal mode, i.e. boot from internal storage.
-
-REC_ON = 'on'
-REC_OFF = 'off'
-
class _PowerStateController(object):
@@ -48,16 +15,19 @@
"""
- # Delay in seconds needed between asserting and de-asserting cold
- # or warm reset. Subclasses will normally override this constant
- # with a board-specific value.
- _RESET_HOLD_TIME = 0.5
+ # Constants acceptable to be passed for the `rec_mode` parameter
+ # to power_on().
+ #
+ # REC_ON: Boot the DUT in recovery mode, i.e. boot from USB or
+ # SD card.
+ # REC_OFF: Boot in normal mode, i.e. boot from internal storage.
- # _EC_RESET_DELAY: Time required before the EC will be working
- # after cold reset. Five seconds is at least twice as long as
- # necessary for Alex, and is presumably good enough for all other
- # systems.
- _EC_RESET_DELAY = 5.0
+ REC_ON = 'rec'
+ REC_OFF = 'on'
+
+ # Delay in seconds needed between asserting and de-asserting
+ # warm reset.
+ _RESET_HOLD_TIME = 0.5
def __init__(self, servo):
"""Initialize the power state control.
@@ -68,20 +38,16 @@
"""
self._servo = servo
- def cold_reset(self):
- """Apply cold reset to the DUT.
+ def reset(self):
+ """Force the DUT to reset.
- This asserts, then de-asserts the 'cold_reset' signal.
- The exact affect on the hardware varies depending on
- the board type.
+ The DUT is guaranteed to be on at the end of this call,
+ regardless of its previous state, provided that there is
+ working OS software. This also guarantees that the EC has
+ been restarted.
"""
- self._servo.set_get_all(['cold_reset:on',
- 'sleep:%.4f' % self._RESET_HOLD_TIME,
- 'cold_reset:off'])
- # After the reset, give the EC the time it needs to
- # re-initialize.
- time.sleep(self._EC_RESET_DELAY)
+ self._servo.set_nocheck('power_state', 'reset')
def warm_reset(self):
"""Apply warm reset to the DUT.
@@ -101,7 +67,7 @@
not raise a NotImplementedError. False means they will.
"""
- return False
+ return True
def power_off(self):
"""Force the DUT to power off.
@@ -112,7 +78,7 @@
working OS software.
"""
- raise NotImplementedError()
+ self._servo.set_nocheck('power_state', 'off')
def power_on(self, rec_mode=REC_OFF):
"""Force the DUT to power on.
@@ -134,107 +100,17 @@
power on. default: REC_OFF aka 'off'
"""
- raise NotImplementedError()
+ self._servo.set_nocheck('power_state', rec_mode)
- def reset(self):
- """Force the DUT to reset.
-
- The DUT is guaranteed to be on at the end of this call,
- regardless of its previous state, provided that there is
- working OS software. This also guarantees that the EC has
- been restarted.
-
- """
- raise NotImplementedError()
-
-
-class _ServodController(_PowerStateController):
-
- """Controller based on the servod `power_state` control.
-
- TODO(jrbarnette): This is a transitional class. Servod is
- adding support for operations like `set('power_state', 'off')`,
- which will supersede `_PowerStateController`. However, not all
- boards are both implemented and tested in servod. To manage
- the transition, boards that support the new feature are mapped
- to this class.
-
- Once support in hdctools is complete for all boards, this class
- should be removed, and the functionality should be refactored to
- be board-independent.
-
- """
-
- @_inherit_docstring(_PowerStateController)
- def recovery_supported(self):
- return True
-
- @_inherit_docstring(_PowerStateController)
- def power_off(self):
- self._servo.set_nocheck('power_state', 'off')
-
- @_inherit_docstring(_PowerStateController)
- def power_on(self, rec_mode=REC_OFF):
- if rec_mode == REC_OFF:
- state = 'on'
- else:
- state = 'rec'
- self._servo.set_nocheck('power_state', state)
-
- @_inherit_docstring(_PowerStateController)
- def reset(self):
- self._servo.set_nocheck('power_state', 'reset')
-
-
-class _PantherController(_PowerStateController):
-
- """Power-state controller for Panther and compatible boards.
-
- For Panther, the 'cold_reset' signal is now connected (from DVT)
- However releasing the 'cold_reset' line does not power on the
- device. Hence the need to press the power button.
- """
-
- _RESET_HOLD_TIME = 0.5
- _RESET_DELAY = 5.0
- _TIME_TO_HOLD_POWER_BUTTON = 1.2
-
- @_inherit_docstring(_PowerStateController)
- def cold_reset(self):
- self._servo.set_get_all(['cold_reset:on',
- 'sleep:%.4f' % self._RESET_HOLD_TIME,
- 'cold_reset:off'])
- time.sleep(self._RESET_DELAY)
-
- self._servo.set('pwr_button', 'press')
- time.sleep(self._TIME_TO_HOLD_POWER_BUTTON)
- self._servo.set('pwr_button', 'release')
-
-
-_CONTROLLER_BOARD_MAP = {
- 'panther': _PantherController,
- 'mccloud': _PantherController,
- 'monroe': _PantherController,
- 'zako': _PantherController,
- 'tricky': _PantherController,
-}
-
-
-def create_controller(servo, board):
+def create_controller(servo):
"""Create a power state controller instance.
- The controller class will be selected based on the provided board type, and
- instantiated with the provided servo instance. Default controller is
- _ServodController.
-
@param servo Servo object that will be used to manipulate DUT
power states.
- @param board Board name of the DUT to be controlled.
- @returns An instance of a power state controller appropriate to
- the given board type, default controller is _ServodController if no
- controller is specified for the board.
+ @returns An instance of _PowerStateController for the servo
+ object.
"""
- return _CONTROLLER_BOARD_MAP.get(board, _ServodController)(servo)
+ return _PowerStateController(servo)
diff --git a/server/cros/servo/servo.py b/server/cros/servo/servo.py
index 09c2c5d..454606a 100644
--- a/server/cros/servo/servo.py
+++ b/server/cros/servo/servo.py
@@ -10,7 +10,6 @@
import logging, re, time, xmlrpclib
from autotest_lib.client.common_lib import error
-from autotest_lib.server import utils
from autotest_lib.server.cros.servo import power_state_controller
from autotest_lib.server.cros.servo import firmware_programmer
@@ -75,9 +74,8 @@
self._servo_host = servo_host
self._servo_serial = servo_serial
self._server = servo_host.get_servod_server_proxy()
- board = self._server.get_board()
self._power_state = (
- power_state_controller.create_controller(self, board))
+ power_state_controller.create_controller(self))
# a string, showing what interface (host or dut) the USB device is
# connected to.
@@ -124,16 +122,15 @@
that's off, depending on the board type and previous state
of the device.
- If `cold_reset` is a true value, cold reset will be applied
- to the DUT. Cold reset will force the DUT to power off;
- however, the final state of the DUT depends on the board type.
+ If `cold_reset` is a true value, the DUT and its EC will be
+ reset, and the DUT rebooted in normal mode.
@param cold_reset If True, cold reset the device after
initialization.
"""
self._server.hwinit()
if cold_reset:
- self._power_state.cold_reset()
+ self._power_state.reset()
def is_localhost(self):
@@ -513,7 +510,7 @@
automatically after installation.
"""
self.image_to_servo_usb(image_path, make_image_noninteractive)
- self._power_state.power_on(rec_mode=power_state_controller.REC_ON)
+ self._power_state.power_on(rec_mode=self._power_state.REC_ON)
self.switch_usbkey('dut')
diff --git a/server/site_tests/platform_ExternalUSBBootStress/platform_ExternalUSBBootStress.py b/server/site_tests/platform_ExternalUSBBootStress/platform_ExternalUSBBootStress.py
index 5c270a0..f02f3d8 100644
--- a/server/site_tests/platform_ExternalUSBBootStress/platform_ExternalUSBBootStress.py
+++ b/server/site_tests/platform_ExternalUSBBootStress/platform_ExternalUSBBootStress.py
@@ -2,9 +2,9 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import json, logging, re, time
+import logging, re, time
-from autotest_lib.server import autotest, test
+from autotest_lib.server import test
from autotest_lib.server.cros import stress
from autotest_lib.server.cros.servo import servo
from autotest_lib.client.common_lib import error
@@ -96,7 +96,7 @@
if skip_gbb:
# For devices that do not support gbb we have servo
# accelerate booting through dev mode.
- host.servo.get_power_state_controller().cold_reset()
+ host.servo.get_power_state_controller().reset()
host.servo.power_short_press()
time.sleep(servo.Servo.BOOT_DELAY)
host.servo.ctrl_d()
diff --git a/server/site_tests/platform_ServoPowerStateController/platform_ServoPowerStateController.py b/server/site_tests/platform_ServoPowerStateController/platform_ServoPowerStateController.py
index 9dbbf7c..4d8760b 100644
--- a/server/site_tests/platform_ServoPowerStateController/platform_ServoPowerStateController.py
+++ b/server/site_tests/platform_ServoPowerStateController/platform_ServoPowerStateController.py
@@ -6,7 +6,6 @@
from autotest_lib.client.common_lib import error
from autotest_lib.server import test
-from autotest_lib.server.cros.servo import power_state_controller
class platform_ServoPowerStateController(test.test):
@@ -25,7 +24,7 @@
# Power off, then power on DUT from internal storage.
self.controller.power_off()
self.host.servo.switch_usbkey('off')
- self.controller.power_on(power_state_controller.REC_OFF)
+ self.controller.power_on(self.controller.REC_OFF)
def confirm_dut_on(self, rec_on=False):
@@ -73,7 +72,7 @@
# Power DUT on in non-recovery mode with USB stick plugged in.
# DUT shall boot from internal storage.
logging.info('Power on DUT in non-recovery mode.')
- self.controller.power_on(power_state_controller.REC_OFF)
+ self.controller.power_on(self.controller.REC_OFF)
self.confirm_dut_on()
logging.info('Power off DUT which is up in non-recovery mode.')
@@ -83,7 +82,7 @@
logging.info('Power DUT on in recovery mode, DUT shall boot from USB.')
self.host.servo.switch_usbkey('off')
- self.controller.power_on(power_state_controller.REC_ON)
+ self.controller.power_on(self.controller.REC_ON)
self.host.servo.switch_usbkey('dut')
time.sleep(30)
self.confirm_dut_on(rec_on=True)
@@ -94,7 +93,7 @@
'USB stick.')
logging.info('Power on in non-recovery mode.')
- self.controller.power_on(power_state_controller.REC_OFF)
+ self.controller.power_on(self.controller.REC_OFF)
self.confirm_dut_on(rec_on=False)
@@ -116,7 +115,7 @@
# DUT should be off before calling power_on(REC_ON)
logging.info('Power on DUT in recovery mode with USB unplugged.')
- self.controller.power_on(power_state_controller.REC_ON)
+ self.controller.power_on(self.controller.REC_ON)
self.confirm_dut_off("power_state:rec didn't stay at recovery screen.")
logging.info('Power off DUT in recovery mode with USB unplugged.')
@@ -124,13 +123,13 @@
self.confirm_dut_off('power_state:off failed at recovery screen.')
logging.info('Power on in non-recovery mode.')
- self.controller.power_on(power_state_controller.REC_OFF)
+ self.controller.power_on(self.controller.REC_OFF)
self.confirm_dut_on(rec_on=False)
logging.info('Power DUT off and on without delay. DUT should be on '
'after power_on is completed.')
self.controller.power_off()
- self.controller.power_on(power_state_controller.REC_OFF)
+ self.controller.power_on(self.controller.REC_OFF)
self.confirm_dut_on(rec_on=False)
logging.info('Power DUT off and reset. DUT should be on after reset '
diff --git a/server/site_tests/provision_FirmwareUpdate/provision_FirmwareUpdate.py b/server/site_tests/provision_FirmwareUpdate/provision_FirmwareUpdate.py
index 166ee78..065a59b 100644
--- a/server/site_tests/provision_FirmwareUpdate/provision_FirmwareUpdate.py
+++ b/server/site_tests/provision_FirmwareUpdate/provision_FirmwareUpdate.py
@@ -108,6 +108,6 @@
self._servo.program_ec(os.path.join(self.tmpd.name, self._ec_image))
logging.info('Will re-program BIOS now')
self._servo.program_bios(os.path.join(self.tmpd.name, self._ap_image))
- self._servo.get_power_state_controller().cold_reset()
+ self._servo.get_power_state_controller().reset()
time.sleep(self._servo.BOOT_DELAY)
self._add_version_label()