// 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/cheriot_state.h"

#include <algorithm>
#include <cstdint>
#include <limits>
#include <new>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "absl/flags/flag.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/strings/str_cat.h"
#include "cheriot/cheriot_register.h"
#include "cheriot/riscv_cheriot_csr_enum.h"
#include "mpact/sim/generic/arch_state.h"
#include "mpact/sim/generic/type_helpers.h"
#include "mpact/sim/util/memory/memory_interface.h"
#include "mpact/sim/util/memory/tagged_flat_demand_memory.h"
#include "mpact/sim/util/memory/tagged_memory_interface.h"
#include "riscv//riscv_counter_csr.h"
#include "riscv//riscv_csr.h"
#include "riscv//riscv_misa.h"
#include "riscv//riscv_pmp.h"
#include "riscv//riscv_state.h"

ABSL_FLAG(uint64_t, revocation_ram_base, 0x8000'0000,
          "Ram base for revocation.");
ABSL_FLAG(uint64_t, revocation_mem_base, 0x8300'0000,
          "Revocation memory base.");

namespace mpact {
namespace sim {
namespace cheriot {

using EC = ::mpact::sim::riscv::ExceptionCode;
using ::mpact::sim::generic::operator*;  // NOLINT: used below (clang error).
using ::mpact::sim::riscv::IsaExtension;
using ::mpact::sim::riscv::RiscVCounterCsr;
using ::mpact::sim::riscv::RiscVCounterCsrHigh;
using ::mpact::sim::riscv::RiscVCsrEnum;
using ::mpact::sim::riscv::RiscVCsrInterface;
using ::mpact::sim::riscv::RiscVPmp;
using ::mpact::sim::riscv::RiscVSimpleCsr;
using ::mpact::sim::riscv::RiscVXlen;

// These helper templates are used to store information about the CSR registers
// used in CHERIoT RiscV (32 bits).
template <typename T>
struct CsrInfo {};

template <>
struct CsrInfo<uint32_t> {
  using T = uint32_t;
  static constexpr T kMhartidRMask = std::numeric_limits<T>::max();
  static constexpr T kMhartidWMask = 0;
  static constexpr T kMstatusInitialValue = 0x1800;
  static constexpr T kMisaInitialValue =
      (*RiscVXlen::RV32 << 30) | *IsaExtension::kIntegerMulDiv |
      *IsaExtension::kRVIBaseIsa | *IsaExtension::kGExtension |
      *IsaExtension::kSinglePrecisionFp | *IsaExtension::kDoublePrecisionFp |
      *IsaExtension::kCompressed | *IsaExtension::kAtomic |
      *IsaExtension::kSupervisorMode;
  static constexpr T kMisaRMask = 0xc3ff'ffff;
  static constexpr T kMisaWMask = 0x0;
};

// Three templated helper functions used to create individual CSRs.

// This creates the CSR and assigns it to a pointer in the state object. Type
// can be inferred from the state object pointer.
template <typename T, typename... Ps>
T *CreateCsr(CheriotState *state, T *&ptr,
             std::vector<RiscVCsrInterface *> &csr_vec, Ps... pargs) {
  auto *csr = new T(pargs...);
  auto result = state->csr_set()->AddCsr(csr);
  if (!result.ok()) {
    LOG(ERROR) << absl::StrCat("Failed to add csr '", csr->name(),
                               "': ", result.message());
    delete csr;
    return nullptr;
  }
  csr_vec.push_back(csr);
  ptr = csr;
  return csr;
}

// This creates the CSR and assigns it to a pointer in the state object, however
// that pointer is of abstract type, so the CSR type cannot be inferred, but
// has to be specified in the call.
template <typename T, typename... Ps>
T *CreateCsr(CheriotState *state, RiscVCsrInterface *&ptr,
             std::vector<RiscVCsrInterface *> &csr_vec, Ps... pargs) {
  auto *csr = new T(pargs...);
  auto result = state->csr_set()->AddCsr(csr);
  if (!result.ok()) {
    LOG(ERROR) << absl::StrCat("Failed to add csr '", csr->name(),
                               "': ", result.message());
    delete csr;
    return nullptr;
  }
  csr_vec.push_back(csr);
  ptr = csr;
  return csr;
}

// This creates the CSR, but does not assign it to a pointer in the state
// object. That means the type cannot be inferred, but has to be specified
// in the call.
template <typename T, typename... Ps>
T *CreateCsr(CheriotState *state, std::vector<RiscVCsrInterface *> &csr_vec,
             Ps... pargs) {
  auto *csr = new T(pargs...);
  auto result = state->csr_set()->AddCsr(csr);
  if (!result.ok()) {
    LOG(ERROR) << absl::StrCat("Failed to add csr '", csr->name(),
                               "': ", result.message());
    delete csr;
    return nullptr;
  }
  csr_vec.push_back(csr);
  return csr;
}

// Templated helper function that is used to create the set of CSRs needed
// for simulation.
template <typename T>
void CreateCsrs(CheriotState *state,
                std::vector<RiscVCsrInterface *> &csr_vec) {
  absl::Status result;
  // Create CSRs.
  // misa
  auto *misa = CreateCsr(state, state->misa_, csr_vec,
                         CsrInfo<T>::kMisaInitialValue, state);
  CHECK_NE(misa, nullptr);
  // mtvec is replaced by mtcc

  // mcause
  CHECK_NE(
      CreateCsr<RiscVSimpleCsr<T>>(state, state->mcause_, csr_vec, "mcause",
                                   RiscVCsrEnum::kMCause, 0, state),
      nullptr);

  // Mip and Mie are always 32 bit.
  // mip
  auto *mip = CreateCsr(state, state->mip_, csr_vec, 0, state);
  CHECK_NE(mip, nullptr);

  // mie
  auto *mie = CreateCsr(state, state->mie_, csr_vec, 0, state);
  CHECK_NE(mie, nullptr);

  // mhartid
  CHECK_NE(CreateCsr<RiscVSimpleCsr<T>>(
               state, csr_vec, "mhartid", *RiscVCheriotCsrEnum::kMHartId, 0,
               CsrInfo<T>::kMhartidRMask, CsrInfo<T>::kMhartidWMask, state),
           nullptr);

  // mepc is replaced by mepcc

  // mscratch
  CHECK_NE(CreateCsr<RiscVSimpleCsr<T>>(state, csr_vec, "mscratch",
                                        *RiscVCsrEnum::kMScratch, 0, state),
           nullptr);

  // medeleg - machine mode exception delegation register. Not used.

  // mideleg - machine mode interrupt delegation register. Not used.

  // mstatus
  auto *mstatus =
      CreateCsr(state, state->mstatus_, csr_vec,
                CsrInfo<uint32_t>::kMstatusInitialValue, state, misa);
  CHECK_NE(mstatus, nullptr);
  // mtval
  auto *mtval = CreateCsr<RiscVSimpleCsr<T>>(
      state, state->mtval_, csr_vec, "mtval", *RiscVCsrEnum::kMTval, 0, state);
  CHECK_NE(mtval, nullptr);

  // minstret/minstreth
  auto *minstret = CreateCsr<RiscVCounterCsr<T, CheriotState>>(
      state, csr_vec, "minstret", RiscVCsrEnum ::kMInstret, state);
  CHECK_NE(minstret, nullptr);
  if (sizeof(T) == sizeof(uint32_t)) {
    CHECK_NE(CreateCsr<RiscVCounterCsrHigh<CheriotState>>(
                 state, csr_vec, "minstreth", RiscVCsrEnum::kMInstretH, state,
                 reinterpret_cast<RiscVCounterCsr<uint32_t, CheriotState> *>(
                     minstret)),
             nullptr);
  }
  // mcycle/mcycleh
  auto *mcycle = CreateCsr<RiscVCounterCsr<T, CheriotState>>(
      state, csr_vec, "mcycle", RiscVCsrEnum::kMCycle, state);
  CHECK_NE(mcycle, nullptr);
  if (sizeof(T) == sizeof(uint32_t)) {
    CHECK_NE(CreateCsr<RiscVCounterCsrHigh<CheriotState>>(
                 state, csr_vec, "mcycleh", RiscVCsrEnum::kMCycleH, state,
                 reinterpret_cast<RiscVCounterCsr<uint32_t, CheriotState> *>(
                     mcycle)),
             nullptr);
  }

  // Stack high water mark CSRs. Mshwm gets updated automatically during
  // execution. mshwm
  auto *mshwm = CreateCsr<RiscVSimpleCsr<T>>(
      state, state->mshwm_, csr_vec, "mshwm", *RiscVCheriotCsrEnum::kMshwm,
      /*initial_value=*/0,
      /*read_mask=*/0xffff'fff0, /*write_mask=*/0xffff'fff0, state);
  CHECK_NE(mshwm, nullptr);
  // mshwmb
  auto *mshwmb = CreateCsr<RiscVSimpleCsr<T>>(
      state, state->mshwmb_, csr_vec, "mshwmb", *RiscVCheriotCsrEnum::kMshwmb,
      /*initial_value=*/0,
      /*read_mask=*/0xffff'fff0, /*write_mask=*/0xffff'fff0, state);
  CHECK_NE(mshwmb, nullptr);

  // mccsr.
  auto *mccsr = CreateCsr<RiscVSimpleCsr<T>>(
      state, csr_vec, "mccsr", *RiscVCheriotCsrEnum::kMCcsr,
      /*initial_value=*/0x3,
      /*read_mask=*/0x3, /*write_mask=*/0x2, state);
  CHECK_NE(mccsr, nullptr);

  // Supervisor level CSRs
  // None in CHERIoT.

  // User level CSRs
  // None in CHERIoT.

  // PMP CSRs
  state->pmp_ = new RiscVPmp(state);
  state->pmp_->CreatePmpCsrs<T, RiscVCheriotCsrEnum>(state->csr_set());

  // Simulator CSRs

  // Access current privilege mode. Omitted.
}

// This value is in the RV32ISA manual to support MMU, although in "BARE" mode
// only the bottom 32-bit is valid.
constexpr uint64_t kRiscv32MaxMemorySize = 0x3f'ffff'ffffULL;

CheriotState::CheriotState(std::string_view id,
                           util::TaggedMemoryInterface *memory,
                           util::AtomicMemoryOpInterface *atomic_memory)
    : generic::ArchState(id),
      tagged_memory_(memory),
      atomic_tagged_memory_(atomic_memory),
      counter_interrupts_taken_("interrupts_taken", 0),
      counter_interrupt_returns_("interrupt_returns", 0) {
  for (auto &[name, index] : std::vector<std::pair<std::string, unsigned>>{
           {"c0", 0b0'00000},   {"c1", 0b0'00001},   {"c2", 0b0'00010},
           {"c3", 0b0'00011},   {"c4", 0b0'00100},   {"c5", 0b0'00101},
           {"c6", 0b0'00110},   {"c7", 0b0'00111},   {"c8", 0b0'01000},
           {"c9", 0b0'01001},   {"c10", 0b0'01010},  {"c11", 0b0'01011},
           {"c12", 0b0'01100},  {"c13", 0b0'01101},  {"c14", 0b0'01110},
           {"c15", 0b0'01111},  {"c16", 0b0'10000},  {"c17", 0b0'10001},
           {"c18", 0b0'10010},  {"c19", 0b0'10011},  {"c20", 0b0'10100},
           {"c21", 0b0'10101},  {"c22", 0b0'10110},  {"c23", 0b0'10111},
           {"c24", 0b0'11000},  {"c25", 0b0'11001},  {"c26", 0b0'11010},
           {"c27", 0b0'11011},  {"c28", 0b0'11100},  {"c29", 0b0'11101},
           {"c30", 0b0'11110},  {"c31", 0b0'11111},  {"pcc", 0b1'00000},
           {"mtcc", 0b1'11100}, {"mtdc", 0b1'11101}, {"mscratchc", 0b1'11110},
           {"mepcc", 0b1'11111}}) {
    cap_index_map_.emplace(name, index);
  }
  CHECK_OK(AddCounter(&counter_interrupts_taken_));
  CHECK_OK(AddCounter(&counter_interrupt_returns_));
  // Create root capabilities and the special capability CSRs.
  executable_root_ = new CheriotRegister(this, "executable_root");
  executable_root_->ResetExecuteRoot();
  sealing_root_ = new CheriotRegister(this, "sealing_root");
  sealing_root_->ResetSealingRoot();
  memory_root_ = new CheriotRegister(this, "memory_root");
  memory_root_->ResetMemoryRoot();
  mtcc_ = AddRegister<CheriotRegister>("mtcc");
  mtcc_->ResetExecuteRoot();
  mepcc_ = AddRegister<CheriotRegister>("mepcc");
  mepcc_->ResetExecuteRoot();
  mtdc_ = AddRegister<CheriotRegister>("mtdc");
  mtdc_->ResetMemoryRoot();
  mscratchc_ = AddRegister<CheriotRegister>("mscratchc");
  mscratchc_->ResetSealingRoot();
  pcc_ = AddRegister<CheriotRegister>("pcc");
  auto status = AddRegisterAlias<CheriotRegister>("pcc", "pc");
  if (!status.ok()) {
    LOG(ERROR) << "Error creating pc alias of 'pcc': " << status.message();
    return;
  }
  pcc_->ResetExecuteRoot();
  temp_reg_ = new CheriotRegister(this, "temp_reg");
  // Add the general capability registers.
  for (int i = 0; i < 32; i++) {
    AddRegister<CheriotRegister>(absl::StrCat("c", i));
  }
  status = AddRegisterAlias<CheriotRegister>("c3", "cgp");
  if (!status.ok()) {
    LOG(ERROR) << "Error creating cgp alias of 'c3': " << status.message();
    return;
  }
  auto [cgp_reg, unused] = GetRegister<CheriotRegister>("cgp");
  cgp_ = cgp_reg;
  // Create the other CSRs.
  csr_set_ = new RiscVCsrSet();
  CreateCsrs<uint32_t>(this, csr_vec_);
  pc_src_operand_ = new RiscVCheri32PcSourceOperand(this);
  set_pc_operand(pc_src_operand_);
  // Create the revocation data buffer.
  revocation_db_ = db_factory()->Allocate<uint8_t>(1);
  revocation_ram_base_ = absl::GetFlag(FLAGS_revocation_ram_base);
  revocation_mem_base_ = absl::GetFlag(FLAGS_revocation_mem_base);

  set_max_physical_address(kRiscv32MaxMemorySize);
}

CheriotState::~CheriotState() {
  delete executable_root_;
  delete sealing_root_;
  delete memory_root_;
  delete pc_src_operand_;
  for (auto *csr : csr_vec_) delete csr;
  delete csr_set_;
  delete pmp_;
  delete temp_reg_;
  revocation_db_->DecRef();
}

void CheriotState::Reset() {
  for (auto &[unused, reg_ptr] : *registers()) {
    reg_ptr->data_buffer()->Set<uint32_t>(0, 0);
  }
  // Reset CSRs.
  pcc_->ResetExecuteRoot();
  mtcc_->ResetExecuteRoot();
  mepcc_->ResetExecuteRoot();
  mtdc_->ResetMemoryRoot();
  mscratchc_->ResetSealingRoot();
  mstatus_->Set(CsrInfo<uint32_t>::kMstatusInitialValue);
  mtval_->Set(0UL);
  mshwm_->Set(0UL);
  mshwmb_->Set(0UL);
  mip_->Set(0UL);
  mie_->Set(0UL);
  csr_set_->GetCsr("minstret").value()->Set(0UL);
  csr_set_->GetCsr("minstreth").value()->Set(0UL);
  csr_set_->GetCsr("mcause").value()->Set(0UL);
  csr_set_->GetCsr("misa").value()->Set(CsrInfo<uint32_t>::kMisaInitialValue);
}

void CheriotState::HandleCheriRegException(const Instruction *instruction,
                                           uint64_t epc, ExceptionCode code,
                                           const CheriotRegister *reg) {
  // Map the CHERIoT exception to a RiscV trap.
  unsigned mcause = kCheriExceptionCode;
  uint32_t mtval = *code & 0b1'1111;
  auto const &name = reg->name();
  auto iter = cap_index_map_.find(name);
  uint32_t cap_index = 0x1f;  // Set to a default value.
  if (iter != cap_index_map_.end()) {
    cap_index = iter->second;
  }
  mtval |= cap_index << 5;
  Trap(/*is_interrupt*/ false, mtval, mcause, epc, instruction);
}

void CheriotState::set_max_physical_address(uint64_t max_physical_address) {
  max_physical_address_ = std::min(max_physical_address, kRiscv32MaxMemorySize);
}

void CheriotState::set_min_physical_address(uint64_t min_physical_address) {
  min_physical_address_ = std::min(min_physical_address, max_physical_address_);
}

void CheriotState::LoadCapability(const Instruction *instruction,
                                  uint32_t address, DataBuffer *db,
                                  DataBuffer *tags, Instruction *child,
                                  CapabilityLoadContext32 *context) {
  // Check for alignment.
  uint64_t mask = db->size<uint8_t>() - 1;
  if ((address & mask) != 0) {
    Trap(/*is_interrupt*/ false, address, *EC::kLoadAddressMisaligned,
         instruction == nullptr ? 0 : instruction->address(), instruction);
    return;
  }
  // Check for physical address violation.
  if (address < min_physical_address_ || address > max_physical_address_) {
    Trap(/*is_interrupt*/ false, address, *EC::kLoadAccessFault,
         instruction == nullptr ? 0 : instruction->address(), instruction);
    return;
  }
  // Forward the load.
  tagged_memory_->Load(address, db, tags, child, context);
  if (!tracing_active_) return;
  load_address_ = address;
  load_db_ = db;
  load_db_->IncRef();
  load_tags_ = tags;
  load_tags_->IncRef();
}

void CheriotState::StoreCapability(const Instruction *instruction,
                                   uint32_t address, DataBuffer *db,
                                   DataBuffer *tags) {
  // Check for alignment.
  uint64_t mask = db->size<uint8_t>() - 1;
  if ((address & mask) != 0) {
    Trap(/*is_interrupt*/ false, address, *EC::kStoreAddressMisaligned,
         instruction == nullptr ? 0 : instruction->address(), instruction);
    return;
  }
  // Check for physical address violation.
  if (address < min_physical_address_ || address > max_physical_address_) {
    Trap(/*is_interrupt*/ false, address, *EC::kStoreAccessFault,
         instruction == nullptr ? 0 : instruction->address(), instruction);
    return;
  }
  // Check for stack accesses relative to mshwm/mshwmb.
  if ((address >= mshwmb_->GetUint32()) && (address < mshwm_->GetUint32())) {
    mshwm_->Set(address);
  }
  // Forward the store.
  tagged_memory_->Store(address, db, tags);
  if (!tracing_active_) return;
  store_address_ = address;
  store_db_ = db;
  store_db_->IncRef();
  store_tags_ = tags;
  store_tags_->IncRef();
}

void CheriotState::LoadMemory(const Instruction *inst, uint64_t address,
                              DataBuffer *db, Instruction *child_inst,
                              ReferenceCount *context) {
  // Check for alignment.
  uint64_t mask = db->size<uint8_t>() - 1;
  if ((address & mask) != 0) {
    Trap(/*is_interrupt*/ false, address, *EC::kLoadAddressMisaligned,
         inst == nullptr ? 0 : inst->address(), inst);
    return;
  }
  // Check for physical address violation.
  if (address < min_physical_address_ || address > max_physical_address_) {
    Trap(/*is_interrupt*/ false, address, *EC::kLoadAccessFault,
         inst == nullptr ? 0 : inst->address(), inst);
    return;
  }
  // Forward the load.
  tagged_memory_->Load(address, db, child_inst, context);
  if (!tracing_active_) return;
  load_address_ = address;
  load_db_ = db;
  load_db_->IncRef();
  load_tags_ = nullptr;
}

void CheriotState::LoadMemory(const Instruction *inst, DataBuffer *address_db,
                              DataBuffer *mask_db, int el_size, DataBuffer *db,
                              Instruction *child_inst,
                              ReferenceCount *context) {
  // For now, we don't check for alignment on vector memory accesses.

  // Check for physical address violation.
  for (auto address : address_db->Get<uint64_t>()) {
    if (address < min_physical_address_ || address > max_physical_address_) {
      Trap(/*is_interrupt*/ false, address, *EC::kLoadAccessFault,
           inst == nullptr ? 0 : inst->address(), inst);
      return;
    }
  }
  // Forward the load.
  tagged_memory_->Load(address_db, mask_db, el_size, db, child_inst, context);
}

void CheriotState::StoreMemory(const Instruction *inst, uint64_t address,
                               DataBuffer *db) {
  // Check for alignment.
  uint64_t mask = db->size<uint8_t>() - 1;
  if ((address & mask) != 0) {
    Trap(/*is_interrupt*/ false, address, *EC::kStoreAddressMisaligned,
         inst == nullptr ? 0 : inst->address(), inst);
    return;
  }
  // Check for physical address violation.
  if (address < min_physical_address_ || address > max_physical_address_) {
    Trap(/*is_interrupt*/ false, address, *EC::kStoreAccessFault,
         inst == nullptr ? 0 : inst->address(), inst);
    return;
  }
  // Check for stack accesses relative to mshwm/mshwmb.
  uint32_t address32 = static_cast<uint32_t>(address);
  if ((address32 >= mshwmb_->GetUint32()) &&
      (address32 < mshwm_->GetUint32())) {
    mshwm_->Set(address32);
  }
  // Forward the store.
  tagged_memory_->Store(address, db);
  if (!tracing_active_) return;
  store_address_ = address;
  store_db_ = db;
  store_db_->IncRef();
  store_tags_ = nullptr;
}

void CheriotState::StoreMemory(const Instruction *inst, DataBuffer *address_db,
                               DataBuffer *mask_db, int el_size,
                               DataBuffer *db) {
  // Ignore alignment check for vector memory accesses.

  // Check for physical address violation.
  for (auto address : address_db->Get<uint64_t>()) {
    if (address < min_physical_address_ || address > max_physical_address_) {
      Trap(/*is_interrupt*/ false, address, *EC::kStoreAccessFault,
           inst == nullptr ? 0 : inst->address(), inst);
      return;
    }
  }
  // Check for stack accesses relative to mshwm/mshwmb.
  for (auto address : address_db->Get<uint64_t>()) {
    uint32_t address32 = static_cast<uint32_t>(address);
    if ((address32 >= mshwmb_->GetUint32()) &&
        (address32 < mshwm_->GetUint32())) {
      mshwm_->Set(address32);
    }
  }
  // Forward the store.
  tagged_memory_->Store(address_db, mask_db, el_size, db);
}

void CheriotState::DbgStoreMemory(uint64_t address, DataBuffer *db) {
  tagged_memory_->Store(address, db);
}

void CheriotState::DbgLoadMemory(uint64_t address, DataBuffer *db) {
  tagged_memory_->Load(address, db, nullptr, nullptr);
}

void CheriotState::Fence(const Instruction *inst, int fm, int predecessor,
                         int successor) {
  // TODO: Add fence operation once operations have non-zero latency.
}

void CheriotState::FenceI(const Instruction *inst) {
  // TODO: Add instruction fence operation when needed.
}

void CheriotState::ECall(const Instruction *inst) {
  // If there is a handler, call it.
  if (on_ecall_ != nullptr) {
    auto res = on_ecall_(inst);
    // If the handler returns true, the ecall has been handled, just return.
    if (res) return;
  }

  // Otherwise trap.
  std::string where = (inst != nullptr)
                          ? absl::StrCat(absl::Hex(inst->address()))
                          : "unknown location";

  EC code;
  code = EC::kEnvCallFromMMode;

  uint64_t epc = inst->address();
  Trap(/*is_interrupt*/ false, 0, *code, epc, inst);
}

void CheriotState::EBreak(const Instruction *inst) {
  // Call the handlers.
  for (auto &handler : on_ebreak_) {
    bool res = handler(inst);
    // If a handler returns true, the ebreak has been handled. Just return.
    if (res) return;
  }
  // Otherwise trap.
  // Set the return address to the current instruction.
  auto epc = (inst != nullptr) ? inst->address() : 0;
  Trap(/*is_interrupt=*/false, /*trap_value=*/epc, 3, epc, inst);
}

void CheriotState::WFI(const Instruction *inst) {
  // Call the handler.
  if (on_wfi_ != nullptr) {
    bool res = on_wfi_(inst);
    // If the handler returns true, the wfi has been handled. Just return.
    if (res) return;
  }
  // If no handler is specified, or if no handlers returns true, treat it
  // as a nop.
  std::string where = (inst != nullptr)
                          ? absl::StrCat(absl::Hex(inst->address()))
                          : "unknown location";

  LOG(INFO) << "No handler for wfi: treating as nop: " << where;
}

void CheriotState::Cease(const Instruction *inst) {
  // Call the handler.
  if (on_cease_ != nullptr) {
    const bool res = on_cease_(inst);
    if (res) return;
  }

  // If no handler is specified, then CEASE is treated as an infinite loop.
  // TODO(torerik): set next pc to the right value.

  const std::string where = (inst != nullptr)
                                ? absl::StrCat(absl::Hex(inst->address()))
                                : "unknown location";

  LOG(INFO) << "No handler for cease: treating as an infinite loop: " << where;
}

void CheriotState::Trap(bool is_interrupt, uint64_t trap_value,
                        uint64_t exception_code, uint64_t epc,
                        const Instruction *inst) {
  // LOG(INFO) << "Trap: " << std::hex << is_interrupt << " " << trap_value
  //  << " " << exception_code << " " << epc;  // Call the handler.
  if (on_trap_ != nullptr) {
    bool res = on_trap_(is_interrupt, trap_value, exception_code, epc, inst);
    // If the handler returns true, the trap has been handled. Just return.
    if (res) return;
  }
  // Get trap destination.
  int trap_vector_mode = mtcc_->address() & 0x3ULL;
  uint64_t trap_target = mtcc_->address() & ~0x3ULL;
  if (trap_vector_mode == 1) {
    trap_target += 4 * exception_code;
  }

  // Set mepc by copying pcc to mepc and setting the address to epc.
  mepcc_->CopyFrom(*pcc());
  mepcc_->set_address(epc);
  // Set xcause.
  mcause_->Set(exception_code);
  if (is_interrupt) {
    mcause_->SetBits(static_cast<uint32_t>(0x8000'0000));
  }
  // Set mstatus bits accordingly.

  // Set the privilege mode to return to after the interrupt.
  mstatus_->set_mpp(*PrivilegeMode::kMachine);
  // Save the current interrupt enable to mpie.
  mstatus_->set_mpie(mstatus_->mie());
  // Disable further interrupts.
  mstatus_->set_mie(0);

  // Advance data buffer delay line until empty. Flush pending writes to
  // register and possibly pc.
  while (!data_buffer_delay_line()->IsEmpty()) {
    data_buffer_delay_line()->Advance();
  }

  // Set mtval.
  mtval_->Write(trap_value);

  // Update the PC from the mtvec_ capability. Update the address in case of
  // vectored mode.
  pcc()->CopyFrom(*mtcc_);
  pcc()->set_address(trap_target);
  set_branch(true);
  // TODO(torerik): set next pc
  mstatus_->Submit();
  // Set up interrupt info before incrementing the interrupt counter. That way
  // any code that is triggered by the interrupt counter will see the updated
  // interrupt info.
  InterruptInfo info;
  info.is_interrupt = is_interrupt;
  info.cause = mcause_->GetUint32();
  info.tval = mtval_->GetUint32();
  info.epc = epc;
  interrupt_info_list_.push_back(info);

  counter_interrupts_taken_.Increment(1);
}

// Called upon returning from an interrupt or exception.
void CheriotState::SignalReturnFromInterrupt() {
  // First increment the interrupt return counter. Then pop the interrupt info.
  // This way any code that is triggered by the interrupt return counter will
  // be able to access the interrupt info.
  counter_interrupt_returns_.Increment(1);
  interrupt_info_list_.pop_back();
}

// CheckForInterrupt is called whenever any relevant bits in the interrupt
// enable and set bits are changed. It should always be scheduled to execute
// from the function_delay_line, that way it is executed after an instruction
// has completed execution.
void CheriotState::CheckForInterrupt() {
  // Get global interrupts enable bit.
  bool mie = mstatus_->mie();
  // No interrupts can be taken.
  if (!mie) return;

  // Get pending and enabled interrupts.
  uint32_t interrupts = mip_->AsUint32() & mie_->AsUint32();
  // If there are no enabled pending interrupts, just return.
  if (interrupts == 0) return;

  InterruptCode code = PickInterrupt(interrupts);

  available_interrupt_code_ = code;
  is_interrupt_available_ = true;
}

// Take the interrupt that is pending.
void CheriotState::TakeAvailableInterrupt(uint64_t epc) {
  // Make sure an interrupt is set as pending by CheckForInterrupt.
  if (!is_interrupt_available_) return;
  // Initiate the interrupt.
  Trap(/*is_interrupt*/ true, 0, *available_interrupt_code_, epc, nullptr);
  // Clear pending interrupt.
  is_interrupt_available_ = false;
  available_interrupt_code_ = InterruptCode::kNone;
}

// The priority order of the interrupts are as follows:
// mei, msi, mti, sei, ssi, sti, uei, usi, uti.
InterruptCode CheriotState::PickInterrupt(uint32_t interrupts) {
  if (interrupts & (1 << *InterruptCode::kMachineExternalInterrupt))
    return InterruptCode::kMachineExternalInterrupt;
  if (interrupts & (1 << *InterruptCode::kMachineSoftwareInterrupt))
    return InterruptCode::kMachineSoftwareInterrupt;
  if (interrupts & (1 << *InterruptCode::kMachineTimerInterrupt))
    return InterruptCode::kMachineTimerInterrupt;

  // No supervisor or user mode.

  return InterruptCode::kNone;
}

// Check if the address is for a capability that has been revoked. If so,
// return true;
bool CheriotState::MustRevoke(uint32_t address) const {
  uint64_t revocation_address =
      address & ~(static_cast<uint64_t>(kCapabilitySizeInBytes) - 1ULL);
  // If the address is less than the revocation memory base, return false.
  if (revocation_address < revocation_ram_base()) return false;
  uint64_t offset = (revocation_address - revocation_ram_base());
  uint64_t revocation_offset = offset >> 6;
  tagged_memory_->Load(revocation_mem_base() + revocation_offset,
                       revocation_db_, nullptr, nullptr);
  uint8_t revocation_bits = revocation_db_->Get<uint8_t>(0);
  int bit_offset = (offset >> 3) & 0b111;
  return revocation_bits & (1 << bit_offset);
}

uint64_t RiscVCheri32PcSourceOperand::GetPC() {
  auto *pcc = state_->pcc();
  // PCC should always be a valid capability, otherwise an exception would
  // have been taken. It should also have execute permissions. The only thing
  // to check for is that the address is within bounds.
  if (!pcc->IsInBounds(pcc->address(), state_->has_compact() ? 2 : 4)) {
    state_->HandleCheriRegException(nullptr, pcc->address(),
                                    ExceptionCode::kCapExBoundsViolation, pcc);
  }
  return pcc->address();
}

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