blob: 891c03e9129eebb9b966b42d67f1227360b90311 [file] [log] [blame]
# Copyright 2023 The ChromiumOS Authors
# 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.client.common_lib.cros import cr50_utils
from autotest_lib.server.cros.faft.cr50_test import Cr50Test
class firmware_GSCDSUpdate(Cr50Test):
"""
Verify a dut can pick up a gsc update after deep sleep.
The AP flashes the GSC image in the inactive region. When the AP
restarts, it tells GSC to enable the new image. Verify this process
works when GSC enters deep sleep while the AP is shutdown.
"""
version = 1
UPDATE_OK = 1
DBG_PATH = '/tmp/gsc.dbg.bin'
def initialize(self, host, cmdline_args, full_args={}):
"""Get the DBG image information."""
if not host.servo or host.servo.main_device_is_ccd():
raise error.TestNAError(
'CCD not supported. Run with servo micro or c2d2')
super(firmware_GSCDSUpdate, self).initialize(host,
cmdline_args,
full_args,
restore_cr50_image=True)
self.host = host
self.dbg_img = self.get_saved_dbg_image_path()
def run_once(self):
"""Flash the dbg image. Verify GSC jumps to it after on resume"""
# Flash the image on the DUT.
dest, image_ver = cr50_utils.InstallImage(self.host, self.dbg_img,
self.DBG_PATH)
self.gsc.wait_until_update_is_allowed()
# Flash the dbg image in the inactive slot.
result = self.host.run('gsctool -au %s' % dest, ignore_status=True)
logging.info('Update result: %s', result)
if result.exit_status != self.UPDATE_OK:
try:
# Reboot the dut to cleanup the update state.
self.host.reboot()
finally:
raise error.TestError('Unable to run gsc update: %r' % result)
# Disable CCD, so gsc can enter deep sleep.
self.gsc.ccd_disable()
start_ds_count = self.gsc.get_deep_sleep_count()
# Shutdown the dut, so GSC will enter deep sleep.
self.faft_client.system.run_shell_command('poweroff', True)
logging.info('Waiting for gsc to enter deep sleep')
time.sleep(self.gsc.DEEP_SLEEP_DELAY * 2)
# Before turning on the system get the deep sleep count to make sure
# GSC entered deep sleep.
end_ds_count = self.gsc.get_deep_sleep_count()
# Check the version to make sure GSC doesn't pickup the update until
# the system boots.
resume_ver = self.gsc.get_active_version_info()
# Press the power button to turn on the DUT.
logging.info('Turning on the device')
self.servo.power_short_press()
# Wait for dut to pickup update
time.sleep(self.faft_config.delay_reboot_to_ping)
running_ver = self.gsc.get_active_version_info()
is_dbg = running_ver[2]
logging.info('Running: %r', running_ver)
logging.info('Expected: %r', image_ver)
# Try to rollback to the release version, so cleanup will be faster.
try:
self.gsc.rollback()
except:
logging.info('Rollback failed. Cleanup should handle it')
if start_ds_count >= end_ds_count:
raise error.TestError('Unable to enter deep sleep')
# Raise an error if the dut failed to update to the DBG image.
if not is_dbg or image_ver[1] != running_ver[1]:
raise error.TestFail('Unable to update after deep sleep')
if resume_ver == running_ver:
raise error.TestFail('Enabled the update before the system booted')