/*
 * Copyright 2023 Google LLC
 * Copyright lowRISC contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "hw/top_matcha/sw/autogen/top_matcha.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_flash_ctrl.h"
#include "sw/device/lib/dif/dif_rv_plic.h"
#include "sw/device/lib/runtime/irq.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/autogen/isr_testutils.h"
#include "sw/device/lib/testing/flash_ctrl_testutils.h"
#include "sw/device/lib/testing/rv_plic_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"

#define FLASH_CTRL_NUM_IRQS 5

OTTF_DEFINE_TEST_CONFIG();

static dif_rv_plic_t plic0;
static dif_flash_ctrl_state_t flash_state;
static dif_flash_ctrl_t flash_ctrl;

static plic_isr_ctx_t plic_ctx = {
    .rv_plic = &plic0,
    .hart_id = kTopMatchaPlicTargetIbex0,
};

static flash_ctrl_isr_ctx_t flash_ctx = {
    .flash_ctrl = &flash_ctrl,
    .plic_flash_ctrl_start_irq_id = kTopMatchaPlicIrqIdFlashCtrlProgEmpty,
    .is_only_irq = false,
};

enum {
  kFlashInfoPageIdCreatorSecret = 1,
  kFlashInfoPageIdOwnerSecret = 2,
  kFlashInfoPageIdIsoPart = 3,
  kFlashInfoBank = 0,
  kRegionBaseBank0Page0Index = 0,
  kRegionBaseBank1Page0Index = 256,
  kRegionBaseBank1Page255Index = 511,
  kFlashBank0DataRegion = 0,
  kFlashBank1DataRegion = 1,
  kPartitionId = 0,
  kRegionSize = 1,
  kInfoSize = 16,
  kDataSize = 32,
  kPageSize = 2048,
};

const uint32_t kRandomData1[kInfoSize] = {
    0xb295d21b, 0xecdfbdcd, 0x67e7ab2d, 0x6f660b08, 0x273bf65c, 0xe80f1695,
    0x586b80db, 0xc3dba27e, 0xdc124c5d, 0xb01ccd52, 0x815713e1, 0x31a141b2,
    0x2124be3b, 0x299a6f2a, 0x1f2a4741, 0x1a073cc0,
};

const uint32_t kRandomData2[kInfoSize] = {
    0x69e705a0, 0x65c2ec6b, 0x04b0b634, 0x59313526, 0x1858aee1, 0xd49f3ba9,
    0x230bcd38, 0xc1eb6b3e, 0x68c15e3b, 0x024d02a9, 0x0b062ae4, 0x334dd155,
    0x53fdbf8a, 0x3792f1e2, 0xee317161, 0x33b19bf3,
};

const uint32_t kRandomData3[kInfoSize] = {
    0x2b78dbf5, 0x3e6e5a00, 0xbf82c6d5, 0x68d8e33f, 0x9c524bbc, 0xac5beeef,
    0x1287ca5a, 0x12b61419, 0x872e709f, 0xf91b7c0c, 0x18312a1f, 0x325cef9a,
    0x19fefa95, 0x4ceb421b, 0xa57d74c4, 0xaf1d723d,
};

const uint32_t kRandomData4[kDataSize] = {
    0x0f5b84a3, 0xfa0330c3, 0xe125d174, 0x959d9779, 0xe10da3ba, 0x739e804d,
    0xf8f8c317, 0xf236e75f, 0xa2118c37, 0x2d12fa9d, 0xa6fd72cd, 0x4b21d3dc,
    0x6d36ca93, 0xbac514a6, 0x5f5695f8, 0xe7fdbe07, 0xde77eac9, 0x5ee7432f,
    0xc7d26081, 0xae1d7262, 0x47d46715, 0x9da2de97, 0xa41e639d, 0x34470ce0,
    0x8ac69175, 0x1dbcd910, 0x8193d43e, 0xe1538689, 0x166599e1, 0x0d5cc465,
    0x86298854, 0x93121b13,
};

const uint32_t kRandomData5[kDataSize] = {
    0xe5214227, 0x8473a570, 0xc6fc9728, 0x6110fbbe, 0xa2b4cdc8, 0x0156836a,
    0xa0c90954, 0x23e66c9b, 0x607c9e7c, 0x40f993b6, 0x253dfc7d, 0xe0c70727,
    0xa7b974ea, 0x0e8561c8, 0xfe8858a9, 0x36bf06bc, 0x2a734e91, 0xf0aca1e6,
    0x6e22f4c5, 0x469cb0a2, 0x0f6bbc43, 0xc719f5cd, 0x0a129d7d, 0x9a6c171e,
    0x1b39ff3a, 0x9644ab82, 0x5209d14c, 0x46a7e380, 0x575b1e0b, 0x4af5e8c3,
    0xfcbbfa64, 0xe3afddf2,
};

static volatile bool expected_irqs[FLASH_CTRL_NUM_IRQS];
static volatile bool fired_irqs[FLASH_CTRL_NUM_IRQS];

/**
 * Provides external IRQ handling for this test.
 *
 * This function overrides the default OTTF external ISR.
 */
