// Copyright 2020 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 LIB_UART_UART_H_
#define LIB_UART_UART_H_

#include <lib/arch/intrin.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <zircon/assert.h>
#include <zircon/boot/driver-config.h>
#include <zircon/boot/image.h>

#include <cstdlib>
#include <optional>
#include <string_view>
#include <type_traits>
#include <utility>

#include <hwreg/mmio.h>
#include <hwreg/pio.h>

#include "chars-from.h"

namespace uart {

// This template is specialized by payload configuration type (see below).
// It parses bits out of strings from the "kernel.serial" boot option.
template <typename Config>
inline std::optional<Config> ParseConfig(std::string_view) {
  static_assert(std::is_void_v<Config>, "missing specialization");
  return {};
}

// This template is specialized by payload configuration type (see below).
// It recreates a string for Parse.
template <typename Config>
inline void UnparseConfig(const Config& config, FILE* out) {
  static_assert(std::is_void_v<Config>, "missing specialization");
}

// Specific hardware support is implemented in a class uart::xyz::Driver,
// referred to here as UartDriver.  The uart::DriverBase template class
// provides a helper base class for UartDriver implementations.
//
// The UartDriver object represents the hardware itself.  Many UartDriver
// classes hold no state other than the initial configuration data used in the
// constructor, but a UartDriver is not required to be stateless.  However, a
// UartDriver is required to be copy-constructible, trivially destructible,
// and contain no pointers.  This makes it safe to copy an object set up by
// physboot into a new object in the virtual-memory kernel to hand off the
// configuration and the state of the hardware.
//
// All access to the UartDriver object is serialized by its caller, so it does
// no synchronization of its own.  This serves to serialize the actual access
// to the hardware.
//
// The UartDriver API fills four roles:
//  1. Match a ZBI item that configures this driver.
//  2. Generate a ZBI item for another kernel to match this configuration.
//  3. Configure the IoProvider (see below).
//  4. Drive the actual hardware.
//
// The first three are handled by DriverBase.  The KdrvExtra and KdrvConfig
// template arguments give the KDRV_* value and the dcfg_*_t type for the ZBI
// item.  The Pio template argument tells the IoProvider whether this driver
// uses MMIO or PIO (including PIO via MMIO): the number of consecutive PIO
// ports used, or 0 for simple MMIO.
//
// Item matching is done by the MaybeCreate static method.  If the item
// matches KdrvExtra, then the UartDriver(KdrvConfig) constructor is called.
// DriverBase provides this constructor to fill the cfg_ field, which the
// UartDriver can then refer to.  The UartDriver copy constructor copies it.
//
// The calls to drive the hardware are all template functions passed an
// IoProvider object (see below).  The driver accesses device registers using
// hwreg ReadFrom and WriteTo calls on the pointers from the provider.  The
// IoProvider constructed is passed uart.config() and uart.pio_size().
//
template <typename Driver, uint32_t KdrvExtra, typename KdrvConfig, uint16_t Pio = 0>
class DriverBase {
 public:
  using config_type = KdrvConfig;

  DriverBase() = delete;

  DriverBase(const DriverBase&) = default;

  explicit DriverBase(const config_type& cfg) : cfg_(cfg) {}

  constexpr bool operator==(const Driver& other) const {
    return memcmp(&cfg_, &other.cfg_, sizeof(cfg_)) == 0;
  }
  constexpr bool operator!=(const Driver& other) const { return !(*this == other); }

  // API to fill a ZBI item describing this UART.
  constexpr uint32_t type() const { return ZBI_TYPE_KERNEL_DRIVER; }
  constexpr uint32_t extra() const { return KdrvExtra; }
  constexpr size_t size() const { return sizeof(cfg_); }
  void FillItem(void* payload) const { memcpy(payload, &cfg_, sizeof(cfg_)); }

  // API to match a ZBI item describing this UART.
  static std::optional<Driver> MaybeCreate(const zbi_header_t& header, const void* payload) {
    static_assert(alignof(config_type) <= ZBI_ALIGNMENT);
    if (header.type == ZBI_TYPE_KERNEL_DRIVER && header.extra == KdrvExtra &&
        header.length >= sizeof(config_type)) {
      return Driver{*reinterpret_cast<const config_type*>(payload)};
    }
    return {};
  }

