/*
 * 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.
 */


// Verify byte read/write on SMC and ML memory region.

#include "hw/top_matcha/sw/autogen/top_matcha.h"
#include "sw/device/lib/arch/device.h"
#include "sw/device/lib/dif/dif_smc_ctrl.h"
#include "sw/device/lib/dif/dif_uart.h"
#include "sw/device/lib/runtime/hart.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/test_util.h"

OTTF_DEFINE_TEST_CONFIG();

static dif_smc_ctrl_t smc_ctrl;
static dif_uart_t uart;

void _ottf_main(void) {
  CHECK_DIF_OK(dif_smc_ctrl_init(
      mmio_region_from_addr(TOP_MATCHA_SMC_CTRL_BASE_ADDR), &smc_ctrl));
  CHECK_DIF_OK(dif_smc_ctrl_set_en(&smc_ctrl));

  // Initialize the UART to enable logging for non-DV simulation platforms.
  if (kDeviceType != kDeviceSimDV) {
    init_uart(TOP_MATCHA_UART0_BASE_ADDR, &uart);
  }
  LOG_INFO("[SC] Memory test starts from SC!");

  mmio_region_t base_addr = mmio_region_from_addr(TOP_MATCHA_RAM_SMC_BASE_ADDR);
  mmio_region_t ml_dmem_base =
      mmio_region_from_addr(TOP_MATCHA_RAM_ML_DMEM_BASE_ADDR);

  const unsigned char golden_data[20] = {
      0xff, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xe1, 0xe1,
      0xe1, 0xe5, 0xc1, 0xde, 0xe1, 0xe1, 0xb3, 0xb3, 0xb1, 0xa9};
  uint32_t golden_data_size = 20;

  unsigned char mem_val;
  unsigned char golden_val;

  LOG_INFO("[SC] Write the test data array.");
  for (uint32_t offset = 0; offset < golden_data_size; offset++) {
    mmio_region_write8(base_addr, offset, golden_data[offset]);
    mmio_region_write8(ml_dmem_base, offset, golden_data[offset]);
  }

  // Check SMC RAM byte access
  // TODO(b/273572595): Extend to test half-word/word access.
  LOG_INFO("[SC] Read the test data array.");
  for (uint32_t offset = 0; offset < golden_data_size; offset++) {
    mem_val = mmio_region_read8(base_addr, offset);
    golden_val = golden_data[offset];
    CHECK(mem_val == golden_val,
          "Mismatch data at offset 0x%h - Expected: 0x%h | Actual: 0x%h",
          offset, golden_val, mem_val);
  }

  // Check ML DMEM byte access
  for (uint32_t offset = 0; offset < golden_data_size; offset++) {
    mem_val = mmio_region_read8(ml_dmem_base, offset);
    golden_val = golden_data[offset];
    CHECK(mem_val == golden_val,
          "Mismatch data at offset 0x%h - Expected: 0x%h | Actual: 0x%h",
          offset, golden_val, mem_val);
  }

  // Note: the SMC must end the simulation through testing or otherwise, as the
  // secure core indefinitely sleeps.
  asm volatile("wfi");
}
