/*
 * 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/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"
#include "sw/device/lib/virtual_memory.h"

OTTF_DEFINE_TEST_CONFIG();

#define CAUSE_USER_ECALL (0x8)
uint32_t supervisor_l1pt[PAGE_SIZE / sizeof(uint32_t)]
    __attribute__((aligned(PAGE_SIZE)));
uint32_t supervisor_l2pt[PAGE_SIZE / sizeof(uint32_t)]
    __attribute__((aligned(PAGE_SIZE)));
uint32_t user_l2pt[PAGE_SIZE / sizeof(uint32_t)]
    __attribute__((aligned(PAGE_SIZE)));

extern uint32_t __VIRTUAL_ROM;
extern uint32_t __virtual_start;
extern uint32_t __virtual_end;
extern uint32_t __SUPER_VIRTUAL_ROM;
extern uint32_t __super_virtual_start;
extern uint32_t __super_virtual_end;

static dif_uart_t smc_uart;

void ottf_store_page_fault_handler(void) { test_status_set(kTestStatusPassed); }

__attribute__((section(".virtual"))) static void umode_fn(void) {
  asm volatile(
      ".option push \n"
      ".option norvc \n"
      "li a1,0xff801000 \n"
      "sw zero,0(a1) \n"
      "li a4,1 \n"
      "fence iorw,ow \n"
      "amoadd.w a5,a4,(a1) \n"
      "li a1,0 \n"
      "amoadd.w a5,a4,(a1) \n"
      "fence iorw,ow \n"
      ".option pop \n");
}

static __attribute__((section(".super_virtual"))) void smode_fn(void) {
  user_trampoline((uint32_t)umode_fn);
}

static __attribute__((section(".super_virtual")))
__attribute__((naked, aligned(256))) void
stvec(void) {
  asm volatile(
      ".option push \n"
      ".option norvc \n"
      "ecall \n"
      ".option pop \n");
}

void _ottf_main(void) {
  test_status_set(kTestStatusInTest);

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

  // Map our code space and UART peripheral.
  // Both are mapped such that the virtual addresses
  // and physical addresses are the same, but this still
  // causes address translation to happen.
  machine_map_megapage((void *)TOP_MATCHA_RAM_SMC_BASE_ADDR,
                       (void *)TOP_MATCHA_RAM_SMC_BASE_ADDR,
                       (uint32_t *)supervisor_l1pt);
  machine_map_megapage((void *)TOP_MATCHA_SMC_UART_BASE_ADDR,
                       (void *)TOP_MATCHA_SMC_UART_BASE_ADDR,
                       (uint32_t *)supervisor_l1pt);

  // Set up 2-level page tables, one set for user-mode and one set for
  // supervisor-mode.
  machine_map_region((uint32_t)&__VIRTUAL_ROM, (uint32_t)&__virtual_start,
                     (uint32_t)&__virtual_end, supervisor_l1pt, user_l2pt,
                     true);
  machine_map_region(
      (uint32_t)&__SUPER_VIRTUAL_ROM, (uint32_t)&__super_virtual_start,
      (uint32_t)&__super_virtual_end, supervisor_l1pt, supervisor_l2pt, false);

  // Calculate the value of the SATP register.
  // We enable SV32 virtual memory, and store the page
  // containing our page tables.
  uint32_t satp = (uint32_t)(0x1llu << 31) | ((uint32_t)supervisor_l1pt >> 12);

  // Delegate U-mode ecalls to S-mode.
  uint32_t medeleg = (1 << CAUSE_USER_ECALL);

  // Execute smode_fn in supervisor mode, after enabling virtual memory.
  supervisor_trampoline((uint32_t)smode_fn, (uint32_t)satp, (uint32_t)medeleg,
                        (uint32_t)stvec, 0 /* mideleg */);

  __builtin_unreachable();
}
