// 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/dif/dif_otbn.h"
#include "sw/device/lib/dif/dif_rv_plic.h"
#include "sw/device/lib/irq.h"
#include "sw/device/lib/runtime/ibex.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/runtime/otbn.h"
#include "sw/device/lib/testing/entropy_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"

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

OTBN_DECLARE_APP_SYMBOLS(err_test);

static const otbn_app_t kAppErrTest = OTBN_APP_T_INIT(err_test);

OTTF_DEFINE_TEST_CONFIG();

static dif_rv_plic_t plic;
static volatile bool otbn_finished;

/**
 * Get OTBN error bits; check they match expected_err_bits.
 */
static void check_otbn_err_bits(otbn_t *otbn_ctx,
                                dif_otbn_err_bits_t expected_err_bits) {
  dif_otbn_err_bits_t otbn_err_bits;
  CHECK_DIF_OK(dif_otbn_get_err_bits(&otbn_ctx->dif, &otbn_err_bits));
  CHECK(otbn_err_bits == expected_err_bits,
        "dif_otbn_get_err_bits() produced unexpected error bits: %x",
        otbn_err_bits);
}

/**
 * Get the OTBN instruction count; check that it matches expected_insn_cnt.
 */
static void check_otbn_insn_cnt(otbn_t *otbn_ctx, uint32_t expected_insn_cnt) {
  uint32_t insn_cnt;
  CHECK_DIF_OK(dif_otbn_get_insn_cnt(&otbn_ctx->dif, &insn_cnt));
  CHECK(insn_cnt == expected_insn_cnt,
        "Expected to execute %d instructions, but got %d.", expected_insn_cnt,
        insn_cnt);
}

/**
 * Get OTBN's status; check that it matches expected_status.
 */
static void check_otbn_status(otbn_t *otbn_ctx,
                              dif_otbn_status_t expected_status) {
  dif_otbn_status_t status;
  CHECK_DIF_OK(dif_otbn_get_status(&otbn_ctx->dif, &status));
  CHECK(status == expected_status, "Unexpected status: expected %d but got %d.",
        expected_status, status);
}

/**
 * Run a binary on OTBN, waiting for completion by interrupt.
 *
 * Once the binary has finished, check for expected status, error bits and
 * instruction count.
 */
static void run_test_with_irqs(otbn_t *otbn_ctx, otbn_app_t app,
                               dif_otbn_status_t expected_status,
                               dif_otbn_err_bits_t expected_err_bits,
                               uint32_t expected_insn_cnt) {
  // Clear the otbn_finished flag: we'll set it in the interrupt handler when
  // we see the Done interrupt fire.
  otbn_finished = false;

  CHECK(otbn_load_app(otbn_ctx, app) == kOtbnOk);

  // If the the CTRL.SOFTWARE_ERRS_FATAL flag is set, a software error will be
  // promoted to a fatal error (which, among other things, bricks OTBN until
  // next reset). Make sure that's not turned on.
  CHECK(dif_otbn_set_ctrl_software_errs_fatal(&otbn_ctx->dif, false) == kDifOk);

  // Enable Done interrupt
  CHECK_DIF_OK(dif_otbn_irq_set_enabled(&otbn_ctx->dif, kDifOtbnIrqDone,
                                        kDifToggleEnabled));

  // Start OTBN
  CHECK(otbn_execute(otbn_ctx) == kOtbnOk);

  // At this point, OTBN should be running. Wait for an interrupt that says
  // it's done.
  for (;;) {
    // This looks a bit odd, but is needed to avoid a race condition where the
    // OTBN interrupt comes in after we load the otbn_finished flag but before
    // we run the WFI instruction. The trick is that WFI returns when an
    // interrupt comes in even if interrupts are globally disabled, which means
    // that the WFI can actually sit *inside* the critical section.
    irq_global_ctrl(false);
    if (otbn_finished)
      break;
    wait_for_interrupt();
    irq_global_ctrl(true);
  }
  irq_global_ctrl(true);

  check_otbn_status(otbn_ctx, expected_status);
  check_otbn_err_bits(otbn_ctx, expected_insn_cnt);
  check_otbn_insn_cnt(otbn_ctx, expected_err_bits);
}

/**
 * Initialize PLIC and enable OTBN interrupt.
 */
static void plic_init_with_irqs(void) {
  mmio_region_t base_addr =
      mmio_region_from_addr(TOP_EARLGREY_RV_PLIC_BASE_ADDR);
  CHECK_DIF_OK(dif_rv_plic_init(base_addr, &plic));

  dif_rv_plic_irq_id_t irq_id = kTopEarlgreyPlicIrqIdOtbnDone;

  // Set interrupt priority to be positive
  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(&plic, irq_id, 0x1));

  // Enable the interrupt
  CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(
      &plic, irq_id, kTopEarlgreyPlicTargetIbex0, kDifToggleEnabled));

  // Set the threshold for Ibex to 0.
  CHECK_DIF_OK(dif_rv_plic_target_set_threshold(
      &plic, kTopEarlgreyPlicTargetIbex0, 0x0));
}

/**
 * The ISR for this test.
 *
 * This function overrides the default OTTF external ISR.
 */
void ottf_external_isr(void) {
  // Find which interrupt fired at PLIC by claiming it.
  dif_rv_plic_irq_id_t irq_id;
  CHECK_DIF_OK(
      dif_rv_plic_irq_claim(&plic, kTopEarlgreyPlicTargetIbex0, &irq_id));

  // Check it was from OTBN
  top_earlgrey_plic_peripheral_t peri =
      top_earlgrey_plic_interrupt_for_peripheral[irq_id];
  CHECK(peri == kTopEarlgreyPlicPeripheralOtbn,
        "Interrupt from incorrect peripheral: (exp: %d, obs: %s)",
        kTopEarlgreyPlicPeripheralOtbn, peri);

  // Check this is the interrupt we expected
  CHECK(irq_id == kTopEarlgreyPlicIrqIdOtbnDone);

  // otbn_finished should currently be false (we're supposed to clear it before
  // starting OTBN)
  CHECK(!otbn_finished);

  // Set otbn_finished, which we'll pick up in run_test_with_irqs.
  otbn_finished = true;
}

bool test_main(void) {
  entropy_testutils_boot_mode_init();
  plic_init_with_irqs();

  // Enable the external IRQ (so that we see the interrupt from the PLIC)
  irq_global_ctrl(true);
  irq_external_ctrl(true);

  mmio_region_t base_addr = mmio_region_from_addr(TOP_EARLGREY_OTBN_BASE_ADDR);

  otbn_t otbn_ctx;
  CHECK(otbn_init(&otbn_ctx, base_addr) == kOtbnOk);

  run_test_with_irqs(&otbn_ctx, kAppErrTest, kDifOtbnStatusIdle,
                     kDifOtbnErrBitsBadDataAddr, 1);

  return true;
}