void ottf_external_isr(void) {
  top_matcha_plic_peripheral_t peripheral_serviced;
  dif_flash_ctrl_irq_t irq_serviced;
  isr_testutils_flash_ctrl_isr(plic_ctx, flash_ctx, &peripheral_serviced,
                               &irq_serviced);
  CHECK(peripheral_serviced == kTopMatchaPlicPeripheralFlashCtrl,
        "Interurpt from unexpected peripheral: %d", peripheral_serviced);
  fired_irqs[irq_serviced] = true;
}

/**
 * Clear the volatile IRQ variables.
 */
static void clear_irq_variables(void) {
  for (int i = 0; i < FLASH_CTRL_NUM_IRQS; ++i) {
    expected_irqs[i] = false;
    fired_irqs[i] = false;
  }
}

/**
 * Initializes FLASH_CTRL and enables the relevant interrupts.
 */
static void flash_ctrl_init_with_irqs(mmio_region_t base_addr,
                                      dif_flash_ctrl_state_t *flash_state,
                                      dif_flash_ctrl_t *flash_ctrl) {
  CHECK_DIF_OK(dif_flash_ctrl_init(base_addr, flash_ctrl));
  CHECK_DIF_OK(dif_flash_ctrl_init_state(flash_state, base_addr));

  for (int i = 0; i < FLASH_CTRL_NUM_IRQS; ++i) {
    CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(
        flash_ctrl, kDifFlashCtrlIrqProgEmpty + i, kDifToggleEnabled));
  }
  clear_irq_variables();
}

/**
 * Compares the expected and fired IRQs and clears both.
 */
static void compare_and_clear_irq_variables(void) {
  for (int i = 0; i < FLASH_CTRL_NUM_IRQS; ++i) {
    CHECK(expected_irqs[i] == fired_irqs[i], "expected IRQ mismatch = %d", i);
  }
  clear_irq_variables();
}

/**
 * Check data read from host interface against known data.
 */
static void read_and_check_host_if(uint32_t addr, const uint32_t *check_data) {
  mmio_region_t flash_addr =
      mmio_region_from_addr(TOP_MATCHA_EFLASH_BASE_ADDR + addr);
  uint32_t host_data[kDataSize];
  for (int i = 0; i < kDataSize; ++i) {
    host_data[i] = mmio_region_read32(flash_addr, i * sizeof(uint32_t));
  }
  CHECK_ARRAYS_EQ(host_data, check_data, kDataSize);
}

/**
 * Tests the interrupts for erase, write and
 * read of the specified information partition.
 * Confirms that the written data is read back correctly.
 */
