// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_MOCK_MMIO_H_
#define OPENTITAN_SW_DEVICE_LIB_TESTING_MOCK_MMIO_H_

#include <stdint.h>
#include <string.h>

#include <initializer_list>
#include <memory>
#include <random>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "sw/device/lib/base/mmio.h"

namespace mock_mmio {
/**
 * Represents a single bit field in an integer, useable with EXPECT_* macros
 * defined in this file.
 *
 * An integer can be expressed as a list of BitField values, and can be more
 * convenient to use than 0b or 0x literals in some cases. For example, the
 * integer 0b0000'0000'1100'0101 could be expressed as
 *   {{0x0, 1}, {0x2, 1}, {0x4, 12}}
 * This form makes it clearer to the reader that 0x0, 0x2, and 04 are indices
 * to bitfields, which are set to particular values.
 *
 * In practice, this might use generated register constants, and look like
 *   {{FIELD_FOO_OFFSET, 1}, {FIELD_BAR_OFFSET, 1}, {FIELD_BAZ_OFFSET, 12}}
 *
 * This type does not specify the lengths of bitfields; MaskedBitField should be
 * used for that, instead.
 */
struct BitField {
  uintptr_t offset;
  uintptr_t value;
};

/**
 * Represents a single bit field in an integer, similar to BitField. It can be
 * used in most places that need a BitField, as well as in `EXPECT_MASK` macros.
 *
 * Like with BitFields, we can express the integer 0b0000'0000'1100'0101 as a
 * list of BitFieldMasks:
 *   {{0x0, 0x1, 1}, {0x1, 0x1, 0}, {0x2, 0x1, 1}, {0x3, 0x1, 0},
 *    {0x4, 0xff, 12}}
 *
 * In addition to showing how the integer is broken up, it also expresses
 * the lengths of fields, so it is clear that 0x0 and 0x2 are one-bit fields.
 * This also allows us to formally express that the fields 0x1 and 0x3 are
 * *unset*.
 *
 * In practice, this might use generated register constants, and look like
 *   {{FIELD_FOO_OFFSET, FIELD_FOO_MASK, 1}, ...}
 */
struct MaskedBitField {
  uintptr_t offset;
  uintptr_t mask;
  uintptr_t value;
};

namespace internal {
/**
 * Implicit conversion guard around `char *`. See `LeInt()`.
 */
struct LittleEndianBytes {
  const char *bytes;
};

/**
 * Converts the argument into an unsigned integer of type `Int`.
 *
 * This overload is simply the identity on integers, and allows integers to be
 * converted into themselves. This enables the basic EXPECT_* macros:
 *   EXPECT_READ32(offset, 0xcafecafe);
 *
 * @param val an integer.
 * @return the value `val`.
 */
template <typename Int>
Int ToInt(Int val) {
  return val;
}

/**
 * Converts the argument into an unsinged integer of type `Int`.
 *
 * This overload assumes that `str` is a valid pointer to a buffer of at least
 * `sizeof(Int)` bytes, which are memcpy'd out as an `Int`. This enables
 * memcpy-like EXPECT_* macros:
 *   EXPECT_READ32(offset, LeInt("rv32"));
 *   EXPECT_READ32(offset, LeInt("imc\0"));
 *
 * @param str a pointer to a valid buffer of length at least `sizeof(Int)`.
 * @return a value of type `Int` memcpy'd out of `str`.
 */
template <typename Int>
Int ToInt(LittleEndianBytes str) {
  Int val;
  memcpy(&val, str.bytes, sizeof(Int));
  return val;
}

/**
 * Converts the argument into an unsigned integer of type `Int`.
 *
 * This overload performs the shifts and ors described by `fields`. See
 * `BitField`'s documentation for details one what this means. This overload
 * enables bitfield EXPECT_* macros:
 *   EXPECT_READ32(offset, {{A_OFFSET, 0x55}, {B_OFFSET, 0xaa}});
 *
 * @param fields a list of bit field entries.
 * @return a value of type `Int` built out of `fields`.
 */
template <typename Int>
Int ToInt(std::initializer_list<BitField> fields) {
  Int val = 0;
  for (auto field : fields) {
    // Due to the way that gtest ASSERT_* works, and the fact that this must be
    // a
    // function (since we use function overloading), these cannot be ASSERTs,
    // and
    // must be EXPECTs.
    EXPECT_LE(field.offset, sizeof(Int) * 8);
    val |= static_cast<Int>(field.value << field.offset);
  }
  return val;
}
}  // namespace internal

/**
 * Reads a little-endian integer from `bytes`. This function is lazy, and will
 * only perform the converion when used with an EXPECT_* macro. For example:
 *   EXPECT_READ32(offset, LeInt("abcd"));
 *
 * It is not possible to directly pass in string literals into EXPECT_* macros;
 * this is a limitation of C++'s implicit conversion rules and overload
 * resolution order.
 */
inline internal::LittleEndianBytes LeInt(const char *bytes) { return {bytes}; }

/**
 * A MockDevice represents a mock implementation of an MMIO device.
 *
 * MockDevice provides two mockable member functions, representing a read and a
 * write at a particular offset from the base address. This class can be
 * converted into a `mmio_region_t` value, which, when used in `mmio.h`
 * functions like `read32()`, will map to the appropriate mock member function
 * calls.
 *
 * To maintain sequencing, `ReadN()` and `WriteN()` should not be
 * `EXPECT_CALL`'ed directly; instead, `EXPECT_READN` and `EXPECT_WRITEN` should
 * be used, instead.
 *
 * To use this class, `-DMOCK_MMIO` must be enabled in all translation units
 * using `mmio.h`.
 */
class MockDevice {
 public:
  MockDevice() = default;

