// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/lib/crypto/drivers/otbn.h"

#include <assert.h>
#include <stddef.h>
#include <stdint.h>

#include "sw/device/lib/base/bitfield.h"
#include "sw/device/lib/base/mmio.h"

#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
#include "otbn_regs.h"  // Generated.

#define ASSERT_ERR_BIT_MATCH(enum_val, autogen_val) \
  static_assert(enum_val == 1 << (autogen_val),     \
                "OTBN register bit doesn't match autogen value.");

ASSERT_ERR_BIT_MATCH(kOtbnErrBitsBadDataAddr, OTBN_ERR_BITS_BAD_DATA_ADDR_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsBadInsnAddr, OTBN_ERR_BITS_BAD_INSN_ADDR_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsCallStack, OTBN_ERR_BITS_CALL_STACK_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsIllegalInsn, OTBN_ERR_BITS_ILLEGAL_INSN_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsLoop, OTBN_ERR_BITS_LOOP_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsImemIntgViolation,
                     OTBN_ERR_BITS_IMEM_INTG_VIOLATION_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsDmemIntgViolation,
                     OTBN_ERR_BITS_DMEM_INTG_VIOLATION_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsRegIntgViolation,
                     OTBN_ERR_BITS_REG_INTG_VIOLATION_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsBusIntgViolation,
                     OTBN_ERR_BITS_BUS_INTG_VIOLATION_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsIllegalBusAccess,
                     OTBN_ERR_BITS_ILLEGAL_BUS_ACCESS_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsLifecycleEscalation,
                     OTBN_ERR_BITS_LIFECYCLE_ESCALATION_BIT);
ASSERT_ERR_BIT_MATCH(kOtbnErrBitsFatalSoftware,
                     OTBN_ERR_BITS_FATAL_SOFTWARE_BIT);

const size_t kOtbnDMemSizeBytes = OTBN_DMEM_SIZE_BYTES;
const size_t kOtbnIMemSizeBytes = OTBN_IMEM_SIZE_BYTES;

enum { kBase = TOP_EARLGREY_OTBN_BASE_ADDR };

/**
 * Ensures that `offset_bytes` and `len` are valid for a given `mem_size`.
 */
static otbn_error_t check_offset_len(uint32_t offset_bytes, size_t num_words,
                                     size_t mem_size) {
  if (offset_bytes + num_words * sizeof(uint32_t) <
          num_words * sizeof(uint32_t) ||
      offset_bytes + num_words * sizeof(uint32_t) > mem_size) {
    return kOtbnErrorBadOffsetLen;
  }
  return kOtbnErrorOk;
}

void otbn_execute(void) {
  mmio_region_write32(mmio_region_from_addr(kBase), OTBN_CMD_REG_OFFSET,
                      kOtbnCmdExecute);
}

bool otbn_is_busy() {
  uint32_t status =
      mmio_region_read32(mmio_region_from_addr(kBase), OTBN_STATUS_REG_OFFSET);
  return status != kOtbnStatusIdle && status != kOtbnStatusLocked;
}

void otbn_get_err_bits(otbn_err_bits_t *err_bits) {
  *err_bits = mmio_region_read32(mmio_region_from_addr(kBase),
                                 OTBN_ERR_BITS_REG_OFFSET);
}

otbn_error_t otbn_imem_write(uint32_t offset_bytes, const uint32_t *src,
                             size_t num_words) {
  OTBN_RETURN_IF_ERROR(
      check_offset_len(offset_bytes, num_words, kOtbnIMemSizeBytes));
  mmio_region_t otbn_base = mmio_region_from_addr(kBase);

  for (size_t i = 0; i < num_words; ++i) {
    mmio_region_write32(
        otbn_base, OTBN_IMEM_REG_OFFSET + offset_bytes + i * sizeof(uint32_t),
        src[i]);
  }

  return kOtbnErrorOk;
}

otbn_error_t otbn_dmem_write(uint32_t offset_bytes, const uint32_t *src,
                             size_t num_words) {
  OTBN_RETURN_IF_ERROR(
      check_offset_len(offset_bytes, num_words, kOtbnDMemSizeBytes));
  mmio_region_t otbn_base = mmio_region_from_addr(kBase);

  for (size_t i = 0; i < num_words; ++i) {
    mmio_region_write32(
        otbn_base, OTBN_DMEM_REG_OFFSET + offset_bytes + i * sizeof(uint32_t),
        src[i]);
  }

  return kOtbnErrorOk;
}

otbn_error_t otbn_dmem_read(uint32_t offset_bytes, uint32_t *dest,
                            size_t num_words) {
  OTBN_RETURN_IF_ERROR(
      check_offset_len(offset_bytes, num_words, kOtbnDMemSizeBytes));
  mmio_region_t otbn_base = mmio_region_from_addr(kBase);

  for (size_t i = 0; i < num_words; ++i) {
    dest[i] = mmio_region_read32(
        otbn_base, OTBN_DMEM_REG_OFFSET + offset_bytes + i * sizeof(uint32_t));
  }

  return kOtbnErrorOk;
}

void otbn_zero_dmem(void) {
  mmio_region_t otbn_base = mmio_region_from_addr(kBase);
  for (size_t i = 0; i < kOtbnDMemSizeBytes; i += sizeof(uint32_t)) {
    mmio_region_write32(otbn_base, OTBN_DMEM_REG_OFFSET + i, 0u);
  }
}

otbn_error_t otbn_set_ctrl_software_errs_fatal(bool enable) {
  // Only one bit in the CTRL register so no need to read current value.
  uint32_t new_ctrl;

  if (enable) {
    new_ctrl = 1;
  } else {
    new_ctrl = 0;
  }

  mmio_region_t otbn_base = mmio_region_from_addr(kBase);
  mmio_region_write32(otbn_base, OTBN_CTRL_REG_OFFSET, new_ctrl);
  if (mmio_region_read32(otbn_base, OTBN_CTRL_REG_OFFSET) != new_ctrl) {
    return kOtbnErrorUnavailable;
  }

  return kOtbnErrorOk;
}