static void do_info_partition_test(uint32_t partition_number,
                                   const uint32_t *test_data) {
  uint32_t address = flash_ctrl_testutils_info_region_setup(
      &flash_state, partition_number, kFlashInfoBank, kPartitionId);

  CHECK_DIF_OK(dif_flash_ctrl_set_prog_fifo_watermark(&flash_state, 0));
  CHECK_DIF_OK(dif_flash_ctrl_set_read_fifo_watermark(&flash_state, 8));

  clear_irq_variables();

  expected_irqs[kDifFlashCtrlIrqOpDone] = true;
  CHECK(flash_ctrl_testutils_erase_page(&flash_state, address, kPartitionId,
                                        kDifFlashCtrlPartitionTypeInfo));
  compare_and_clear_irq_variables();

  expected_irqs[kDifFlashCtrlIrqOpDone] = true;
  expected_irqs[kDifFlashCtrlIrqProgEmpty] = true;
  expected_irqs[kDifFlashCtrlIrqProgLvl] = true;
  CHECK(flash_ctrl_testutils_write(&flash_state, address, kPartitionId,
                                   test_data, kDifFlashCtrlPartitionTypeInfo,
                                   kInfoSize));

  compare_and_clear_irq_variables();

  uint32_t readback_data[kInfoSize];
  expected_irqs[kDifFlashCtrlIrqOpDone] = true;
  expected_irqs[kDifFlashCtrlIrqRdLvl] = true;
  expected_irqs[kDifFlashCtrlIrqRdFull] = true;
  CHECK(flash_ctrl_testutils_read(&flash_state, address, kPartitionId,
                                  readback_data, kDifFlashCtrlPartitionTypeInfo,
                                  kInfoSize, 1));

  compare_and_clear_irq_variables();

  CHECK_ARRAYS_EQ(readback_data, test_data, kInfoSize);
}

/**
 * Tests the interrupts for read of bank0 data partition.
 * Only read is tested as this partition contains the program
 * code so should not be erased or written.
 * The data read via the flash_ctrl interface is checked against the
 * data read via the host interface.
 */
static void do_bank0_data_partition_test(void) {
  uint32_t address = flash_ctrl_testutils_data_region_setup(
      &flash_state, kRegionBaseBank0Page0Index, kFlashBank0DataRegion,
      kRegionSize);

  CHECK_DIF_OK(dif_flash_ctrl_set_read_fifo_watermark(&flash_state, 8));

  clear_irq_variables();
  expected_irqs[kDifFlashCtrlIrqOpDone] = true;
  expected_irqs[kDifFlashCtrlIrqRdLvl] = true;
  expected_irqs[kDifFlashCtrlIrqRdFull] = true;

  uint32_t readback_data[kDataSize];
  CHECK(flash_ctrl_testutils_read(&flash_state, address, kPartitionId,
                                  readback_data, kDifFlashCtrlPartitionTypeData,
                                  kDataSize, 1));

  compare_and_clear_irq_variables();
  read_and_check_host_if(0, readback_data);
}

/**
 * Tests the interrupts for erase, write and read of
 * the lowest and highest page of bank 1 data partition.
 * Confirms that the written data is read back correctly.
 * The whole bank is then erased and the interrupt is checked
 * followed by confirmation that the previously written data
 * has been wiped.
 */