  MockDevice(const MockDevice &) = delete;
  MockDevice &operator=(const MockDevice &) = delete;
  MockDevice(MockDevice &&) = delete;
  MockDevice &operator=(MockDevice &&) = delete;

  /**
   * Converts this MockDevice into a mmio_region_t opaque object,
   * which is compatible with `mmio.h` functions.
   */
  mmio_region_t region() { return {this}; }

  MOCK_METHOD(uint8_t, Read8, (ptrdiff_t offset));
  MOCK_METHOD(uint32_t, Read32, (ptrdiff_t offset));

  MOCK_METHOD(void, Write8, (ptrdiff_t offset, uint8_t value));
  MOCK_METHOD(void, Write32, (ptrdiff_t offset, uint32_t value));

  /**
   * Generates "garbage memory" for use in tests. This function should not
   * be called directly.
   */
  template <typename Int>
  Int GarbageMemory() {
    return std::uniform_int_distribution<Int>()(gen_);
  }

 private:
  static std::random_device rd;
  std::mt19937 gen_ = std::mt19937(rd());
};

/**
 * Conveninence fixture for creating device tests.
 *
 * This class should be derived by a test fixture (along with `testing::Test`)
 * and used in a `TEST_F` block. Doing so will make the `EXPECT_READN` and
 * `EXPECT_WRITEN` conveinence macros useable.
 *
 * The device being mocked can be accessed in the test body with `this->dev()`.
 * `this->` is required in this case, since the name `dev` is not immediately
 * visible.
 */
class MmioTest {
 protected:
  MockDevice &dev() { return *dev_; }

 private:
  std::unique_ptr<MockDevice> dev_ =
      std::make_unique<testing::StrictMock<MockDevice>>();
  testing::InSequence seq_;
};
}  // namespace mock_mmio

/**
 * Expect a read to the device `dev` at the given offset, returning the given
 * 8-bit value.
 *
 * The value may be given as an integer, a pointer to little-endian data,
 * or a `std::initializer_list<BitField>`.
 *
 * This expectation is sequenced with all other `EXPECT_READ` and `EXPECT_WRITE`
 * calls.
 */
#define EXPECT_READ8_AT(dev, offset, ...) \
  EXPECT_CALL(dev, Read8(offset))         \
      .WillOnce(                          \
          testing::Return(mock_mmio::internal::ToInt<uint8_t>(__VA_ARGS__)))

/**
 * Expect a read to the device `dev` at the given offset, returning the given
 * 32-bit value.
 *
 * The value may be given as an integer, a pointer to little-endian data,
 * or a `std::initializer_list<BitField>`.
 *
 * This expectation is sequenced with all other `EXPECT_READ` and `EXPECT_WRITE`
 * calls.
 */
#define EXPECT_READ32_AT(dev, offset, ...) \
  EXPECT_CALL(dev, Read32(offset))         \
      .WillOnce(                           \
          testing::Return(mock_mmio::internal::ToInt<uint32_t>(__VA_ARGS__)))

/**
 * Expect a write to the device `dev` at the given offset with the given 8-bit
 * value.
 *
 * The value may be given as an integer, a pointer to little-endian data,
 * or a `std::initializer_list<BitField>`.
 *
 * This expectation is sequenced with all other `EXPECT_READ` and `EXPECT_WRITE`
 * calls.
 */
#define EXPECT_WRITE8_AT(dev, offset, ...) \
  EXPECT_CALL(                             \
      dev, Write8(offset, mock_mmio::internal::ToInt<uint8_t>(__VA_ARGS__)))

/**
 * Expect a write to the device `dev` at the given offset with the given 32-bit
 * value.
 *
 * The value may be given as an integer, a pointer to little-endian data,
 * or a `std::initializer_list<BitField>`.
 *
 * This expectation is sequenced with all other `EXPECT_READ` and `EXPECT_WRITE`
 * calls.
 */
