// 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/base/macros.h"
#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_base.h"
#include "sw/device/lib/dif/dif_flash_ctrl.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/flash_ctrl_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"

#define CHECK_EQZ(x) CHECK((x) == 0)
#define CHECK_NEZ(x) CHECK((x) != 0)

static dif_flash_ctrl_device_info_t flash_info;
#define FLASH_WORD_SZ flash_info.bytes_per_word
#define FLASH_PAGE_SZ flash_info.bytes_per_page
#define FLASH_WORDS_PER_PAGE (FLASH_PAGE_SZ / FLASH_WORD_SZ)
#define FLASH_PAGES_PER_BANK flash_info.data_pages
#define FLASH_BANK_SZ (flash_info.data_pages * flash_info.bytes_per_page)

static dif_flash_ctrl_state_t flash;

/*
 * Basic test of page erase / program / read functions.
 * Tests pages from both the data and info partitions.
 */
static void test_basic_io(void) {
  // The info partitions have no default access. Specifically set up a region.
  dif_flash_ctrl_info_region_t info_region = {
      .bank = 1, .partition_id = 0, .page = 0};
  dif_flash_ctrl_region_properties_t region_properties = {
      .rd_en = kMultiBitBool4True,
      .prog_en = kMultiBitBool4True,
      .erase_en = kMultiBitBool4True,
      .scramble_en = kMultiBitBool4True,
      .ecc_en = kMultiBitBool4True,
      .high_endurance_en = kMultiBitBool4False};
  CHECK_DIF_OK(dif_flash_ctrl_set_info_region_properties(&flash, info_region,
                                                         region_properties));
  CHECK_DIF_OK(dif_flash_ctrl_set_info_region_enablement(&flash, info_region,
                                                         kDifToggleEnabled));

  // Also set up data region to enable scrambling.
  region_properties.rd_en = kMultiBitBool4True;
  region_properties.prog_en = kMultiBitBool4True;
  region_properties.erase_en = kMultiBitBool4True;

  dif_flash_ctrl_data_region_properties_t data_region = {
      .base = FLASH_PAGES_PER_BANK,
      .size = 0x1,
      .properties = region_properties};

  CHECK_DIF_OK(
      dif_flash_ctrl_set_data_region_properties(&flash, 0, data_region));
  CHECK_DIF_OK(
      dif_flash_ctrl_set_data_region_enablement(&flash, 0, kDifToggleEnabled));

  ptrdiff_t flash_bank_1_addr = FLASH_BANK_SZ;
  mmio_region_t flash_bank_1 = mmio_region_from_addr(
      TOP_EARLGREY_FLASH_CTRL_MEM_BASE_ADDR + flash_bank_1_addr);

  // Test erasing flash data partition; this should turn the whole bank to all
  // ones.
  CHECK(flash_ctrl_testutils_erase_page(&flash, flash_bank_1_addr,
                                        /*partition_id=*/0,
                                        kDifFlashCtrlPartitionTypeData));
  for (int i = 0; i < FLASH_WORDS_PER_PAGE; ++i) {
    CHECK_EQZ(~mmio_region_read32(flash_bank_1, i * sizeof(uint32_t)));
  }

  // Erasing flash info partition 0; this should turn one page to all ones.
  CHECK(flash_ctrl_testutils_erase_page(&flash, flash_bank_1_addr,
                                        /*partition_id=*/0,
                                        kDifFlashCtrlPartitionTypeInfo));

  // Prepare an entire page of non-trivial data to program
  // into flash.
  uint32_t input_page[FLASH_WORDS_PER_PAGE];
  uint32_t output_page[FLASH_WORDS_PER_PAGE];
  memset(input_page, 0xa5, FLASH_WORDS_PER_PAGE * sizeof(uint32_t));
  for (int i = 0; i < FLASH_WORDS_PER_PAGE; i += 2) {
    input_page[i] ^= 0xffffffff;
  }

  // Attempt to live-program an entire page, where the overall
  // payload is much larger than the internal flash FIFO.
  CHECK(flash_ctrl_testutils_erase_and_write_page(
      &flash, flash_bank_1_addr, /*partition_id=*/0, input_page,
      kDifFlashCtrlPartitionTypeData, FLASH_WORDS_PER_PAGE));
  CHECK(flash_ctrl_testutils_read(&flash, flash_bank_1_addr, /*partition_id=*/0,
                                  output_page, kDifFlashCtrlPartitionTypeData,
                                  FLASH_WORDS_PER_PAGE, /*delay=*/0));
  CHECK_ARRAYS_EQ(output_page, input_page, FLASH_WORDS_PER_PAGE);

  // Check from host side also.
  for (int i = 0; i < FLASH_WORDS_PER_PAGE; i++) {
    output_page[i] = mmio_region_read32(flash_bank_1, i * sizeof(uint32_t));
  }
  CHECK_ARRAYS_EQ(output_page, input_page, FLASH_WORDS_PER_PAGE);

  // Similar check for info page.
  CHECK(flash_ctrl_testutils_erase_and_write_page(
      &flash, flash_bank_1_addr, /*partition_id=*/0, input_page,
      kDifFlashCtrlPartitionTypeInfo, FLASH_WORDS_PER_PAGE));
  CHECK(flash_ctrl_testutils_read(&flash, flash_bank_1_addr, /*partition_id=*/0,
                                  output_page, kDifFlashCtrlPartitionTypeInfo,
                                  FLASH_WORDS_PER_PAGE, /*delay=*/0));
  CHECK_ARRAYS_EQ(output_page, input_page, FLASH_WORDS_PER_PAGE);

  // Set up default access for data partitions.
  flash_ctrl_testutils_default_region_access(
      &flash, /*rd_en=*/true, /*prog_en=*/true, /*erase_en=*/true,
      /*scramble_en=*/false, /*ecc_en=*/false, /*high_endurance_en=*/false);

  // Perform similar test on the last page of the first bank.
  ptrdiff_t flash_bank_0_last_page_addr = flash_bank_1_addr - FLASH_PAGE_SZ;
  mmio_region_t flash_bank_0_last_page = mmio_region_from_addr(
      TOP_EARLGREY_FLASH_CTRL_MEM_BASE_ADDR + flash_bank_0_last_page_addr);
  CHECK(flash_ctrl_testutils_erase_page(&flash, flash_bank_0_last_page_addr,
                                        /*partition_id=*/0,
                                        kDifFlashCtrlPartitionTypeData));
  for (int i = 0; i < FLASH_WORDS_PER_PAGE; ++i) {
    CHECK_EQZ(
        ~mmio_region_read32(flash_bank_0_last_page, i * sizeof(uint32_t)));
  }

  CHECK(flash_ctrl_testutils_write(
      &flash, flash_bank_0_last_page_addr, /*partition_id=*/0, input_page,
      kDifFlashCtrlPartitionTypeData, FLASH_WORDS_PER_PAGE));
  CHECK(flash_ctrl_testutils_read(
      &flash, flash_bank_0_last_page_addr, /*partition_id=*/0, output_page,
      kDifFlashCtrlPartitionTypeData, FLASH_WORDS_PER_PAGE, /*delay=*/0));

  CHECK_ARRAYS_EQ(output_page, input_page, FLASH_WORDS_PER_PAGE);
}

