// 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
//
//     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 THIRD_PARTY_MPACT_RISCV_RISCV_CLINT_H_
#define THIRD_PARTY_MPACT_RISCV_RISCV_CLINT_H_

#include <cstdint>

#include "mpact/sim/generic/counters.h"
#include "mpact/sim/generic/counters_base.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/generic/ref_count.h"
#include "mpact/sim/util/memory/memory_interface.h"
#include "riscv/riscv_xip_xie.h"

namespace mpact {
namespace sim {
namespace riscv {

// This file contains the class definition of a simple implementation of the
// RiscV Core Level Interrupt controller.
//
// The interrupt controller occupies 0x1'0000 bytes in the memory space. Only
// the lower 16 bits of addresses passed to the clint are considered. It is
// the responsibility of the callers to ensure that the memory requests are
// properly routed according to the address.
//
// The interrupt controller models three memory mapped registers:
//     msip:     0xXXXX_0000 4B machine mode software interrupt.
//     mtimecmp: 0xXXXX_4000 8B machine mode timer compare register.
//     mtime:    0xXXXX_BFF8 8B machine mode timer register.
//
// The controller binds to a counter, for instance the instructions executed
// counter, using the CounterValueSetInterface<> interface. The update_counter_
// keeps track of how many times this is updated, and then increments the mtime
// register once for each 'period' updates. That is, the frequency of the mtime
// clock is 1/'period' of the associated counter. The controller implements the
// MemoryInterface to allow for memory-mapped loads and stores. Only the
// non-vector Load/Store methods are implemented.
//
// The controller only uses the low 16 bits of the address. It is assumed that
// any memory requests routed to the controller are done so correctly.

using ::mpact::sim::generic::CounterValueSetInterface;
using ::mpact::sim::generic::DataBuffer;
using ::mpact::sim::generic::Instruction;
using ::mpact::sim::generic::ReferenceCount;
using ::mpact::sim::generic::SimpleCounter;
using ::mpact::sim::riscv::MipExternalWriteInterface;
using ::mpact::sim::util::MemoryInterface;

class RiscVClint : public CounterValueSetInterface<uint64_t>,
                   public MemoryInterface {
 public:
  RiscVClint(int period, MipExternalWriteInterface* mip_interface);
  RiscVClint() = delete;
  RiscVClint(const RiscVClint&) = delete;
  RiscVClint& operator=(const RiscVClint&) = delete;
  ~RiscVClint() override = default;
  // Resets the interrupt controller.
  void Reset();
  // CounterValueSetInterface override. This is called when the value of the
  // bound counter is modified.
  void SetValue(const uint64_t& val) override;

  // MemoryInterface overrides.
  // Non-vector load method.
  void Load(uint64_t address, DataBuffer* db, Instruction* inst,
            ReferenceCount* context) override;
  // Vector load method - this is stubbed out.
  void Load(DataBuffer* address_db, DataBuffer* mask_db, int el_size,
            DataBuffer* db, Instruction* inst,
            ReferenceCount* context) override;
  // Non-vector store method.
  void Store(uint64_t address, DataBuffer* db) override;
  // Vector store method - this is stubbed out.
  void Store(DataBuffer* address, DataBuffer* mask, int el_size,
             DataBuffer* db) override;

 private:
  // Helpers.
  uint32_t Read(uint32_t offset);
  void Write(uint32_t offset, uint32_t value);
  // Private methods to access the 32 bit portions of the registers.
  uint32_t ReadMTimeLow();
  uint32_t ReadMTimeHigh();
  void WriteMSip(uint32_t value);
  void WriteMTimeCmpLow(uint32_t value);
  void WriteMTimeCmpHigh(uint32_t value);
  void WriteMTimeLow(uint32_t value);
  void WriteMTimeHigh(uint32_t value);

  // The simulated register values.
  uint32_t msip_ = 0;
  uint64_t mtime_ = 0;
  uint64_t mtimecmp_ = 0;
  int mtip_ = 0;
  // mip write interface.
  MipExternalWriteInterface* mip_interface_;
  // Counter for how many updates there have been in current period.
  int update_counter_ = 0;
  int period_ = 0;
};

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

#endif  // THIRD_PARTY_MPACT_RISCV_RISCV_CLINT_H_
