/*
 * Copyright 2023 Google LLC
 *
 * 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 "dma_regs.h"  // Generated.
#include "hw/top_matcha/sw/autogen/top_matcha.h"
#include "sw/device/lib/arch/device.h"
#include "sw/device/lib/dif/dif_dma.h"
#include "sw/device/lib/dif/dif_rv_plic.h"
#include "sw/device/lib/dif/dif_uart.h"
#include "sw/device/lib/runtime/hart.h"
#include "sw/device/lib/runtime/irq.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/runtime/print.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_test_config.h"
#include "sw/device/lib/testing/test_framework/status.h"
#include "sw/device/lib/testing/test_framework/test_util.h"

#define LINE_WIDTH 1
#define LINE_COUNT 4
#define LINE_STRIDE 0

#define READ_START_OFFSET 0xFFF0
#define WRITE_START_OFFSET 0x20000
#define READER_START_ADDR (TOP_MATCHA_RAM_MAIN_BASE_ADDR + READ_START_OFFSET)
#define WRITER_START_ADDR (TOP_MATCHA_RAM_SMC_BASE_ADDR + WRITE_START_OFFSET)

#define IRQ_PRIO 1
#define WORD_OFFSET 4

OTTF_DEFINE_TEST_CONFIG();

static dif_dma_t dma;
static dif_rv_plic_t plic_sec;
static dif_uart_t uart;

const uint32_t data[LINE_COUNT] = {0xcafeb0ba, 0xdeadbeef, 0xdeadb0ba,
                                   0xbeefcafe};

void ottf_external_isr(void) {
  LOG_INFO("Writer interrupt received!");

  uint32_t ram_smc_data[LINE_COUNT];
  dif_rv_plic_irq_id_t plic_irq_id;
  dif_dma_irq_state_snapshot_t intr_state;

  mmio_region_t writer_start_addr = mmio_region_from_addr(WRITER_START_ADDR);

  // Claim PLIC IRQ, perform DMA interrupt reg checks after
  // clearing IP writer interrupt, then compare data.
  CHECK_DIF_OK(dif_dma_irq_get_state(&dma, &intr_state));
  CHECK(intr_state == (1 << DMA_INTR_STATE_WTR_INTR_BIT |
                       1 << DMA_INTR_STATE_RDR_INTR_BIT),
        "Expected: 0x3 | Actual: %h", intr_state);

  CHECK_DIF_OK(dif_dma_irq_acknowledge(&dma, kDifDmaIrqWriterDone));
  CHECK_DIF_OK(dif_rv_plic_irq_claim(&plic_sec, kTopMatchaPlicTargetIbex0,
                                     &plic_irq_id));

  CHECK_DIF_OK(dif_dma_irq_get_state(&dma, &intr_state));
  CHECK(intr_state == (0 << DMA_INTR_STATE_WTR_INTR_BIT |
                       1 << DMA_INTR_STATE_RDR_INTR_BIT),
        "Expected: 0x2 | Actual: %h", intr_state);

  for (int i = 0; i < LINE_COUNT; i++) {
    ram_smc_data[i] = mmio_region_read32(writer_start_addr, (i * WORD_OFFSET));
    CHECK(data[i] == ram_smc_data[i],
          "Data not equivalent. i:%d - data: %h | ram_smc_data: %h", i, data[i],
          ram_smc_data[i]);
  }

  CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic_sec, kTopMatchaPlicTargetIbex0,
                                        plic_irq_id));

  test_status_set(kTestStatusPassed);
}

void _ottf_main(void) {
  test_status_set(kTestStatusInTest);
  irq_global_ctrl(true);
  irq_external_ctrl(true);

  // Initialize the UART to enable logging for non-DV simulation platforms.
  if (kDeviceType != kDeviceSimDV) {
    init_uart(TOP_MATCHA_UART0_BASE_ADDR, &uart);
  }

  LOG_INFO("Performing DMA M2M Test!");
  uint32_t config;

  mmio_region_t reader_start_addr = mmio_region_from_addr(READER_START_ADDR);
  mmio_region_t writer_start_addr = mmio_region_from_addr(WRITER_START_ADDR);

  CHECK_DIF_OK(
      dif_dma_init(mmio_region_from_addr(TOP_MATCHA_DMA0_BASE_ADDR), &dma));

  // Check if the IP is configured for TLUL on all three frontends.
  CHECK_DIF_OK(dif_dma_read_config(&dma, &config));
  CHECK(config == 0x555,
        "Bus configured incorrectly. Expected: 0x555 | Actual: %h", config);

  // Configure the DMA and enable interrupts
  CHECK_DIF_OK(dif_dma_configure_reader(&dma, READER_START_ADDR, LINE_WIDTH,
                                        LINE_COUNT, LINE_STRIDE));
  CHECK_DIF_OK(dif_dma_configure_writer(&dma, WRITER_START_ADDR, LINE_WIDTH,
                                        LINE_COUNT, LINE_STRIDE));

  CHECK_DIF_OK(
      dif_dma_irq_set_enabled(&dma, kDifDmaIrqWriterDone, kDifToggleEnabled));
  CHECK_DIF_OK(
      dif_dma_irq_set_enabled(&dma, kDifDmaIrqReaderDone, kDifToggleEnabled));

  // Only configure the writer IRQ from the PLIC
  CHECK_DIF_OK(dif_rv_plic_init(
      mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR), &plic_sec));
  CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(
      &plic_sec, kTopMatchaPlicIrqIdDma0WriterDone, kTopMatchaPlicTargetIbex0,
      kDifToggleEnabled));
  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(
      &plic_sec, kTopMatchaPlicIrqIdDma0WriterDone, IRQ_PRIO));

  // Populate data in secure core SRAM
  for (int i = 0; i < LINE_COUNT; i++) {
    mmio_region_write32(reader_start_addr, (i * WORD_OFFSET), data[i]);
    mmio_region_write32(writer_start_addr, (i * WORD_OFFSET), 0);
  }

  LOG_INFO("Begin DMA transfer and sleep.");
  CHECK_DIF_OK(dif_dma_begin(&dma));

  asm volatile("wfi");
}
