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

#include <sys/types.h>

#include <cstdint>
#include <cstring>

#include "cheriot/cheriot_register.h"
#include "googlemock/include/gmock/gmock.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/instruction.h"
#include "mpact/sim/util/memory/flat_demand_memory.h"
#include "mpact/sim/util/memory/tagged_flat_demand_memory.h"
#include "mpact/sim/util/memory/tagged_memory_interface.h"
#include "riscv//riscv_plic.h"

// This file contains unit tests for the CheriotIbexHWRevoker class.

namespace {

using ::mpact::sim::cheriot::CheriotIbexHWRevoker;
using ::mpact::sim::cheriot::CheriotRegister;
using ::mpact::sim::generic::DataBuffer;
using ::mpact::sim::generic::DataBufferFactory;
using ::mpact::sim::generic::Instruction;
using ::mpact::sim::generic::ReferenceCount;
using ::mpact::sim::riscv::RiscVPlicIrqInterface;
using ::mpact::sim::util::FlatDemandMemory;
using ::mpact::sim::util::TaggedFlatDemandMemory;
using ::mpact::sim::util::TaggedMemoryInterface;

constexpr uint64_t kRevocationBase = 0x200'0000;
constexpr uint64_t kHeapBase = 0x8001'0000;
constexpr uint64_t kSweepBase = 0x8000'0000;

// Mock plic source interface.
class MockPlicSource : public RiscVPlicIrqInterface {
 public:
  MockPlicSource() = default;
  ~MockPlicSource() override = default;
  void SetIrq(bool irq_value) override { irq_value_ = irq_value; }

  bool irq_value() const { return irq_value_; }
  void set_irq_value(bool value) { irq_value_ = value; }

 private:
  bool irq_value_ = false;
};

// This class is used to capture memory load/store addresses.
class MemoryViewer : public TaggedMemoryInterface {
 public:
  MemoryViewer() = delete;
  MemoryViewer(TaggedMemoryInterface *memory) : memory_(memory) {}
  ~MemoryViewer() override = default;

  void Load(uint64_t address, DataBuffer *db, DataBuffer *tags,
            Instruction *inst, ReferenceCount *context) override {
    ld_address_ = address;
    memory_->Load(address, db, tags, inst, context);
  }
  void Load(uint64_t address, DataBuffer *db, Instruction *inst,
            ReferenceCount *context) override {
    ld_address_ = address;
    memory_->Load(address, db, inst, context);
  }
  void Load(DataBuffer *address_db, DataBuffer *mask_db, int el_size,
            DataBuffer *db, Instruction *inst,
            ReferenceCount *context) override {
    ld_address_ = address_db->Get<uint64_t>(0);
    memory_->Load(address_db, mask_db, el_size, db, inst, context);
  }
  void Store(uint64_t address, DataBuffer *db, DataBuffer *tags) override {
    st_address_ = address;
    memory_->Store(address, db, tags);
  }
  void Store(uint64_t address, DataBuffer *db) override {
    st_address_ = address;
    memory_->Store(address, db);
  }
  void Store(DataBuffer *address_db, DataBuffer *mask_db, int el_size,
             DataBuffer *db) override {
    st_address_ = address_db->Get<uint64_t>(0);
    memory_->Store(address_db, mask_db, el_size, db);
  }

  uint64_t ld_address() const { return ld_address_; }
  uint64_t st_address() const { return st_address_; }

 private:
  TaggedMemoryInterface *memory_ = nullptr;
  uint64_t ld_address_ = 0;
  uint64_t st_address_ = 0;
};

class CheriotIbexHwRevokerTest : public ::testing::Test {
 protected:
  CheriotIbexHwRevokerTest() {
    db1_ = db_factory_.Allocate<uint8_t>(1);
    db4_ = db_factory_.Allocate<uint32_t>(1);
    db8_ = db_factory_.Allocate<uint32_t>(2);
    db128_ = db_factory_.Allocate<uint8_t>(128);
    plic_irq_ = new MockPlicSource();
    heap_memory_ = new TaggedFlatDemandMemory(8);
    memory_viewer_ = new MemoryViewer(heap_memory_);
    revocation_memory_ = new FlatDemandMemory();
    revoker_ =
        new CheriotIbexHWRevoker(plic_irq_, kHeapBase, 0x8000, memory_viewer_,
                                 kRevocationBase, revocation_memory_);
    cap_reg_ = new CheriotRegister(nullptr, "cap");
    cap_db_ = db_factory_.Allocate<uint32_t>(1);
    cap_reg_->SetDataBuffer(cap_db_);
  }

  ~CheriotIbexHwRevokerTest() override {
    db1_->DecRef();
    db4_->DecRef();
    db8_->DecRef();
    db128_->DecRef();
    cap_db_->DecRef();
    delete plic_irq_;
    delete revoker_;
    delete heap_memory_;
    delete memory_viewer_;
    delete revocation_memory_;
    delete cap_reg_;
  }

