// 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
//
//     https://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.

#ifndef MPACT_RISCV_RISCV_RISCV_STATE_H_
#define MPACT_RISCV_RISCV_RISCV_STATE_H_

#include <cstdint>
#include <limits>
#include <string>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/generic/arch_state.h"
#include "mpact/sim/generic/counters.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/generic/operand_interface.h"
#include "mpact/sim/generic/ref_count.h"
#include "mpact/sim/util/memory/memory_interface.h"
#include "riscv/riscv_csr.h"
#include "riscv/riscv_misa.h"
#include "riscv/riscv_register.h"
#include "riscv/riscv_vector_state.h"
#include "riscv/riscv_xip_xie.h"
#include "riscv/riscv_xstatus.h"

namespace mpact {
namespace sim {
namespace riscv {

using ArchState = ::mpact::sim::generic::ArchState;
using DataBuffer = ::mpact::sim::generic::DataBuffer;
using Instruction = ::mpact::sim::generic::Instruction;
using ReferenceCount = ::mpact::sim::generic::ReferenceCount;

// Exception codes.
enum class ExceptionCode : uint64_t {
  kInstructionAddressMisaligned = 0,
  kInstructionAccessFault = 1,
  kIllegalInstruction = 2,
  kBreakpoint = 3,
  kLoadAddressMisaligned = 4,
  kLoadAccessFault = 5,
  kStoreAddressMisaligned = 6,
  kStoreAccessFault = 7,
  kEnvCallFromUMode = 8,
  kEnvCallFromSMode = 9,
  kEnvCallFromMMode = 11,
  kInstructionPageFault = 12,
  kLoadPageFault = 13,
  kStorePageFault = 15,
};

// Interrupt codes.
enum class InterruptCode : uint64_t {
  kUserSoftwareInterrupt = 0,
  kSupervisorSoftwareInterrupt = 1,
  kMachineSoftwareInterrupt = 3,
  kUserTimerInterrupt = 4,
  kSupervisorTimerInterrupt = 5,
  kMachineTimerInterrupt = 7,
  kUserExternalInterrupt = 8,
  kSupervisorExternalInterrupt = 9,
  kMachineExternalInterrupt = 11,
  kNone = std::numeric_limits<uint64_t>::max(),
};

// Isa extensions.
enum class IsaExtension : uint64_t {
  kAtomic = 1 << 0,
  kBitManipulation = 1 << 1,
  kCompressed = 1 << 2,
  kDoublePrecisionFp = 1 << 3,
  kRV32EBase = 1 << 4,
  kSinglePrecisionFp = 1 << 5,
  kGExtension = 1 << 6,
  kHypervisor = 1 << 7,
  kRVIBaseIsa = 1 << 8,
  kJExtension = 1 << 9,
  kKReserved = 1 << 10,
  kLExtension = 1 << 11,
  kIntegerMulDiv = 1 << 12,
  kUserLevelInterrupts = 1 << 13,
  kOReserved = 1 << 14,
  kPExtension = 1 << 15,
  kQuadPrecisionFp = 1 << 16,
  kRReserved = 1 << 17,
  kSupervisorMode = 1 << 18,
  kTExtension = 1 << 19,
  kUserMode = 1 << 20,
  kVectorExtension = 1 << 21,
  kWReserved = 1 << 22,
  kNonStandardExtension = 1 << 23,
  kYReserved = 1 << 24,
  kZReserved = 1 << 25,
  kNone = std::numeric_limits<uint64_t>::max(),
};

// Privilege modes.
enum class PrivilegeMode : uint64_t {
  kUser = 0b00,
  kSupervisor = 0b01,
  kMachine = 0b11,
};

// A simple load context class for convenience.
struct LoadContext : public generic::ReferenceCount {
  explicit LoadContext(DataBuffer* vdb) : value_db(vdb) {}
  ~LoadContext() override {
    if (value_db != nullptr) value_db->DecRef();
  }

