// Copyright 2024 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 "cheriot/riscv_cheriot_zicsr_instructions.h"

#include <any>
#include <cstdint>

#include "absl/log/log.h"
#include "absl/strings/str_cat.h"
#include "cheriot/cheriot_register.h"
#include "cheriot/cheriot_state.h"
#include "cheriot/riscv_cheriot_csr_enum.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/generic/register.h"
#include "mpact/sim/generic/type_helpers.h"
#include "riscv//riscv_csr.h"
#include "riscv//riscv_state.h"

namespace mpact {
namespace sim {
namespace cheriot {

using ::mpact::sim::generic::operator*;  // NOLINT: is used below (clang error).
using ::mpact::sim::riscv::PrivilegeMode;
using PB = ::mpact::sim::cheriot::CheriotRegister::PermissionBits;
using RV_EC = ::mpact::sim::riscv::ExceptionCode;
using CH_EC = ::mpact::sim::cheriot::ExceptionCode;
using CapReg = ::mpact::sim::cheriot::CheriotRegister;
using ::mpact::sim::generic::Instruction;
using ::mpact::sim::generic::RegisterBase;

// Helper to get capability destination registers.
static inline CapReg *GetCapDest(const Instruction *instruction, int i) {
  return static_cast<CapReg *>(
      std::any_cast<RegisterBase *>(instruction->Destination(i)->GetObject()));
}

// Writing an integer result requires invalidating the capability and setting
// it to null.
template <typename Result>
static inline void WriteCapIntResult(const Instruction *instruction, int i,
                                     Result value) {
  auto *cap_reg = GetCapDest(instruction, i);
  cap_reg->data_buffer()->Set<Result>(0, value);
  cap_reg->Invalidate();
  cap_reg->set_is_null();
}

template <typename T>
inline T ReadCsr(RiscVCsrInterface *) {}

template <>
inline uint32_t ReadCsr<uint32_t>(RiscVCsrInterface *csr) {
  return csr->AsUint32();
}
template <>
inline uint64_t ReadCsr<uint64_t>(RiscVCsrInterface *csr) {
  return csr->AsUint64();
}

// Helper function to check that the CSR permission is valid. If not, throw
// an illegal instruction exception.
bool CheckCsrPermission(int csr_index, Instruction *instruction,
                        bool is_write) {
  auto required_mode = (csr_index >> 8) & 0x3;
  auto *state = static_cast<CheriotState *>(instruction->state());
  auto current_mode = PrivilegeMode::kMachine;
  // If the register isn't available in CHERIoT, throw an exception.
  if (required_mode == *PrivilegeMode::kSupervisor) {
    state->Trap(/*is_interrupt*/ false, 0, *RV_EC::kIllegalInstruction,
                instruction->address(), instruction);
    return false;
  }
  // If the privilege mode is too low, throw an exception.
  if (*current_mode < required_mode) {
    state->Trap(/*is_interrupt*/ false, 0, *RV_EC::kIllegalInstruction,
                instruction->address(), instruction);
    return false;
  }
  // Accesses to fflags, frm, and fcsr are all ok.
  if ((csr_index >= *RiscVCheriotCsrEnum::kFFlags) &&
      (csr_index <= *RiscVCheriotCsrEnum::kFCsr)) {
    return true;
  }
  // Reads to MCycle, MInstret, MHpmcounterN are all ok.
  if (!is_write && (((csr_index >= *RiscVCheriotCsrEnum::kMCycle) &&
                     (csr_index <= *RiscVCheriotCsrEnum::kMHpmcounter31)) ||
                    ((csr_index >= *RiscVCheriotCsrEnum::kMCycleH) &&
                     (csr_index <= *RiscVCheriotCsrEnum::kMHpmcounter31H)))) {
    return true;
  }
  // Check pcc capability.
  if ((required_mode != *PrivilegeMode::kUser) &&
      (!state->pcc()->HasPermission(PB::kPermitAccessSystemRegisters))) {
    state->HandleCheriRegException(
        instruction, instruction->address(),
        CH_EC::kCapExPermitAccessSystemRegistersViolation, state->pcc());
    return false;
  }
  return true;
}

// Templated helper functions.

// Read the CSR, write a new value back.
template <typename T>
static inline void RVZiCsrrw(Instruction *instruction) {
  // Get a handle to the state instance.
  auto state = static_cast<CheriotState *>(instruction->state());
  // Get the csr index.
  int csr_index = instruction->Source(1)->AsInt32(0);
  if (!CheckCsrPermission(csr_index, instruction, /*is_write=*/true)) return;
  // Read the csr.
  auto result = state->csr_set()->GetCsr(csr_index);
  if (!result.ok()) {
    // Signal error if it failed.
    LOG(ERROR) << absl::StrCat("Instruction at address 0x",
                               absl::Hex(instruction->address()),
                               " failed to read CSR 0x", absl::Hex(csr_index),
                               ": ", result.status().message());
    return;
  }
  // Get the new value.
  T new_value = generic::GetInstructionSource<T>(instruction, 0);
  auto *csr = result.value();
  // Update the register.
  auto csr_val = ReadCsr<T>(csr);
  WriteCapIntResult(instruction, 0, csr_val);
  // Write the new value to the csr.
  csr->Write(new_value);
}

// Read the CSR, set the bits specified by the new value and write back.
template <typename T>
static inline void RVZiCsrrs(Instruction *instruction) {
  // Get a handle to the state instance.
  auto state = static_cast<CheriotState *>(instruction->state());
  // Get the csr index.
  int csr_index = instruction->Source(1)->AsInt32(0);
  if (!CheckCsrPermission(csr_index, instruction, /*is_write=*/true)) return;
  // Read the csr.
  auto result = state->csr_set()->GetCsr(csr_index);
  if (!result.ok()) {
    // Signal error if it failed.
    LOG(ERROR) << absl::StrCat("Instruction at address 0x",
                               absl::Hex(instruction->address()),
                               " failed to read CSR 0x", absl::Hex(csr_index),
                               ": ", result.status().message());
    return;
  }
  // Get the new value.
  T new_value = generic::GetInstructionSource<T>(instruction, 0);
  auto *csr = result.value();
  // Update the register.
  auto csr_val = ReadCsr<T>(csr);
  WriteCapIntResult(instruction, 0, csr_val);
  // Write the new value to the csr.
  csr->SetBits(new_value);
}

// Read the CSR, clear the bits specified by the new value and write back.
template <typename T>
static inline void RVZiCsrrc(Instruction *instruction) {
  // Get a handle to the state instance.
  auto state = static_cast<CheriotState *>(instruction->state());
  // Get the csr index.
  int csr_index = instruction->Source(1)->AsInt32(0);
  if (!CheckCsrPermission(csr_index, instruction, /*is_write=*/true)) return;
  // Read the csr.
  auto result = state->csr_set()->GetCsr(csr_index);
  if (!result.ok()) {
    // Signal error if it failed.
    LOG(ERROR) << absl::StrCat("Instruction at address 0x",
                               absl::Hex(instruction->address()),
                               " failed to read CSR 0x", absl::Hex(csr_index),
                               ": ", result.status().message());
    return;
  }
  // Get the new value.
  T new_value = generic::GetInstructionSource<T>(instruction, 0);
  auto *csr = result.value();
  // Write the current value of the CSR to the destination register.
  auto csr_val = ReadCsr<T>(csr);
  WriteCapIntResult(instruction, 0, csr_val);
  // Write the new value to the csr.
  csr->ClearBits(new_value);
}

// Do not read the CSR, just write the new value back.
template <typename T>
static inline void RVZiCsrrwNr(Instruction *instruction) {
  // Get a handle to the state instance.
  auto state = static_cast<CheriotState *>(instruction->state());
  // Get the csr index.
  int csr_index = instruction->Source(1)->AsInt32(0);
  if (!CheckCsrPermission(csr_index, instruction, /*is_write=*/true)) return;
  // Read the csr.
  auto result = state->csr_set()->GetCsr(csr_index);
  if (!result.ok()) {
    LOG(ERROR) << absl::StrCat("Instruction at address 0x",
                               absl::Hex(instruction->address()),
                               " failed to write CSR 0x", absl::Hex(csr_index),
                               ": ", result.status().message());
    return;
  }
  auto *csr = result.value();
  // Write the new value to the csr.
  T new_value = generic::GetInstructionSource<T>(instruction, 0);
  csr->Write(new_value);
}

// Do not write a value back to the CSR, just read it.
template <typename T>
static inline void RVZiCsrrNw(Instruction *instruction) {
  // Get a handle to the state instance.
  auto state = static_cast<CheriotState *>(instruction->state());
  // Get the csr index.
  int csr_index = instruction->Source(0)->AsInt32(0);
  if (!CheckCsrPermission(csr_index, instruction, /*is_write=*/false)) return;
  // Read the csr.
  auto result = state->csr_set()->GetCsr(csr_index);
  if (!result.ok()) {
    LOG(ERROR) << absl::StrCat("Instruction at address 0x",
                               absl::Hex(instruction->address()),
                               " failed to read CSR 0x", absl::Hex(csr_index),
                               ": ", result.status().message());
    return;
  }
  // Get the CSR object.
  auto *csr = result.value();
  auto csr_val = ReadCsr<T>(csr);
  WriteCapIntResult(instruction, 0, csr_val);
}

using RegisterType = CheriotRegister;
using UintReg = RegisterType::ValueType;

// Read the CSR, write a new value back.
void RiscVZiCsrrw(Instruction *instruction) { RVZiCsrrw<UintReg>(instruction); }

// Read the CSR, set the bits specified by the new value and write back.
void RiscVZiCsrrs(Instruction *instruction) { RVZiCsrrs<UintReg>(instruction); }

// Read the CSR, clear the bits specified by the new value and write back.
void RiscVZiCsrrc(Instruction *instruction) { RVZiCsrrc<UintReg>(instruction); }

// Do not read the CSR, just write the new value back.
void RiscVZiCsrrwNr(Instruction *instruction) {
  RVZiCsrrwNr<UintReg>(instruction);
}

// Do not write a value back to the CSR, just read it.
void RiscVZiCsrrNw(Instruction *instruction) {
  RVZiCsrrNw<UintReg>(instruction);
}

}  // namespace cheriot
}  // namespace sim
}  // namespace mpact
