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

#include "riscv/riscv_csr.h"

#include <cstdint>
#include <ios>

#include "absl/status/status.h"
#include "googlemock/include/gmock/gmock.h"
#include "mpact/sim/util/memory/flat_demand_memory.h"
#include "riscv/riscv_state.h"

namespace {

#ifndef EXPECT_OK
#define EXPECT_OK(x) EXPECT_TRUE(x.ok())
#endif

using ::mpact::sim::riscv::RiscV32SimpleCsr;
using ::mpact::sim::riscv::RiscVCsrEnum;
using ::mpact::sim::riscv::RiscVShadowCsr;
using ::mpact::sim::riscv::RiscVState;
using ::mpact::sim::riscv::RiscVXlen;
using ::mpact::sim::util::FlatDemandMemory;

constexpr char kCsrName0[] = "csr0";
constexpr char kCsrName1[] = "csr1";
constexpr uint32_t kAllOnes = 0xffff'ffff;
constexpr uint32_t kDeadBeef = 0xdead'beef;
constexpr uint32_t kA5 = 0xaaaa'5555;
constexpr uint32_t kReadMask = 0x00ff'ff00;
constexpr uint32_t kWriteMask = 0x000f'f000;

// Test fixture class.
class RiscV32CsrTest : public testing::Test {
 protected:
  RiscV32CsrTest() {
    state_ = new RiscVState("test", RiscVXlen::RV32, &memory_);
  }
  ~RiscV32CsrTest() override { delete state_; }

  FlatDemandMemory memory_;
  RiscVState *state_;
};

// Test that the simple csr constructs properly and with the expected values.
TEST_F(RiscV32CsrTest, SimpleCsrConstruction) {
  auto *csr0 = new RiscV32SimpleCsr(kCsrName0, RiscVCsrEnum::kUScratch,
                                    kDeadBeef, state_);
  EXPECT_EQ(csr0->name(), kCsrName0);
  EXPECT_EQ(csr0->index(), static_cast<int>(RiscVCsrEnum::kUScratch));
  EXPECT_EQ(csr0->read_mask(), kAllOnes);
  EXPECT_EQ(csr0->write_mask(), kAllOnes);
  csr0->set_read_mask(kReadMask);
  csr0->set_write_mask(kWriteMask);
  EXPECT_EQ(csr0->read_mask(), kReadMask);
  EXPECT_EQ(csr0->write_mask(), kWriteMask);

  auto *csr1 = new RiscV32SimpleCsr(kCsrName1, RiscVCsrEnum::kMScratch, kA5,
                                    kReadMask, kWriteMask, state_);
  EXPECT_EQ(csr1->name(), kCsrName1);
  EXPECT_EQ(csr1->index(), static_cast<int>(RiscVCsrEnum::kMScratch));
  EXPECT_EQ(csr1->read_mask(), kReadMask);
  EXPECT_EQ(csr1->write_mask(), kWriteMask);

  delete csr0;
  delete csr1;
}

// Read and write values from/to the csr.
TEST_F(RiscV32CsrTest, SimpleCsrReadWrite) {
  auto *csr = new RiscV32SimpleCsr(kCsrName1, RiscVCsrEnum::kMScratch, kA5,
                                   kReadMask, kWriteMask, state_);
  EXPECT_EQ(csr->AsUint32(), kA5 & kReadMask);
  csr->Write(kAllOnes);
  EXPECT_EQ(csr->AsUint32(), (kA5 & kReadMask) | (kAllOnes & kWriteMask))
      << std::hex << csr->AsUint32()
      << " != " << ((kA5 & kReadMask) | (kAllOnes & kWriteMask));
  delete csr;
}

// Raw read/writes.
TEST_F(RiscV32CsrTest, SimpleCsrSetGet) {
  auto *csr = new RiscV32SimpleCsr(kCsrName1, RiscVCsrEnum::kMScratch, kA5,
                                   kReadMask, kWriteMask, state_);
  EXPECT_EQ(csr->GetUint32(), kA5);
  csr->Set(kAllOnes);
  EXPECT_EQ(csr->AsUint32(), (kAllOnes & kReadMask));
  EXPECT_EQ(csr->GetUint32(), kAllOnes);
  delete csr;
}

// Test the csr-set class.
TEST_F(RiscV32CsrTest, CsrSet) {
  // Allocate new csr.
  auto *csr = new RiscV32SimpleCsr(kCsrName1, RiscVCsrEnum::kUScratch, kA5,
                                   kReadMask, kWriteMask, state_);
  // Add it to the set, then try to add it again. The second attempt should
  // fail.
  EXPECT_OK(state_->csr_set()->AddCsr(csr));
  EXPECT_EQ(state_->csr_set()->AddCsr(csr).code(),
            absl::StatusCode::kAlreadyExists);
  // Read the csr and validate the value.
  auto result =
      state_->csr_set()->GetCsr(static_cast<int>(RiscVCsrEnum::kUScratch));
  EXPECT_OK(result.status());
  auto *stored_csr = result.value();
  EXPECT_EQ(stored_csr, csr);
  EXPECT_EQ(stored_csr->AsUint32(), (kA5 & kReadMask));
  // Getting a different csr should fail.
  EXPECT_EQ(state_->csr_set()->GetCsr(0xffff).status().code(),
            absl::StatusCode::kNotFound);
  delete csr;
}

// Test that the shadow csr constructs properly and with the expected values.
TEST_F(RiscV32CsrTest, ShadowCsrConstruction) {
  auto *csr0 = new RiscV32SimpleCsr(kCsrName0, RiscVCsrEnum::kMScratch,
                                    kDeadBeef, state_);
  EXPECT_EQ(csr0->name(), kCsrName0);
  EXPECT_EQ(csr0->index(), static_cast<int>(RiscVCsrEnum::kMScratch));

  auto *csr1 = new RiscVShadowCsr<uint32_t>(
      kCsrName1, RiscVCsrEnum::kUScratch, kReadMask, kWriteMask, state_, csr0);
  EXPECT_EQ(csr1->name(), kCsrName1);
  EXPECT_EQ(csr1->index(), static_cast<int>(RiscVCsrEnum::kUScratch));
  EXPECT_EQ(csr1->read_mask(), kReadMask);
  EXPECT_EQ(csr1->write_mask(), kWriteMask);

  EXPECT_EQ(csr1->AsUint32(), csr0->AsUint32() & kReadMask);
  csr1->Write(kAllOnes);
  EXPECT_EQ(csr0->AsUint32(), kDeadBeef | (kAllOnes & kWriteMask));
  delete csr0;
  delete csr1;
}

}  // namespace