static void test_memory_protection(void) {
  dif_flash_ctrl_state_t flash;
  CHECK_DIF_OK(dif_flash_ctrl_init_state(
      &flash, mmio_region_from_addr(TOP_EARLGREY_FLASH_CTRL_CORE_BASE_ADDR)));

  // Set up default access for data partitions.
  flash_ctrl_testutils_default_region_access(
      &flash, /*rd_en=*/true, /*prog_en=*/true, /*erase_en=*/true,
      /*scramble_en=*/false, /*ecc_en=*/false, /*high_endurance_en=*/false);

  // A memory protection region representing the first page of the second bank.
  dif_flash_ctrl_region_properties_t protected_properties = {
      .rd_en = kMultiBitBool4True,
      .prog_en = kMultiBitBool4True,
      .erase_en = kMultiBitBool4True,
      .scramble_en = kMultiBitBool4False,
      .ecc_en = kMultiBitBool4True,
      .high_endurance_en = kMultiBitBool4False};

  dif_flash_ctrl_data_region_properties_t protected_region = {
      .base = FLASH_PAGES_PER_BANK,
      .size = 0x1,
      .properties = protected_properties};

  uintptr_t ok_region_start = TOP_EARLGREY_FLASH_CTRL_MEM_BASE_ADDR +
                              (protected_region.base * FLASH_PAGE_SZ);
  uintptr_t ok_region_end =
      ok_region_start + (protected_region.size * FLASH_PAGE_SZ);
  mmio_region_t ok_region = mmio_region_from_addr(ok_region_start);

  uintptr_t bad_region_start = ok_region_end;

  // Erase good and bad regions.
  CHECK(flash_ctrl_testutils_erase_page(&flash, ok_region_start,
                                        /*partition_id=*/0,
                                        kDifFlashCtrlPartitionTypeData));
  CHECK(flash_ctrl_testutils_erase_page(&flash, bad_region_start,
                                        /*partition_id=*/0,
                                        kDifFlashCtrlPartitionTypeData));

  // Turn off flash access by default.
  flash_ctrl_testutils_default_region_access(
      &flash, /*rd_en=*/false, /*prog_en=*/false, /*erase_en=*/false,
      /*scramble_en=*/false, /*ecc_en=*/false, /*high_endurance_en=*/false);

  // Enable protected region for access.
  CHECK_DIF_OK(
      dif_flash_ctrl_set_data_region_properties(&flash, 0, protected_region));

  // Attempt to perform a write.
  uintptr_t region_boundary_start = bad_region_start - (FLASH_WORD_SZ * 2);
  mmio_region_t region_boundary = mmio_region_from_addr(region_boundary_start);

  // Place half the words in the good region and half in the bad.
  uint32_t words[(FLASH_WORD_SZ * 2 * 2) / sizeof(uint32_t)];
  memset(words, 0xa5, ARRAYSIZE(words) * sizeof(uint32_t));
  for (int i = 0; i < ARRAYSIZE(words); ++i) {
    words[i] += i;
  }

  // Perform a partial write.
  CHECK(!flash_ctrl_testutils_write(
      &flash, region_boundary_start, /*partition_id=*/0, words,
      kDifFlashCtrlPartitionTypeData, ARRAYSIZE(words)));
  // Words in the good region should still match, while words in the bad
  // region should be all-ones, since we erased.
  for (int i = 0; i < ARRAYSIZE(words); ++i) {
    uint32_t expected = 0xffffffff;
    if (i < ARRAYSIZE(words) / 2) {
      expected = words[i];
    }
    CHECK(mmio_region_read32(region_boundary, i * sizeof(uint32_t)) ==
          expected);
  }

  // Attempt to erase bad page, which should fail.
  CHECK(!flash_ctrl_testutils_erase_page(&flash, bad_region_start,
                                         /*partition_id=*/0,
                                         kDifFlashCtrlPartitionTypeData));

  // Attempt to erase the good page, which should succeed.
  CHECK(flash_ctrl_testutils_erase_page(&flash, ok_region_start,
                                        /*partition_id=*/0,
                                        kDifFlashCtrlPartitionTypeData));
  for (int i = 0; i < FLASH_WORDS_PER_PAGE; i++) {
    CHECK_EQZ(~mmio_region_read32(ok_region, i * sizeof(uint32_t)));
  }
}

OTTF_DEFINE_TEST_CONFIG();

bool test_main(void) {
  flash_info = dif_flash_ctrl_get_device_info();
  CHECK_DIF_OK(dif_flash_ctrl_init_state(
      &flash, mmio_region_from_addr(TOP_EARLGREY_FLASH_CTRL_CORE_BASE_ADDR)));
  flash_ctrl_testutils_wait_for_init(&flash);

  LOG_INFO("flash test!");

  CHECK_DIF_OK(dif_flash_ctrl_set_bank_erase_enablement(&flash, /*bank=*/0,
                                                        kDifToggleEnabled));
  CHECK_DIF_OK(dif_flash_ctrl_set_bank_erase_enablement(&flash, /*bank=*/1,
                                                        kDifToggleEnabled));

  test_basic_io();
  test_memory_protection();

  CHECK_DIF_OK(dif_flash_ctrl_set_bank_erase_enablement(&flash, /*bank=*/0,
                                                        kDifToggleDisabled));
  CHECK_DIF_OK(dif_flash_ctrl_set_bank_erase_enablement(&flash, /*bank=*/1,
                                                        kDifToggleDisabled));

  return true;
}