static void do_bank1_data_partition_test(void) {
  uint32_t address;

  CHECK_DIF_OK(dif_flash_ctrl_set_prog_fifo_watermark(&flash_state, 0));
  CHECK_DIF_OK(dif_flash_ctrl_set_read_fifo_watermark(&flash_state, 8));

  // Loop for low and high page erase, write and read.
  for (int i = 0; i < 2; ++i) {
    uint32_t page_index =
        (i == 0) ? kRegionBaseBank1Page0Index : kRegionBaseBank1Page255Index;
    const uint32_t *test_data = (i == 0) ? kRandomData4 : kRandomData5;

    address = flash_ctrl_testutils_data_region_setup(
        &flash_state, page_index, kFlashBank1DataRegion, kRegionSize);

    clear_irq_variables();

    expected_irqs[kDifFlashCtrlIrqOpDone] = true;
    CHECK(flash_ctrl_testutils_erase_page(&flash_state, address, kPartitionId,
                                          kDifFlashCtrlPartitionTypeData));

    compare_and_clear_irq_variables();

    expected_irqs[kDifFlashCtrlIrqOpDone] = true;
    expected_irqs[kDifFlashCtrlIrqProgEmpty] = true;
    expected_irqs[kDifFlashCtrlIrqProgLvl] = true;
    CHECK(flash_ctrl_testutils_write(&flash_state, address, kPartitionId,
                                     test_data, kDifFlashCtrlPartitionTypeData,
                                     kDataSize));

    compare_and_clear_irq_variables();

    uint32_t readback_data[kDataSize];
    expected_irqs[kDifFlashCtrlIrqOpDone] = true;
    expected_irqs[kDifFlashCtrlIrqRdLvl] = true;
    expected_irqs[kDifFlashCtrlIrqRdFull] = true;
    CHECK(flash_ctrl_testutils_read(
        &flash_state, address, kPartitionId, readback_data,
        kDifFlashCtrlPartitionTypeData, kDataSize, 1));

    compare_and_clear_irq_variables();

    read_and_check_host_if(kPageSize * page_index, test_data);
    CHECK_ARRAYS_EQ(readback_data, test_data, kDataSize);
  }

  // Erasing the whole of bank 1.
  CHECK_DIF_OK(dif_flash_ctrl_set_bank_erase_enablement(&flash_state, 1,
                                                        kDifToggleEnabled));
  expected_irqs[kDifFlashCtrlIrqOpDone] = true;

  address = flash_ctrl_testutils_data_region_setup(
      &flash_state, kRegionBaseBank1Page0Index, kFlashBank1DataRegion,
      kRegionSize);
  dif_flash_ctrl_transaction_t transaction = {
      .byte_address = address,
      .op = kDifFlashCtrlOpBankErase,
      .partition_type = kDifFlashCtrlPartitionTypeData,
      .partition_id = 0x0,
      .word_count = 0x0};
  CHECK_DIF_OK(dif_flash_ctrl_start(&flash_state, transaction));
  CHECK(flash_ctrl_testutils_wait_transaction_end(&flash_state));

  compare_and_clear_irq_variables();

  // Loop for low and high page read back after bank erase.
  for (int i = 0; i < 2; ++i) {
    uint32_t page_index =
        (i == 0) ? kRegionBaseBank1Page0Index : kRegionBaseBank1Page255Index;

    address = flash_ctrl_testutils_data_region_setup(
        &flash_state, page_index, kFlashBank1DataRegion, kRegionSize);

    uint32_t readback_data[kDataSize];
    expected_irqs[kDifFlashCtrlIrqOpDone] = true;
    expected_irqs[kDifFlashCtrlIrqRdLvl] = true;
    expected_irqs[kDifFlashCtrlIrqRdFull] = true;
    CHECK(flash_ctrl_testutils_read(
        &flash_state, address, kPartitionId, readback_data,
        kDifFlashCtrlPartitionTypeData, kDataSize, 1));

    compare_and_clear_irq_variables();

    uint32_t expected_data[kDataSize];
    memset(expected_data, 0xff, sizeof(expected_data));

    read_and_check_host_if(kPageSize * page_index, expected_data);
    CHECK_ARRAYS_EQ(readback_data, expected_data, kDataSize);
  }
}

bool test_main(void) {
  CHECK_DIF_OK(dif_rv_plic_init(
      mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR), &plic0));

  flash_ctrl_init_with_irqs(
      mmio_region_from_addr(TOP_MATCHA_FLASH_CTRL_CORE_BASE_ADDR), &flash_state,
      &flash_ctrl);
  rv_plic_testutils_irq_range_enable(&plic0, plic_ctx.hart_id,
                                     kTopMatchaPlicIrqIdFlashCtrlProgEmpty,
                                     kTopMatchaPlicIrqIdFlashCtrlOpDone);

  // Enable the external IRQ at Ibex.
  irq_global_ctrl(true);
  irq_external_ctrl(true);

  do_info_partition_test(kFlashInfoPageIdCreatorSecret, kRandomData1);
  do_info_partition_test(kFlashInfoPageIdOwnerSecret, kRandomData2);
  do_info_partition_test(kFlashInfoPageIdIsoPart, kRandomData3);
  do_bank0_data_partition_test();
  do_bank1_data_partition_test();

  return true;
}