  // Call to advance the revoker.
  void AdvanceRevoker() { revoker_->SetValue(0); }

  // Convenience method to set the revocation bit for the given address.
  void RevokeAddress(uint64_t address) {
    if (address < kHeapBase) return;
    uint64_t offset = address - kHeapBase;
    offset >>= 3;
    auto bit = offset & 0x7;
    offset >>= 3;
    revocation_memory_->Load(kRevocationBase + offset, db1_, nullptr, nullptr);
    uint8_t val = db1_->Get<uint8_t>(0);
    val |= 1 << bit;
    db1_->Set<uint8_t>(0, val);
    revocation_memory_->Store(kRevocationBase + offset, db1_);
  }

  // This clears the revocation bits for the memory range [kHeapBase, kHeapBase
  // + 0x8000].
  void ClearRevocationBits() {
    std::memset(db128_->raw_ptr(), 0, db128_->size<uint8_t>());
    uint64_t address = kRevocationBase;
    for (uint64_t i = 0; i < 0x100; ++i) {
      revocation_memory_->Store(address, db128_);
      address += db128_->size<uint8_t>();
    }
  }

  // The following methods are convenience methods for accessing the MMRs of
  // the hw revoker using the revoker's memory interface.
  void SetStartAddress(uint32_t address) {
    db4_->Set<uint32_t>(0, address);
    revoker_->Store(CheriotIbexHWRevoker::kStartAddressOffset, db4_);
  }
  uint32_t GetStartAddress() {
    revoker_->Load(CheriotIbexHWRevoker::kStartAddressOffset, db4_, nullptr,
                   nullptr);
    return db4_->Get<uint32_t>(0);
  }
  void SetEndAddress(uint32_t address) {
    db4_->Set<uint32_t>(0, address);
    revoker_->Store(CheriotIbexHWRevoker::kEndAddressOffset, db4_);
  }
  uint32_t GetEndAddress() {
    revoker_->Load(CheriotIbexHWRevoker::kEndAddressOffset, db4_, nullptr,
                   nullptr);
    return db4_->Get<uint32_t>(0);
  }
  void SetGo(uint32_t go) {
    db4_->Set<uint32_t>(0, go);
    revoker_->Store(CheriotIbexHWRevoker::kGoOffset, db4_);
  }
  uint32_t GetGo() {
    revoker_->Load(CheriotIbexHWRevoker::kGoOffset, db4_, nullptr, nullptr);
    return db4_->Get<uint32_t>(0);
  }
  void SetEpoch(uint32_t epoch) {
    db4_->Set<uint32_t>(0, epoch);
    revoker_->Store(CheriotIbexHWRevoker::kEpochOffset, db4_);
  }
  uint32_t GetEpoch() {
    revoker_->Load(CheriotIbexHWRevoker::kEpochOffset, db4_, nullptr, nullptr);
    return db4_->Get<uint32_t>(0);
  }
  void SetStatus(uint32_t status) {
    db4_->Set<uint32_t>(0, status);
    revoker_->Store(CheriotIbexHWRevoker::kStatusOffset, db4_);
  }
  uint32_t GetStatus() {
    revoker_->Load(CheriotIbexHWRevoker::kStatusOffset, db4_, nullptr, nullptr);
    return db4_->Get<uint32_t>(0);
  }
  void SetInterruptEnable(uint32_t enable) {
    db4_->Set<uint32_t>(0, enable);
    revoker_->Store(CheriotIbexHWRevoker::kInterruptEnableOffset, db4_);
  }
  uint32_t GetInterruptEnable() {
    revoker_->Load(CheriotIbexHWRevoker::kInterruptEnableOffset, db4_, nullptr,
                   nullptr);
    return db4_->Get<uint32_t>(0);
  }

  // Convenience method to write a valid capability to memory with the given
  // base.
  void WriteCapability(uint64_t address, uint64_t base) {
    cap_reg_->ResetMemoryRoot();
    cap_reg_->SetAddress(base);
    cap_reg_->SetBounds(base, 0x10);
    db8_->Set<uint32_t>(0, cap_reg_->address());
    db8_->Set<uint32_t>(1, cap_reg_->Compress());
    db8_->set_latency(0);
    db1_->Set<uint8_t>(0, true);
    db1_->set_latency(0);
    heap_memory_->Store(address, db8_, db1_);
  }

  // Convenience method to read a capability from memory with the given base.
  CheriotRegister *ReadCapability(uint64_t address) {
    heap_memory_->Load(address, db8_, db1_, nullptr, nullptr);
    cap_reg_->Expand(db8_->Get<uint32_t>(0), db8_->Get<uint32_t>(1),
                     db1_->Get<uint8_t>(0));
    return cap_reg_;
  }

