#!/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 that RO cannot flash to wrong address."""

from __future__ import print_function

import sys
import time

import common
import hammerd_api

# These will fail in RO because hammer prevents current image from being
# updated. It'll fail in RW as RO is protected.
WRONG_ADDR_RO_OFFSET = '0x00000000'
WRONG_ADDR_KEY_RO = '0x0000ac00'
WRONG_ADDR_RO_FRID = '0x000000c4'
WRONG_ADDR_RW_FWID = '0x0000c0c4'
WRONG_ADDR_SIG_RW = '0x0001fc00'
# This will fail because hammer never allows rollback to be updated
WRONG_ADDR_RW_RBVER = '0x0000c0e8'
# These will fail in RW because hammer prevents current image from being
# updated. It'll fail in RO as RW must be write protected.
WRONG_ADDR_RW_OFFSET = '0x0000c000'

WRONG_ADDR_LIST = [WRONG_ADDR_RO_OFFSET, WRONG_ADDR_KEY_RO, WRONG_ADDR_RO_FRID,
                   WRONG_ADDR_RW_FWID, WRONG_ADDR_SIG_RW, WRONG_ADDR_RW_RBVER,
                   WRONG_ADDR_RW_OFFSET]

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)
  with open(common.IMAGE, 'rb') as f:
    ec_image = f.read()
  updater.LoadEcImage(ec_image)

  common.disable_hammerd()
  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))
  print('Is RW locked?:  %s' % updater.IsSectionLocked(1))
  assert updater.IsSectionLocked(1), 'RW should be locked'

  updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset)
  updater.CloseUsb()
  time.sleep(0.5)
  updater.TryConnectUsb()
  updater.SendSubcommand(hammerd_api.UpdateExtraCommand.StayInRO)
  time.sleep(1)
  assert updater.SendFirstPdu() is True, 'Error sending first PDU'
  updater.SendDone()

  print('Current section after StayInRO cmd: %s' % updater.CurrentSection())
  assert updater.CurrentSection() == 0, 'Running section should be 0 (RO)'

  init_transfer(updater)
  # First test that RW can't update anything
  flash_invalid_address(updater, True)

  # Uncommenting these line will make the test fail (RO will be able to write to
  # WRONG_ADDR_RW_OFFSET)
  # common.connect_usb(updater)
  # unlock_rw(updater)
  # updater.CloseUsb()

  # Then test that RO can't update anything
  flash_invalid_address(updater, False)


def get_wp_status(updater):
  wp_rw = (get_flash_protection(updater) & common.EC_FLASH_PROTECT_RW_NOW) > 0
  return wp_rw


def flash_invalid_address(updater, rw):
  # Using TransferTouchpadFirmware method for now as API lacks equivalent.
  for address in WRONG_ADDR_LIST:
    common.connect_usb(updater)
    if rw:
      updater.SendSubcommand(hammerd_api.UpdateExtraCommand.JumpToRW)
      updater.CloseUsb()
      time.sleep(0.5)
      updater.TryConnectUsb()
      assert updater.SendFirstPdu(), 'Error sending first PDU'
      updater.SendDone()

      print('Current section: %s' % updater.CurrentSection())
      if rw:
        assert updater.CurrentSection() == 1, 'Running section should be 1 (RW)'
      else:
        assert updater.CurrentSection() == 0, 'Running section should be 0 (RO)'

      wr = updater.TransferTouchpadFirmware(int(address, 0), 4096)
      assert wr == 0, 'Should not be able to write to wrong address!'
      updater.SendSubcommand(hammerd_api.UpdateExtraCommand.ImmediateReset)
      updater.CloseUsb()
      time.sleep(0.5)


def init_transfer(updater):
  with open(common.TP, 'rb') as f:
    ec_image = f.read()
  updater.LoadTouchpadImage(ec_image)
  assert updater.SendFirstPdu() is True, 'Error sending first PDU'
  updater.SendDone()
  unlock_rw(updater)
  common.sim_disconnect_connect(updater)


def unlock_rw(updater):
  # Check if RW is locked and unlock if needed.
  wp_rw = get_wp_status(updater)
  print('WP status:  %s' % str(wp_rw))
  if wp_rw:
    print('Need to unlock RW')
    unlocked = updater.UnlockRW()
    assert unlocked == 1, 'Failed to unlock RW'


def get_flash_protection(updater):
  pdu_resp = updater.GetFirstResponsePdu().contents
  return pdu_resp.flash_protection

if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