  // Override the base class method so that the data buffer can be DecRef'ed
  // when the context object is recycled.
  void OnRefCountIsZero() override {
    if (value_db != nullptr) value_db->DecRef();
    value_db = nullptr;
    // Call the base class method.
    generic::ReferenceCount::OnRefCountIsZero();
  }
  // Data buffers for the value loaded from memory (byte, half, word, etc.).
  DataBuffer* value_db = nullptr;
};

// Vector load context class.
struct VectorLoadContext : public generic::ReferenceCount {
  VectorLoadContext(DataBuffer* vdb, DataBuffer* mdb, int element_width_,
                    int vstart_, int vlength_)
      : value_db(vdb),
        mask_db(mdb),
        element_width(element_width_),
        vstart(vstart_),
        vlength(vlength_) {}
  ~VectorLoadContext() override {
    if (value_db != nullptr) value_db->DecRef();
    if (mask_db != nullptr) mask_db->DecRef();
  }
  // Override the base class method so that the data buffers can be DecRef'ed
  // when the context object is recycled.
  void OnRefCountIsZero() override {
    if (value_db != nullptr) value_db->DecRef();
    value_db = nullptr;
    if (mask_db != nullptr) mask_db->DecRef();
    mask_db = nullptr;
    // Call the base class method.
    generic::ReferenceCount::OnRefCountIsZero();
  }
  // DataBuffer instances for the value loaded from memory.
  DataBuffer* value_db = nullptr;
  // Mask data buffer.
  DataBuffer* mask_db = nullptr;
  // Vector element width.
  int element_width;
  // Starting element index.
  int vstart;
  // Vector length.
  int vlength;
};

// Supported values of Xlen.
enum class RiscVXlen : uint64_t {
  RV32 = 0b01,
  RV64 = 0b10,
  RVUnknown = 4,
};

// Forward declare a template function defined in the .cc file.
template <typename T>
void CreateCsrs(RiscVState*, std::vector<RiscVCsrInterface*>&);

class RiscVFPState;
class RiscVPmp;

// Class that extends ArchState with RiscV specific methods. These methods
// implement RiscV specific memory operations, memory/IO fencing, system
// calls and software breakpoints.
class RiscVState : public ArchState {
 public:
  friend void CreateCsrs<uint32_t>(RiscVState*,
                                   std::vector<RiscVCsrInterface*>&);
  friend void CreateCsrs<uint64_t>(RiscVState*,
                                   std::vector<RiscVCsrInterface*>&);

  static constexpr char kFregPrefix[] = "f";
  static constexpr char kXregPrefix[] = "x";
  static constexpr char kVregPrefix[] = "v";
  static constexpr char kCsrName[] = "csr";
  static constexpr char kNextPcName[] = "next_pc";
  static constexpr char kPcName[] = "pc";

  RiscVState(absl::string_view id, RiscVXlen xlen,
             util::MemoryInterface* memory,
             util::AtomicMemoryOpInterface* atomic_memory);
  RiscVState(absl::string_view id, RiscVXlen xlen,
             util::MemoryInterface* memory)
      : RiscVState(id, xlen, memory, nullptr) {}
  ~RiscVState() override;

  // Deleted Constructors and operators.
  RiscVState(const RiscVState&) = delete;
  RiscVState(RiscVState&&) = delete;
  RiscVState& operator=(const RiscVState&) = delete;
  RiscVState& operator=(RiscVState&&) = delete;

  // Return a pair consisting of pointer to the named register and a bool that
  // is true if the register had to be created, and false if it was found
  // in the register map (or if nullptr is returned).
  template <typename RegisterType>
  std::pair<RegisterType*, bool> GetRegister(absl::string_view name) {
    // If the register already exists, return a pointer to the register.
    auto ptr = registers()->find(std::string(name));
    if (ptr != registers()->end())
      return std::make_pair(static_cast<RegisterType*>(ptr->second), false);
    // Create a new register and return a pointer to the object.
    return std::make_pair(AddRegister<RegisterType>(name), true);
  }

  // Add register alias.
  template <typename RegisterType>
  absl::Status AddRegisterAlias(absl::string_view current_name,
                                absl::string_view new_name) {
    auto ptr = registers()->find(std::string(current_name));
    if (ptr == registers()->end()) {
      return absl::NotFoundError(
          absl::StrCat("Register '", current_name, "' does not exist."));
    }
    AddRegister(new_name, ptr->second);
    return absl::OkStatus();
  }