  uint64_t GetLoadAddress() { return memory_viewer_->ld_address(); }
  uint64_t GetStoreAddress() { return memory_viewer_->st_address(); }
  MockPlicSource *plic_irq() { return plic_irq_; }

 private:
  CheriotRegister *cap_reg_ = nullptr;
  DataBufferFactory db_factory_;
  DataBuffer *db1_;
  DataBuffer *db4_;
  DataBuffer *db8_;
  DataBuffer *db128_;
  DataBuffer *cap_db_;
  CheriotIbexHWRevoker *revoker_ = nullptr;
  MockPlicSource *plic_irq_ = nullptr;
  TaggedFlatDemandMemory *heap_memory_ = nullptr;
  FlatDemandMemory *revocation_memory_ = nullptr;
  MemoryViewer *memory_viewer_ = nullptr;
};

// Initial state should all be clear.
TEST_F(CheriotIbexHwRevokerTest, TestInitial) {
  EXPECT_EQ(GetStartAddress(), 0);
  EXPECT_EQ(GetEndAddress(), 0);
  EXPECT_EQ(GetGo(), 0x5500'0000);
  EXPECT_EQ(GetEpoch(), 0);
  EXPECT_EQ(GetStatus(), 0);
  EXPECT_EQ(GetInterruptEnable(), 0);
}

// No valid capabilities in the sweep range.
TEST_F(CheriotIbexHwRevokerTest, RevokeNone) {
  SetStartAddress(kSweepBase);
  SetEndAddress(kSweepBase + 0x100);
  SetGo(1);
  EXPECT_EQ(GetGo(), 0x5500'0001);
  // Expect zero status.
  EXPECT_EQ(GetStatus(), 0);
  // Expect sweep to be started.
  EXPECT_EQ(GetEpoch(), 1);
  // Step through 256/8 - 1 capabilities.
  int num = 0x100 / 8;
  for (int i = 0; i < num; ++i) {
    AdvanceRevoker();
    EXPECT_EQ(GetLoadAddress(), kSweepBase + (i << 3));
    EXPECT_EQ(GetEpoch(), 1);
    EXPECT_EQ(GetStatus(), 0);
  }
  // Step through the next capability. The sweep should be done.
  AdvanceRevoker();
  // Notice the in progress bit is cleared.
  EXPECT_EQ(GetEpoch(), (1 << 1) | 0);
  // Interrupt status should be 0, as interrupt enable is off.
  EXPECT_EQ(GetStatus(), 0);
}

TEST_F(CheriotIbexHwRevokerTest, RevokeOne) {
  // Write a capability at the sweep base.
  for (auto offset = 0; offset < 0x100; offset += 0x8) {
    WriteCapability(kSweepBase + offset, kHeapBase + offset);
    auto *cap = ReadCapability(kSweepBase);
    EXPECT_TRUE(cap->tag());
  }
  // Revoke one capability.
  RevokeAddress(kHeapBase + 0x20);
  // Set the sweep range to include the capability.
  SetStartAddress(kSweepBase);
  SetEndAddress(kSweepBase + 0x100);
  SetGo(1);
  // Expect zero status.
  EXPECT_EQ(GetStatus(), 0);
  // Expect sweep to be started.
  EXPECT_EQ(GetEpoch(), 1);
  // Step through the sweep.
  while ((GetEpoch() & 0x1) == 1) {
    AdvanceRevoker();
  }
  // Since interrupt enable is not set, the status should be zero.
  EXPECT_EQ(GetStatus(), 0);
  // Verify that only the one revoked capability was invalidated.
  for (auto offset = 0; offset < 0x100; offset += 0x8) {
    auto *cap = ReadCapability(kSweepBase + offset);
    if (offset == 0x20) {
      EXPECT_FALSE(cap->tag());
    } else {
      EXPECT_TRUE(cap->tag());
    }
  }
}

TEST_F(CheriotIbexHwRevokerTest, RevokeWithInterrupt) {
  // Write a capability at the sweep base.
  for (auto offset = 0; offset < 0x100; offset += 0x8) {
    WriteCapability(kSweepBase + offset, kHeapBase + offset);
    auto *cap = ReadCapability(kSweepBase);
    EXPECT_TRUE(cap->tag());
  }
  // Revoke one capability.
  RevokeAddress(kHeapBase + 0x20);
  // Set the sweep range to include the capability.
  SetStartAddress(kSweepBase);
  SetEndAddress(kSweepBase + 0x100);
  // Enable interrupt.
  SetInterruptEnable(1);
  SetGo(1);
  while ((GetEpoch() & 0x1) == 1) {
    AdvanceRevoker();
  }
  EXPECT_EQ(GetStatus(), 1);
  // Verify that the interrupt was set.
  EXPECT_TRUE(plic_irq()->irq_value());
}

}  // namespace
