blob: a6400c7fee51dcc2810b6e55d5dd0404d738f8ae [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2018 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.
"""Verify rollback update possible & flashing with lower rb version fails"""
from __future__ import print_function
import sys
import time
import common
import hammerd_api
# Before this test, please flash staff.dev.rb1 using servo
# This test can only be run once, then the image needs to be reflashed using
# servo again.
def main(argv):
if argv:
sys.exit('Test takes no args!')
updater = hammerd_api.FirmwareUpdater(common.BASE_VENDOR_ID,
common.BASE_PRODUCT_ID,
common.BASE_USB_PATH)
# Load EC image.
with open(common.RB_INITIAL, 'rb') as f:
ec_image = f.read()
updater.LoadEcImage(ec_image)
common.disable_hammerd()
# Make sure rollback is updated to current RW image (rb1)
common.connect_usb(updater)
inc_rollback(updater, 1)
# Update to invalid RW with RB < current RB
image_desc = 'Update to invalid RW with RB < current RB'
update_invalid_rb(updater, common.RB_LOWER, image_desc)
# Restore to valid RB
image_desc = 'Restoring to valid RB_1 from RO'
restore_valid_rb(updater, common.RB_INITIAL, image_desc)
# Update to valid RW with RB > current RB
image_desc = 'Update to valid RW with RB > current RB'
init_before_updaterw(updater)
common.reset_stay_ro(updater)
unlock_rw(updater)
restore_valid_rb(updater, common.RB_HIGHER, image_desc)
# RB should now = RB_HIGHER
common.connect_usb(updater)
inc_rollback(updater, 9)
def init_before_updaterw(updater):
print('Calling init_before_updaterw')
common.connect_usb(updater)
print('EC information:')
pdu_resp = updater.GetFirstResponsePdu().contents
print('PDU Response: %s' % pdu_resp)
print('RO: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RO))
print('RW: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RW))
updater.SendFirstPdu()
updater.SendDone()
print('Current running section before RW: %s' % updater.CurrentSection())
def transfer_rw(updater, image):
with open(image, 'rb') as f:
ec_image = f.read()
updater.LoadEcImage(ec_image)
print('Transferring RW')
updater.TransferImage(1)
updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset)
updater.CloseUsb()
time.sleep(0.5)
common.connect_usb(updater)
updater.SendSubcommand(hammerd_api.UpdateExtraCommand.JumpToRW)
time.sleep(2)
updater.CloseUsb()
time.sleep(0.5)
# Jump to RW resets the base. Need to reconnect
common.connect_usb(updater)
print('PDU Response: %s' % updater.GetFirstResponsePdu().contents)
print('RO: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RO))
print('RW: %s' % updater.GetSectionVersion(hammerd_api.SectionName.RW))
# Check that transferred RW is running if it's not corrupted version
updater.SendFirstPdu()
updater.SendDone()
print('Current running section after RW: %s' % updater.CurrentSection())
def update_invalid_rb(updater, image, image_desc):
init_before_updaterw(updater)
common.reset_stay_ro(updater)
unlock_rw(updater)
print(image_desc)
transfer_rw(updater, image)
assert updater.CurrentSection() == 0, 'RW has lower RB version!'
def restore_valid_rb(updater, image, image_desc):
print(image_desc)
transfer_rw(updater, image)
common.sim_disconnect_connect(updater)
def get_wp_status(updater):
pdu_resp = updater.GetFirstResponsePdu().contents
wp_status = (pdu_resp.flash_protection &
common.EC_FLASH_PROTECT_GPIO_ASSERTED) > 0
return wp_status
def unlock_rw(updater):
# Check if RW is locked and unlock if needed
wp = get_wp_status(updater)
print('WP status: %s' %str(wp))
if wp:
print('Need to unlock RW')
updater.UnlockRW()
common.reset_stay_ro(updater)
def inc_rollback(updater, expected_rb):
current_rb = updater.GetFirstResponsePdu().contents.min_rollback
print('Current RB: %s' % current_rb)
updater.SendSubcommand(hammerd_api.UpdateExtraCommand.UnlockRollback)
common.sim_disconnect_connect(updater)
common.connect_usb(updater)
pdu_resp = updater.GetFirstResponsePdu().contents
print('PDU Response: %s' % pdu_resp)
print('Current running section: %s' % updater.CurrentSection())
new_rb = updater.GetFirstResponsePdu().contents.min_rollback
print('New RB version: %s' % new_rb)
assert new_rb == expected_rb, 'Error: Failed to increment RB version!'
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))