  // API to match a configuration string.
  static std::optional<Driver> MaybeCreate(std::string_view string) {
    const auto config_name = Driver::config_name();
    if (string.substr(0, config_name.size()) == config_name) {
      string.remove_prefix(config_name.size());
      auto config = ParseConfig<KdrvConfig>(string);
      if (config) {
        return Driver{*config};
      }
    }
    return {};
  }

  // API to reproduce a configuration string.
  void Unparse(FILE* out) const {
    fprintf(out, "%.*s", static_cast<int>(Driver::config_name().size()),
            Driver::config_name().data());
    UnparseConfig<KdrvConfig>(cfg_, out);
  }

  // API for use in IoProvider setup.
  const config_type& config() const { return cfg_; }
  constexpr uint16_t pio_size() const { return Pio; }

 protected:
  config_type cfg_;

 private:
  template <typename T>
  static constexpr bool Uninstantiated = false;

  // uart::KernelDriver API
  //
  // These are here just to cause errors if Driver is missing its methods.
  // They also serve to document the API required by uart::KernelDriver.
  // They should all be overridden by Driver methods.
  //
  // Each method is a template parameterized by an hwreg-compatible type for
  // accessing the hardware registers via hwreg ReadFrom and WriteTo methods.
  // This lets Driver types be used with hwreg::Mock in tests independent of
  // actual hardware access.

  template <typename IoProvider>
  void Init(IoProvider& io) {
    static_assert(Uninstantiated<IoProvider>, "derived class is missing Init");
  }

  // Return true if Write can make forward progress right now.
  // The return value can be anything contextually convertible to bool.
  // The value will be passed on to Write.
  template <typename IoProvider>
  bool TxReady(IoProvider& io) {
    static_assert(Uninstantiated<IoProvider>, "derived class is missing TxReady");
    return false;
  }

  // This is called only when TxReady() has just returned something that
  // converts to true; that's passed here so it can convey more information
  // such as a count.  Advance the iterator at least one and as many as is
  // convenient but not past end, outputting each character before advancing.
  template <typename IoProvider, typename It1, typename It2>
  auto Write(IoProvider& io, bool ready, It1 it, const It2& end) {
    static_assert(Uninstantiated<IoProvider>, "derived class is missing Write");
    return end;
  }

  // Poll for an incoming character and return one if there is one.
  template <typename IoProvider>
  std::optional<uint8_t> Read(IoProvider& io) {
    static_assert(Uninstantiated<IoProvider>, "derived class is missing Read");
    return {};
  }

  // Set the UART up to deliver interrupts.  This is called after Init.
  // After this, Interrupt (below) may be called from interrupt context.
  template <typename IoProvider>
  void InitInterrupt(IoProvider& io) {
    static_assert(Uninstantiated<IoProvider>, "derived class is missing InitInterrupt");
  }

  // Enable transmit interrupts so Interrupt will be called when TxReady().
  template <typename IoProvider>
  void EnableTxInterrupt(IoProvider& io) {
    static_assert(Uninstantiated<IoProvider>, "derived class is missing EnableTxInterrupt");
  }

  // Service an interrupt.  Call tx() if transmit has become ready.
  // If receive has become ready, call rx(read_char, full) one or more
  // times, where read_char() -> uint8_t if there is receive buffer
  // space and full() -> void if there is no space.
  template <typename IoProvider, typename Tx, typename Rx>
  void Interrupt(IoProvider& io, Tx&& tx, Rx&& rx) {
    static_assert(Uninstantiated<IoProvider>, "derived class is missing Interrupt");
  }
};

// The IoProvider is a template class parameterized by UartDriver::config_type,
// i.e. the dcfg_*_t type for the ZBI item's format.  This class is responsible
// for supplying pointers to be passed to hwreg types' ReadFrom and WriteTo.
//
// The IoProvider(UartDriver::config_type, uint16_t pio_size) constructor
// initializes the object.  Then IoProvider::io() is called to yield the
// pointer to pass to hwreg calls.
//
// uart::BasicIoProvider handles the simple case where physical MMIO and PIO
// base addresses are used directly.  It also provides base classes that can be
// subclassed with an overridden constructor that does address mapping.
//
template <typename Config>
class BasicIoProvider;

// This is the default "identity mapping" callback for BasicIoProvider::Init.
// A subclass can have an Init function that calls BasicIoProvider::Init with
// a different callback function.
inline auto DirectMapMmio(uint64_t phys) { return reinterpret_cast<volatile void*>(phys); }

// The specialization used most commonly handles simple MMIO devices.
template <>
class BasicIoProvider<dcfg_simple_t> {
 public:
  // Just install the MMIO base pointer.  The third argument can be passed by
  // a subclass constructor method to map the physical address to a virtual
  // address.
  template <typename T>
  BasicIoProvider(const dcfg_simple_t& cfg, uint16_t pio_size, T&& map_mmio) {
    auto ptr = map_mmio(cfg.mmio_phys);
    if (pio_size != 0) {
      // This is PIO via MMIO, i.e. scaled MMIO.
      io_.emplace<hwreg::RegisterPio>(ptr);
    } else {
      // This is normal MMIO.
      io_.emplace<hwreg::RegisterMmio>(ptr);
    }
  }
  BasicIoProvider(const dcfg_simple_t& cfg, uint16_t pio_size)
      : BasicIoProvider(cfg, pio_size, DirectMapMmio) {}