  // Methods called by instruction semantic functions to load from memory.
  void LoadMemory(const Instruction* inst, uint64_t address, DataBuffer* db,
                  Instruction* child_inst, ReferenceCount* context);
  void LoadMemory(const Instruction* inst, DataBuffer* address_db,
                  DataBuffer* mask_db, int el_size, DataBuffer* db,
                  Instruction* child_inst, ReferenceCount* context);
  // Methods called by instruction semantic functions to store to memory.
  void StoreMemory(const Instruction* inst, uint64_t address, DataBuffer* db);
  void StoreMemory(const Instruction* inst, DataBuffer* address_db,
                   DataBuffer* mask_db, int el_size, DataBuffer* db);
  // Called by the fence instruction semantic function to signal a fence
  // operation.
  void Fence(const Instruction* inst, int fm, int predecessor, int successor);
  // Synchronize instruction and data streams.
  void FenceI(const Instruction* inst);
  // System call.
  void ECall(const Instruction* inst);
  // Breakpoint.
  void EBreak(const Instruction* inst);
  // WFI
  void WFI(const Instruction* inst);
  // Ceases execution on the core. This is a non-standard instruction that
  // quiesces traffic for embedded cores before halting. The core must be reset
  // to come out of this state.
  void Cease(const Instruction* inst);
  // Trap.
  void Trap(bool is_interrupt, uint64_t trap_value, uint64_t exception_code,
            uint64_t epc, const Instruction* inst);
  // Add ebreak handler.
  void AddEbreakHandler(absl::AnyInvocable<bool(const Instruction*)> handler) {
    on_ebreak_.emplace_back(std::move(handler));
  }
  // This function is called after any event that may have caused an interrupt
  // to be registered as pending or enabled. If the interrupt can be taken
  // it registers it as available.
  void CheckForInterrupt() override;
  // This function is called when the return pc for the available interrupt
  // is known. If there is no available interrupt, it just returns.
  void TakeAvailableInterrupt(uint64_t epc);

  // Indicates that the program has returned from handling an interrupt. This
  // decrements the interrupt handler depth and should be called by the
  // implementations of mret, sret, and uret.
  void SignalReturnFromInterrupt() { counter_interrupt_returns_.Increment(1); }

  // Returns the depth of the interrupt handler currently being executed, or
  // zero if no interrupt handler is being executed.
  int InterruptHandlerDepth() const {
    return counter_interrupts_taken_.GetValue() -
           counter_interrupt_returns_.GetValue();
  }

  // Accessors.
  void set_memory(util::MemoryInterface* memory) { memory_ = memory; }
  util::MemoryInterface* memory() const { return memory_; }
  util::AtomicMemoryOpInterface* atomic_memory() const {
    return atomic_memory_;
  }
  void set_atomic_memory(util::AtomicMemoryOpInterface* atomic_memory) {
    atomic_memory_ = atomic_memory;
  }

  void set_max_physical_address(uint64_t max_physical_address);
  uint64_t max_physical_address() const { return max_physical_address_; }

  // Setters for handlers for ecall, and trap. The handler returns true
  // if the instruction/event was handled, and false otherwise.

  void set_on_ecall(absl::AnyInvocable<bool(const Instruction*)> callback) {
    on_ecall_ = std::move(callback);
  }

  void set_on_wfi(absl::AnyInvocable<bool(const Instruction*)> callback) {
    on_wfi_ = std::move(callback);
  }

  void set_on_cease(absl::AnyInvocable<bool(const Instruction*)> callback) {
    on_cease_ = std::move(callback);
  }

  void set_on_trap(
      absl::AnyInvocable<bool(bool /*is_interrupt*/, uint64_t /*trap_value*/,
                              uint64_t /*exception_code*/, uint64_t /*epc*/,
                              const Instruction*)>
          callback) {
    on_trap_ = std::move(callback);
  }

  int flen() const { return flen_; }
  RiscVXlen xlen() const { return xlen_; }
  RiscVVectorState* rv_vector() const { return rv_vector_; }
  void set_rv_vector(RiscVVectorState* value) { rv_vector_ = value; }
  RiscVFPState* rv_fp() const { return rv_fp_; }
  void set_rv_fp(RiscVFPState* value) { rv_fp_ = value; }
  void set_vector_register_width(int value) { vector_register_width_ = value; }
  int vector_register_width() const { return vector_register_width_; }

  RiscVCsrSet* csr_set() const { return csr_set_; }

  PrivilegeMode privilege_mode() const { return privilege_mode_; }
  void set_privilege_mode(PrivilegeMode privilege_mode) {
    privilege_mode_ = privilege_mode;
  }

  // Returns true if an interrupt is available for the core to take or false
  // otherwise.
  inline bool is_interrupt_available() const { return is_interrupt_available_; }
  // Resets the is_interrupt_available flag to false. This should only be called
  // when resetting the RISCV core, as 'is_interrupt_available' is Normally
  // reset during the interrupt handling flow.
  inline void reset_is_interrupt_available() {
    is_interrupt_available_ = false;
  }

  void set_branch(bool value) { branch_ = value; }
  bool branch() const { return branch_; }

