// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef HWREG_INTERNAL_H_
#define HWREG_INTERNAL_H_

#include <inttypes.h>
#include <lib/stdcompat/atomic.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <zircon/assert.h>
#include <zircon/compiler.h>

#include <array>
#include <type_traits>
#include <variant>

// Internal macros for generating a unique name for the internal bookkeeping
// member associated with a given field. Beyond its definition, the member is
// never referenced again, within or outside of the macro: accordingly, we use
// __LINE__ as a simple way to satisfy the desired uniqueness. We do not make
// the name a function of the bit range as that would otherwise preclude the
// use of constexpr arithmetic expressions for bits values; moreover, we cannot
// rely on field name alone, as their an a priori unique one for each reserved
// field, and so would still need an alternate source of uniqueness to cover
// that case.
#define HWREG_INTERNAL_PASTE_IMPL(a, b) a##b
#define HWREG_INTERNAL_PASTE(a, b) HWREG_INTERNAL_PASTE_IMPL(a, b)
#define HWREG_INTERNAL_MEMBER_NAME(NAME) \
  HWREG_INTERNAL_PASTE(field_, HWREG_INTERNAL_PASTE(NAME##_, __LINE__))

// Internal macro for checking the type and range of a subfield definition.
#define HWREG_INTERNAL_CHECK_SUBFIELD(FIELD, BIT_HIGH, BIT_LOW)                                  \
  static_assert(                                                                                 \
      hwreg::internal::IsSupportedInt<typename std::remove_reference_t<decltype(FIELD)>>::value, \
      #FIELD " has unsupported type");                                                           \
  static_assert((BIT_HIGH) >= (BIT_LOW), "Upper bit goes before lower bit");                     \
  static_assert((BIT_HIGH) < sizeof(decltype(FIELD)) * CHAR_BIT, "Upper bit is out of range");

namespace hwreg {

struct EnablePrinter;

namespace internal {

template <typename T>
struct IsSupportedInt : std::false_type {};
template <>
struct IsSupportedInt<uint8_t> : std::true_type {};
template <>
struct IsSupportedInt<uint16_t> : std::true_type {};
template <>
struct IsSupportedInt<uint32_t> : std::true_type {};
template <>
struct IsSupportedInt<uint64_t> : std::true_type {};

template <class IntType>
constexpr IntType ComputeMask(uint32_t num_bits) {
  if (num_bits == sizeof(IntType) * CHAR_BIT) {
    return static_cast<IntType>(~0ull);
  }
  return static_cast<IntType>((static_cast<IntType>(1) << num_bits) - 1);
}

// Unfortunately, some register layouts conditionally define the same field in
// different locations (e.g., PAT in x86 page table entries)! This type is a
// version of std::enable_if that helps us to support such cases. Using a naive
// SFINAE approach that wraps getter/setter return types with
// `std::enable_if_t<COND, ...>` across complementary values of COND would
// result in method redeclaration. What EnableIf adds is a trivial
// parameterization by a bit range that makes the compiler treat these as
// different return signatures, a difference that compiles away.
template <bool Cond, typename T, unsigned int HighBit, unsigned int LowBit>
struct enable_if {
  using type = std::enable_if_t<Cond, T>;
};

template <bool Cond, typename T, unsigned int HighBit, unsigned int LowBit>
using enable_if_t = typename enable_if<Cond, T, HighBit, LowBit>::type;

class FieldPrinter {
 public:
  constexpr FieldPrinter() : name_(nullptr), bit_high_incl_(0), bit_low_(0) {}
  constexpr FieldPrinter(const char* name, uint32_t bit_high_incl, uint32_t bit_low)
      : name_(name), bit_high_incl_(bit_high_incl), bit_low_(bit_low) {}

  // Prints the field name, and the result of extracting the field from |value| in
  // hex (with a left-padding of zeroes to a length matching the maximum number of
  // nibbles needed to represent any value the field could take).
  void Print(uint64_t value, char* buf, size_t len) const;

  constexpr auto name() const { return name_; }
  constexpr auto bit_high_incl() const { return bit_high_incl_; }
  constexpr auto bit_low() const { return bit_low_; }

 private:
  const char* name_;
  uint32_t bit_high_incl_;
  uint32_t bit_low_;
};

// Structure used to reduce the storage cost of the pretty-printing features if
// they are not enabled.
template <bool Enabled, typename IntType>
struct FieldPrinterList {
  void AppendField(const char* name, uint32_t bit_high_incl, uint32_t bit_low) {}
};

template <typename IntType>
struct FieldPrinterList<true, IntType> {
  // These two members are used for implementing the Print() function above.
  // They will typically be optimized away if Print() is not used.
  std::array<FieldPrinter, sizeof(IntType) * CHAR_BIT> fields;
  unsigned num_fields = 0;

  void AppendField(const char* name, uint32_t bit_high_incl, uint32_t bit_low) {
    ZX_DEBUG_ASSERT(num_fields < fields.size());
    fields[num_fields++] = FieldPrinter(name, bit_high_incl, bit_low);
  }
};

template <bool PrinterEnabled, typename ValueType>
struct FieldParameters {
  ValueType rsvdz_mask = 0;
  ValueType fields_mask = 0;

  __NO_UNIQUE_ADDRESS FieldPrinterList<PrinterEnabled, ValueType> printer;
};

// Used to record information about a field at construction time.  This enables
// checking for overlapping fields and pretty-printing.
// The UnusedMarker argument is to give each Field member its own type.  This,
// combined with __NO_UNIQUE_ADDRESS, allows the compiler to use no storage
// for the Field members.
template <class RegType, typename UnusedMarker, bool Enabled>
class Field {
 private:
  using IntType = typename RegType::ValueType;

 public:
  Field(FieldParameters<RegType::PrinterEnabled::value, IntType>* reg, const char* name,
        uint32_t bit_high_incl, uint32_t bit_low) {
    if constexpr (Enabled) {
      IntType mask = static_cast<IntType>(
          internal::ComputeMask<IntType>(bit_high_incl - bit_low + 1) << bit_low);
      // Check for overlapping bit ranges
      ZX_DEBUG_ASSERT((reg->fields_mask & mask) == 0ull);
      reg->fields_mask = static_cast<IntType>(reg->fields_mask | mask);

      reg->printer.AppendField(name, bit_high_incl, bit_low);
    }
  }
};

// Used to record information about reserved-zero fields at construction time.
// This enables auto-zeroing of reserved-zero fields on register write.
// Represents a field that must be zeroed on write.
// The UnusedMarker argument is to give each RsvdZField member its own type.
// This, combined with __NO_UNIQUE_ADDRESS, allows the compiler to use no
// storage for the RsvdZField members.
template <class RegType, typename UnusedMarker, bool Enabled>
class RsvdZField : public Field<RegType, UnusedMarker, Enabled> {
 private:
  using IntType = typename RegType::ValueType;

 public:
  RsvdZField(FieldParameters<RegType::PrinterEnabled::value, IntType>* reg, uint32_t bit_high_incl,
             uint32_t bit_low)
      : Field<RegType, UnusedMarker, Enabled>(reg, "RsvdZ", bit_high_incl, bit_low) {
    if constexpr (Enabled) {
      IntType mask = static_cast<IntType>(
          internal::ComputeMask<IntType>(bit_high_incl - bit_low + 1) << bit_low);
      reg->rsvdz_mask = static_cast<IntType>(reg->rsvdz_mask | mask);
    }
  }
};

// Implementation for RegisterBase::Print, see the documentation there.
// |reg_value| is the current value of the register.
// |fields_mask| is a bitmask with a bit set for each bit that has been defined
// in the register.
template <typename F>
void PrintRegister(F print_fn, FieldPrinter fields[], size_t num_fields, uint64_t reg_value,
                   uint64_t fields_mask, int register_width_bytes) {
  char buf[128];
  for (unsigned i = 0; i < num_fields; ++i) {
    fields[i].Print(reg_value, buf, sizeof(buf));
    print_fn(buf);
  }

  // Check if any unknown bits are set, and if so let the caller know
  uint64_t val = reg_value & ~fields_mask;
  if (val != 0) {
    int pad_len = (register_width_bytes * CHAR_BIT) / 4;
    snprintf(buf, sizeof(buf), "unknown set bits: 0x%0*" PRIx64, pad_len, val);
    buf[sizeof(buf) - 1] = 0;
    print_fn(buf);
  }
}

// Utility for the common print function of [](const char* arg) { printf("%s\n", arg); }
void PrintRegisterPrintf(FieldPrinter fields[], size_t num_fields, uint64_t reg_value,
                         uint64_t fields_mask, int register_width_bytes);

// The std::visit implementation is quite complicated and works in a way that
// relies on constexpr arrays of function pointers.  This is not reliably
// compiled to pure PIC as is required in some contexts like phys executables.
//
// This Visit provides a limited implementation that is much simpler.  It's
// less general than std::visit in that it doesn't handle return values or
// multiple arguments of variant types.  The first argument to the function
// must be the variant type, and any other arguments are forwarded perfectly.
//
// Visit also has two additional features over std::visit.  It works in the
// degenerate case where the first argument is not a std::variant type.  It
// also works "recursively", i.e. if the selected variant is itself another
// std::variant type, then Visit acts on the selected inner variant.

template <typename T>
constexpr bool IsVariant = false;

template <typename... Variants>
constexpr bool IsVariant<std::variant<Variants...>> = true;

// Forward declaration.
template <typename F, typename V, typename... A, size_t... I>
constexpr void VisitEach(F&& f, V&& v, A&&... args, std::index_sequence<I...>);

template <typename F, typename V, typename... A>
constexpr void Visit(F&& f, V&& v, A&&... args) {
  if constexpr (IsVariant<std::decay_t<V>>) {
    constexpr auto n = std::variant_size_v<std::decay_t<V>>;
    VisitEach(std::forward<F>(f), std::forward<V>(v), std::forward<A>(args)...,
              std::make_index_sequence<n>());
  } else {
    f(std::forward<V>(v), std::forward<A>(args)...);
  }
}

// Helper template for Visit, needed so it can use a fold expression across
// the variant indices.  Forward the remaining arguments to a Visit call using
// the selected variant.
template <typename F, typename V, typename... A, size_t... I>
constexpr void VisitEach(F&& f, V&& v, A&&... args, std::index_sequence<I...>) {
  static_assert(sizeof...(I) == std::variant_size_v<std::decay_t<V>>);
  [[maybe_unused]] bool visited_one =  // Statically always true.
      ((v.index() == I
            // Exactly one of these Visit calls will be evaluated.
            ? (Visit(std::forward<F>(f), std::get<I>(std::forward<V>(v)), std::forward<A>(args)...),
               true)
            : false) ||
       ...);
  ZX_DEBUG_ASSERT(visited_one);
}

// This is used in the implementation of hwreg::AtomicArrayIo.
template <typename ElementType, std::memory_order MemoryOrder>
class AtomicArrayIoRef {
 public:
  AtomicArrayIoRef(const AtomicArrayIoRef&) = default;

  explicit AtomicArrayIoRef(ElementType& ref) : ref_(ref) {}

  AtomicArrayIoRef& operator=(ElementType value) {
    ref_.store(value, MemoryOrder);
    return *this;
  }

  explicit operator ElementType() const { return ref_.load(MemoryOrder); }

  ElementType fetch_add(ElementType n) { return ref_.fetch_add(n, MemoryOrder); }

  ElementType fetch_sub(ElementType n) { return ref_.fetch_sub(n, MemoryOrder); }

  ElementType fetch_and(ElementType bits) { return ref_.fetch_and(bits, MemoryOrder); }

  ElementType fetch_or(ElementType bits) { return ref_.fetch_or(bits, MemoryOrder); }

  ElementType fetch_xor(ElementType bits) { return ref_.fetch_xor(bits, MemoryOrder); }

 private:
  cpp20::atomic_ref<ElementType> ref_;
};

}  // namespace internal

}  // namespace hwreg

#endif  // HWREG_INTERNAL_H_