  auto* io() { return &io_; }

 private:
  std::variant<hwreg::RegisterMmio, hwreg::RegisterPio> io_{std::in_place_index<0>, nullptr};
};

// The specialization for devices using actual PIO only occurs on x86.
#if defined(__x86_64__) || defined(__i386__)
template <>
class BasicIoProvider<dcfg_simple_pio_t> {
 public:
  BasicIoProvider(const dcfg_simple_pio_t& cfg, uint16_t pio_size) : io_(cfg.base) {
    ZX_DEBUG_ASSERT(pio_size > 0);
  }

  auto* io() { return &io_; }

 private:
  hwreg::RegisterDirectPio io_;
};
#endif

// The specialization for devices requiring two separate MMIO areas
// provides an additional entry point for the second one.
template <>
class BasicIoProvider<dcfg_soc_uart_t> {
 public:
  // The third argument can be passed by a subclass's constructor.
  template <typename T>
  BasicIoProvider(const dcfg_soc_uart_t& cfg, uint16_t pio_size, T&& map_mmio)
      : soc_mmio_(map_mmio(cfg.soc_mmio_phys)), uart_mmio_(map_mmio(cfg.uart_mmio_phys)) {
    ZX_DEBUG_ASSERT(pio_size == 0);
  }
  BasicIoProvider(const dcfg_soc_uart_t& cfg, uint16_t pio_size)
      : BasicIoProvider(cfg, pio_size, DirectMapMmio) {}

  auto* io() { return &uart_mmio_; }

  auto* soc_io() { return &soc_mmio_; }

 private:
  hwreg::RegisterMmio soc_mmio_, uart_mmio_;
};

// The Sync class provides synchronization around the UartDriver.
//
// This is the degenerate case of the uart::KernelDriver Sync API.
// It busy-waits with no locking.
struct TA_CAP("uart") Unsynchronized {
  // This is returned by lock() and passed back to unlock().
  struct InterruptState {};

  // The Sync object is normally default-constructed.
  Unsynchronized() = default;

  // The constructor argument is the UartDriver object.  This is only used
  // by uart::mock::Sync so other implementations use a template just to
  // ignore the argument without specializing the whole class on its type.
  template <typename T>
  explicit Unsynchronized(const T&) {}

  // This is the normal pair, used in "process context", i.e. where
  // interrupts might happen.  unlock takes the state returned by lock.
  [[nodiscard]] const InterruptState lock() TA_ACQ() { return {}; }
  void unlock(InterruptState) TA_REL() {}

  // Wait for a good time to check again.  Implementations that actually
  // block pending an interrupt first call enable_tx_interrupt(), then
  // unlock to block, and finally relock when woken before return.
  template <typename T>
  InterruptState Wait(InterruptState, T&& enable_tx_interrupt) TA_REQ(this) {
    arch::Yield();
    return {};
  }