  // Getters for select CSRs.
  RiscVMStatus* mstatus() const { return mstatus_; }
  RiscVMIsa* misa() const { return misa_; }
  RiscVMIp* mip() const { return mip_; }
  RiscVMIe* mie() const { return mie_; }
  RiscVCsrInterface* jvt() const { return jvt_; }
  RiscVCsrInterface* mtvec() const { return mtvec_; }
  RiscVCsrInterface* mepc() const { return mepc_; }
  RiscVCsrInterface* mcause() const { return mcause_; }
  RiscVCsrInterface* medeleg() const { return medeleg_; }
  RiscVCsrInterface* mideleg() const { return mideleg_; }
  RiscVSIp* sip() const { return sip_; }
  RiscVSIe* sie() const { return sie_; }
  RiscVCsrInterface* stvec() const { return stvec_; }
  RiscVCsrInterface* sepc() const { return sepc_; }
  RiscVCsrInterface* scause() const { return scause_; }
  RiscVCsrInterface* sideleg() const { return sideleg_; }

 private:
  InterruptCode PickInterrupt(uint32_t interrupts);
  RiscVXlen xlen_;
  uint64_t max_physical_address_;
  RiscVVectorState* rv_vector_ = nullptr;
  RiscVFPState* rv_fp_ = nullptr;
  // Program counter register.
  generic::RegisterBase* pc_;
  // Operands used to access pc values generically. Note, the pc value may read
  // as the address of the next instruction during execution of an instruction,
  // so the address of the instruction executing should be used instead.
  generic::SourceOperandInterface* pc_src_operand_ = nullptr;
  generic::DestinationOperandInterface* pc_dst_operand_ = nullptr;
  int vector_register_width_ = 0;
  int flen_ = 0;
  util::MemoryInterface* memory_ = nullptr;
  util::AtomicMemoryOpInterface* atomic_memory_ = nullptr;
  RiscVCsrSet* csr_set_ = nullptr;
  std::vector<absl::AnyInvocable<bool(const Instruction*)>> on_ebreak_;
  absl::AnyInvocable<bool(const Instruction*)> on_ecall_;
  absl::AnyInvocable<bool(bool, uint64_t, uint64_t, uint64_t,
                          const Instruction*)>
      on_trap_;
  absl::AnyInvocable<bool(const Instruction*)> on_wfi_;
  absl::AnyInvocable<bool(const Instruction*)> on_cease_;
  std::vector<RiscVCsrInterface*> csr_vec_;
  // For interrupt handling.
  bool is_interrupt_available_ = false;
  InterruptCode available_interrupt_code_ = InterruptCode::kNone;
  // By default, execute in machine mode.
  PrivilegeMode privilege_mode_ = PrivilegeMode::kMachine;
  // Flag set on branch instructions.
  bool branch_ = false;
  // Handles to frequently used CSRs.
  RiscVMStatus* mstatus_ = nullptr;
  RiscVMIsa* misa_ = nullptr;
  RiscVMIp* mip_ = nullptr;
  RiscVMIe* mie_ = nullptr;
  RiscVPmp* pmp_ = nullptr;
  RiscVCsrInterface* jvt_ = nullptr;
  RiscVCsrInterface* mtvec_ = nullptr;
  RiscVCsrInterface* mepc_ = nullptr;
  RiscVCsrInterface* mcause_ = nullptr;
  RiscVCsrInterface* medeleg_ = nullptr;
  RiscVCsrInterface* mideleg_ = nullptr;
  RiscVSIp* sip_ = nullptr;
  RiscVSIe* sie_ = nullptr;
  RiscVCsrInterface* stvec_ = nullptr;
  RiscVCsrInterface* sepc_ = nullptr;
  RiscVCsrInterface* scause_ = nullptr;
  RiscVCsrInterface* sideleg_ = nullptr;
  generic::SimpleCounter<int64_t> counter_interrupts_taken_;
  generic::SimpleCounter<int64_t> counter_interrupt_returns_;
};

// Specialization for RiscV vector registers.
template <>
inline std::pair<RVVectorRegister*, bool>
RiscVState::GetRegister<RVVectorRegister>(absl::string_view name) {
  int vector_byte_width = vector_register_width();
  if (vector_byte_width == 0) return std::make_pair(nullptr, false);
  auto ptr = registers()->find(std::string(name));
  if (ptr != registers()->end())
    return std::make_pair(static_cast<RVVectorRegister*>(ptr->second), false);
  // Create a new register and return a pointer to the object.
  return std::make_pair(AddRegister<RVVectorRegister>(name, vector_byte_width),
                        true);
}

}  // namespace riscv
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_RISCV_RISCV_RISCV_STATE_H_