#define EXPECT_WRITE32_AT(dev, offset, ...) \
  EXPECT_CALL(                              \
      dev, Write32(offset, mock_mmio::internal::ToInt<uint32_t>(__VA_ARGS__)))

/**
 * Expect a read at the given offset, returning the given 8-bit value.
 *
 * The value may be given as an integer, a pointer to little-endian data,
 * or a `std::initializer_list<BitField>`.
 *
 * This function is only available in tests using a fixture that derives
 * `MmioTest`.
 *
 * This expectation is sequenced with all other `EXPECT_READ` and `EXPECT_WRITE`
 * calls.
 */
#define EXPECT_READ8(offset, ...) \
  EXPECT_READ8_AT(this->dev(), offset, __VA_ARGS__)

/**
 * Expect a read at the given offset, returning the given 32-bit value.
 *
 * The value may be given as an integer, a pointer to little-endian data,
 * or a `std::initializer_list<BitField>`.
 *
 * This function is only available in tests using a fixture that derives
 * `MmioTest`.
 *
 * This expectation is sequenced with all other `EXPECT_READ` and `EXPECT_WRITE`
 * calls.
 */
#define EXPECT_READ32(offset, ...) \
  EXPECT_READ32_AT(this->dev(), offset, __VA_ARGS__)

/**
 * Expect a write to the given offset with the given 8-bit value.
 *
 * The value may be given as an integer, a pointer to little-endian data,
 * or a `std::initializer_list<BitField>`.
 *
 * This function is only available in tests using a fixture that derives
 * `MmioTest`.
 *
 * This expectation is sequenced with all other `EXPECT_READ` and `EXPECT_WRITE`
 * calls.
 */
#define EXPECT_WRITE8(offset, ...) \
  EXPECT_WRITE8_AT(this->dev(), offset, __VA_ARGS__);

/**
 * Expect a write to the given offset with the given 32-bit value.
 *
 * The value may be given as an integer, a pointer to little-endian data,
 * or a `std::initializer_list<BitField>`.
 *
 * This function is only available in tests using a fixture that derives
 * `MmioTest`.
 *
 * This expectation is sequenced with all other `EXPECT_READ` and `EXPECT_WRITE`
 * calls.
 */
#define EXPECT_WRITE32(offset, ...) \
  EXPECT_WRITE32_AT(this->dev(), offset, __VA_ARGS__);

#define EXPECT_MASK_INTERNAL_(width, dev, off, ...)                        \
  do {                                                                     \
    auto &device = dev;                                                    \
    std::initializer_list<mock_mmio::MaskedBitField> fields = __VA_ARGS__; \
                                                                           \
    using Int = uint##width##_t;                                           \
    auto val = device.GarbageMemory<Int>();                                \
    EXPECT_READ##width##_AT(device, off, val);                             \
                                                                           \
    for (auto field : fields) {                                            \
      ASSERT_LT(field.offset, sizeof(Int) * 8);                            \
      ASSERT_LE(field.mask, std::numeric_limits<Int>::max());              \
      ASSERT_LE(field.value, field.mask);                                  \
                                                                           \
      val &= ~static_cast<Int>(field.mask << field.offset);                \
      val |= static_cast<Int>(field.value << field.offset);                \
    }                                                                      \
    EXPECT_WRITE##width##_AT(device, off, val);                            \
  } while (false)

/**
 * Expect an unspecified 8-bit read at the given offset, followed by a write to
 * the same location, with the same value but with some bits changed; the
 * remaining bits must be untouched.
 *
 * The changed bits are specified by a `std::initializer_list<MaskedBitField>`.
 *
 * This function is only available in tests using a fixture that derives
 * `MmioTest`.
 *
 * This expectation is sequenced with all other `EXPECT_READ` and `EXPECT_WRITE`
 * calls.
 */
#define EXPECT_MASK8(offset, ...) \
  EXPECT_MASK_INTERNAL_(8, this->dev(), offset, __VA_ARGS__)

/**
 * Expect an unspecified 32-bit read at the given offset, followed by a write to
 * the same location, with the same value but with some bits changed; the
 * remaining bits must be untouched.
 *
 * The changed bits are specified by a `std::initializer_list<MaskedBitField>`.
 *
 * This function is only available in tests using a fixture that derives
 * `MmioTest`.
 *
 * This expectation is sequenced with all other `EXPECT_READ` and `EXPECT_WRITE`
 * calls.
 */
#define EXPECT_MASK32(offset, ...) \
  EXPECT_MASK_INTERNAL_(32, this->dev(), offset, __VA_ARGS__)

#endif  // OPENTITAN_SW_DEVICE_LIB_TESTING_MOCK_MMIO_H_
