# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
"""Utilities used to download firmware images into the OpenTitan system."""

import subprocess
import time
import hashlib
from functools import partial

def _uint_to_le(val, length):
  """Returns a byte array that represents an unsigned integer in little-endian format.

  Args:
    val: Unsigned integer to convert.
    length: Number of bytes.

  Returns:
    A byte array of ``length`` bytes that represents ``val`` in little-endian format.
  """
  return val.to_bytes(length=length, byteorder='little')

def _le_to_uint(val):
  """Returns the unsigned integer represented by the given byte array in little-endian format.

  Args:
    val: Byte array in little-endian format that represents an unsigned integer.

  Returns:
    The unsigned integer represented by the byte array ``val``.
  """
  return int.from_bytes(val, byteorder='little')

class _SpiFlashFrame:
  """A frame used for programming OpenTitan over the SPI interface.

  In order to program OpenTitan with a binary image, the image is broken into ``PAYLOAD_SIZE``
  byte chunks, each of which is transmitted as a frame over the SPI interface. A frame consists
  of four parts:
  * Digest: A ``DIGEST_SIZE`` byte digest of the rest of the frame,
  * Frame number: A ``FRAME_NUMBER_SIZE`` byte little-endian representation of the frame number.
    MSB of the last frame's frame number is set to 1 to indicate the end of the image.
  * Flash offset: A ``FLASH_OFFSET_SIZE`` byte little-endian representation of the flash offset
    to start writing the payload of the frame.
  * Payload: ``PAYLOAD_SIZE`` byte actual binary payload in little-endian format.

  OpenTitan signals correct transmission of frame N-1 by transmitting its digest (computed over
  the entire frame, i.e. including the digest field of the frame) while it receives frame N.

  Attributes:
    HASH_FUNCTION: Hash function to use for digest computations.
    DIGEST_SIZE: Size of digests (inferred from ``HASH_FUNCTION``).
    FRAME_NUMBER_SIZE: Size of the frame number field in bytes.
    FLASH_OFFSET_SIZE: Size of the flash offset field in bytes.
    PAYLOAD_SIZE: Size of the frame payload in bytes.
    is_first_frame: Indicates if this is the first frame.
    expected_ack: Expected acknowledgement value for a frame.
  """
  HASH_FUNCTION = hashlib.sha256
  DIGEST_SIZE = HASH_FUNCTION().digest_size
  FRAME_NUMBER_SIZE = 4
  FLASH_OFFSET_SIZE = 4
  PAYLOAD_SIZE = 2048 - DIGEST_SIZE - FRAME_NUMBER_SIZE - FLASH_OFFSET_SIZE

  def __init__(self, frame_number, flash_offset, payload):
    """Inits a _SpiFlashFrame.

    Also pads frame payload to ``PAYLOAD_SIZE`` bytes if needed.

    Args:
      frame_numer: Frame number.
      flash_offset: Flash offset.
      payload: Frame payload.
    """
    self._frame_number = _uint_to_le(frame_number, self.FRAME_NUMBER_SIZE)
    self._flash_offset = _uint_to_le(flash_offset, self.FLASH_OFFSET_SIZE)
    self._payload = payload
    padding = self.PAYLOAD_SIZE - len(self._payload)
    if padding > 0:
      self._payload = b''.join([self._payload, b'\xFF'*padding])
    self._digest = self.HASH_FUNCTION(b''.join([
      self._frame_number,
      self._flash_offset,
      self._payload,
    ])).digest()

  def __bytes__(self):
    return b''.join([
        self._digest,
        self._frame_number,
        self._flash_offset,
        self._payload,
    ])

  def __repr__(self):
    return f'frame 0x{_le_to_uint(self._frame_number):08X} @ 0x{_le_to_uint(self._flash_offset):08X}'

  @property
  def is_first_frame(self):
    """Indicates if this is the first frame."""
    return _le_to_uint(self._frame_number) == 0

  @property
  def expected_ack(self):
    """Expected acknowledgement value for the frame."""
    return self.HASH_FUNCTION(bytes(self)).digest()