  // In blocking implementations, the interrupt handler calls this.  It should
  // statically never be reached in an instantiation using this implementation,
  // but static_assert for that only works in templates.
  void Wake() TA_REQ(this) { ZX_PANIC("uart::Unsynchronized::Wake() should never be called"); }
};

// Forward declaration.
namespace mock {
class Driver;
}

// The KernelDriver template class is parameterized by those three to implement
// actual driver logic for some environment.
//
// The KernelDriver constructor just passes its arguments through to the
// UartDriver constructor.  So it can be created directly from a configuration
// struct or copied from another UartDriver object.  In this way, the device is
// handed off from one KernelDriver instantiation to a different one using a
// different IoProvider (physboot vs kernel) and/or Sync (polling vs blocking).
//
template <class UartDriver, template <typename> class IoProvider, class Sync>
class KernelDriver {
 public:
  using uart_type = UartDriver;
  static_assert(std::is_copy_constructible_v<uart_type>);
  static_assert(std::is_trivially_destructible_v<uart_type> ||
                std::is_same_v<uart_type, mock::Driver>);

  // This sets up the object but not the device itself.  The device might
  // already have been set up by a previous instantiation's Init function,
  // or might never actually be set up because this instantiation gets
  // replaced with a different one before ever calling Init.
  template <typename... Args>
  explicit KernelDriver(Args&&... args)
      : uart_(std::forward<Args>(args)...), io_(uart_.config(), uart_.pio_size()) {}

  // Access underlying hardware driver object.
  const auto& uart() const { return uart_; }
  auto& uart() { return uart_; }

  // Access IoProvider object.
  auto& io() { return io_; }

  // Set up the device for nonblocking output and polling input.
  // If the device is handed off from a different instantiation,
  // this won't be called in the new instantiation.
  void Init() {
    Guard lock(sync_);
    uart_.Init(io_);
  }

  // TODO(mcgrathr): Add InitInterrupt for enabling interrupt-based i/o.

  // This is the FILE-compatible API: `FILE::stdout_ = FILE{&driver};`.
  int Write(std::string_view str) {
    uart::CharsFrom chars(str);  // Massage into uint8_t with \n -> CRLF.
    auto it = chars.begin();
    Guard lock(sync_);
    while (it != chars.end()) {
      // Wait until the UART is ready for Write.
      auto ready = uart_.TxReady(io_);
      while (!ready) {
        // Block or just unlock and spin or whatever "wait" means to Sync.
        // If that means blocking for interrupt wakeup, enable tx interrupts.
        lock.Wait([this]() TA_REQ(sync_) { uart_.EnableTxInterrupt(io_); });
        ready = uart_.TxReady(io_);
      }
      // Advance the iterator by writing some.
      it = uart_.Write(io_, std::move(ready), it, chars.end());
    }
    return static_cast<int>(str.size());
  }

  // This is a direct polling read, not used in interrupt-based operation.
  auto Read() {
    Guard lock(sync_);
    return uart_.Read(io_);
  }

 private:
  friend Sync;
  uart_type uart_ TA_GUARDED(sync_);
  IoProvider<typename uart_type::config_type> io_;
  Sync sync_{uart_};

  class TA_SCOPED_CAP Guard {
   public:
    template <typename... T>
    __WARN_UNUSED_CONSTRUCTOR explicit Guard(Sync& sync, T... args) TA_ACQ(sync) TA_ACQ(sync_)
        : sync_(sync), state_(sync_.lock(std::forward<T>(args)...)) {}

    ~Guard() TA_REL() { sync_.unlock(std::move(state_)); }

    template <typename T>
    void Wait(T&& enable) TA_REQ(sync_) {
      state_ = sync_.Wait(std::move(state_), std::forward<T>(enable));
    }

    void Wake() TA_REQ(sync_) { sync_.Wake(); }

   private:
    Sync& sync_;
    typename Sync::InterruptState state_;
  };
};

// These specializations are defined in the library to cover all the ZBI item
// payload types used by the various drivers.

template <>
std::optional<dcfg_simple_t> ParseConfig<dcfg_simple_t>(std::string_view string);

template <>
void UnparseConfig(const dcfg_simple_t& config, FILE* out);

template <>
std::optional<dcfg_simple_pio_t> ParseConfig<dcfg_simple_pio_t>(std::string_view string);

template <>
void UnparseConfig(const dcfg_simple_pio_t& config, FILE* out);

template <>
std::optional<dcfg_soc_uart_t> ParseConfig<dcfg_soc_uart_t>(std::string_view string);

template <>
void UnparseConfig(const dcfg_soc_uart_t& config, FILE* out);

}  // namespace uart

#endif  // LIB_UART_UART_H_