class _Bootstrap:
  """Handles low-level details during programming OpenTitan using SAM3U on CW305.

  Initializes pins, resets OpenTitan, transmits frames, and receives acknowledgements.

  To use:
  >>> with _Bootstrap(fpga) as bootstrap:
  >>>   ...
  >>>   ack = bootstrap.transfer(frame)
  >>>   ...
  """
  _PIN_SCK='USB_A13'
  _PIN_SDI='USB_A14'
  _PIN_SDO='USB_A15'
  _PIN_CS='USB_A16'
  _PIN_TRST='USB_A17'
  _PIN_SRST='USB_A18'
  _PIN_JTAG_SPI='USB_A19'
  _PIN_BOOTSTRAP='USB_A20'
  # Delays below are in seconds.
  _BOOTSTRAP_DELAY=0.1
  _FIRST_FRAME_DELAY=0.2
  _INTER_FRAME_DELAY=0.02

  def __init__(self, fpga):
    """Inits a _Bootstrap with a CW305.

    Args:
      fpga: CW305 to be programmed, a ``cw.capture.targets.CW305`` instance.
    """
    # Configure JTAG and bootstrap pins.
    self._fpga_io = fpga.gpio_mode()
    self._fpga_io.pin_set_output(self._PIN_TRST)
    self._fpga_io.pin_set_output(self._PIN_SRST)
    self._fpga_io.pin_set_output(self._PIN_JTAG_SPI)
    self._fpga_io.pin_set_output(self._PIN_BOOTSTRAP)
    self._fpga_io.pin_set_state(self._PIN_TRST, 1)
    self._fpga_io.pin_set_state(self._PIN_SRST, 1)
    self._fpga_io.pin_set_state(self._PIN_JTAG_SPI, 1)
    self._fpga_io.pin_set_state(self._PIN_BOOTSTRAP, 0)
    # Initialize SPI pins.
    self._fpga_io.spi1_setpins(sck=self._PIN_SCK, sdo=self._PIN_SDI, sdi=self._PIN_SDO, cs=self._PIN_CS)
    self._fpga_io.spi1_enable(True)

  def _reset_opentitan(self):
    self._fpga_io.pin_set_state(self._PIN_JTAG_SPI, 1)
    self._fpga_io.pin_set_state(self._PIN_SRST, 0)
    time.sleep(self._BOOTSTRAP_DELAY)
    self._fpga_io.pin_set_state(self._PIN_SRST, 1)
    time.sleep(self._BOOTSTRAP_DELAY)

  def __enter__(self):
    """Starts bootstrapping."""
    self._fpga_io.pin_set_state(self._PIN_BOOTSTRAP, 1)
    self._reset_opentitan()
    self._fpga_io.pin_set_state(self._PIN_JTAG_SPI, 0)
    time.sleep(self._BOOTSTRAP_DELAY)
    return self

  def __exit__(self, exc_type, exc_value, traceback):
    """Ends bootstrapping."""
    self._fpga_io.pin_set_state(self._PIN_BOOTSTRAP, 0)
    self._fpga_io.pin_set_state(self._PIN_JTAG_SPI, 1)
    time.sleep(self._BOOTSTRAP_DELAY)

  def transfer(self, frame):
    """Transmits a frame over SPI and receives the acknowledgement for the previous frame."""
    # Wait longer after the first frame since it triggers a flash erase operation.
    if frame.is_first_frame:
      time.sleep(self._FIRST_FRAME_DELAY)
    else:
      time.sleep(self._INTER_FRAME_DELAY)
    print(f'Transferring {frame}.')
    # Acknowledgement is the same size as digests.
    return bytes(self._fpga_io.spi1_transfer(bytes(frame))[:_SpiFlashFrame.DIGEST_SIZE])


class SAM3UProgrammer:
  """Class for programming OpenTitan over the SPI interface of SAM3U on CW305."""
  def __init__(self, firmware_path):
    """Inits SAM3UProgrammer with the path of a firmware image."""
    self._firmware_path = firmware_path

  def run(self, fpga):
    """Programs OpenTitan over the SPI interface of SAM3U on CW305.

    This implementation has two improvements over the `spiflash` tool in
    lowRISC/opentitan:
    * Optimizes the happy path by checking the acknowledgement of frame N-1
      after transmitting frame N instead of transmitting an extra frame to check
      each frame's acknowledgement.
    * Sends an all 0xFF frame as the last frame to avoid cases where the last
      frame gets corrupted and halts the bootstrapping process.

    Args:
      fpga: CW305 to be programmed, a ``cw.capture.targets.CW305`` instance.
    """
    with _Bootstrap(fpga) as bootstrap:
      frame_number = 0
      flash_offset = 0
      prev_frame = None
      print(f'Programming OpenTitan with "{self._firmware_path}"...')
      with open(self._firmware_path, mode='rb') as fw:
        # Read fixed-size blocks from the firmware image.
        # Note: The second argument ``b''`` to ``iter`` below is the sentinel value that
        # ends the loop, i.e. the value returned by ``fw.read`` at EOF.
        for payload in iter(partial(fw.read, _SpiFlashFrame.PAYLOAD_SIZE), b''):
          frame = _SpiFlashFrame(frame_number, flash_offset, payload)
          # We need to make sure that the previous frame is transmitted correctly before
          # proceeding with the next frame.
          while True:
            # Transmit frame N, receive acknowledgement for frame N-1.
            ack = bootstrap.transfer(frame)
            if prev_frame and prev_frame.expected_ack != ack:
              # When OpenTitan encounters a transmission error or an out of
              # sequence frame, it ignores the current frame and sends the ack of
              # the last successfully received frame. Since transmission errors
              # can occur in both directions, i.e. the previous frame sent by
              # SAM3U or the ack sent by OpenTitan, and we can't tell them
              # apart, we should re-transmit the previous frame and check the
              # ack sent by OpenTitan.
              print(f'Error transferring {prev_frame}.')
              ack = bootstrap.transfer(prev_frame)
              if ack == frame.expected_ack:
                # Ack sent by OpenTitan was corrupted. Proceed with the next frame.
                break
              else:
                # Previous frame sent by SAM3U was corrupted. Send current frame again.
                pass
            else:
              # Correct acknowledgement received or this is the first frame.
              break
          prev_frame = frame
          frame_number += 1
          flash_offset += _SpiFlashFrame.PAYLOAD_SIZE
      # Transmit an all 0xFF frame with the expected frame number to finish bootstrapping.
      bootstrap.transfer(_SpiFlashFrame(frame_number | (1<<31), flash_offset, b''))
