// 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 acpi_lite {
struct AcpiDebugPortDescriptor;
}

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;

  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 match DBG2 Table (ACPI). Currently only 16550 compatible uarts are supported.
  static std::optional<Driver> MaybeCreate(const acpi_lite::AcpiDebugPortDescriptor& debug_port) {
    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) : pio_size_(pio_size) {
    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) {}

  BasicIoProvider& operator=(BasicIoProvider&& other) {
    io_.swap(other.io_);
    pio_size_ = other.pio_size_;
    return *this;
  }

  auto* io() { return &io_; }

  uint16_t pio_size() const { return pio_size_; }

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

// 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 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_);
  }

  // Configure the UART line control settings.
  //
  // TODO(fxbug.dev/102726): Give more freedom in setting the controls.
  void SetLineControl() {
    // TODO(fxbug.dev/102726): Set it on all variants.
    if constexpr (kCanSetLineControl) {
      Guard lock(sync_);
      uart_.Init(io_);
      uart_.SetLineControl(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_;
  };

  // SFINAE check for a UartType::SetLineControl method.
  template <typename UartType = uart_type,
            typename = decltype(std::declval<UartType>().SetLineControl())>
  static constexpr bool SfinaeSetLineControl(int ignored) {
    return true;
  }

  // This overload is chosen only if SFINAE detected a missing SetLineControl method.
  static constexpr bool SfinaeSetLineControl(...) { return false; }

  static constexpr bool kCanSetLineControl = SfinaeSetLineControl(0);
};

// 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);

}  // namespace uart

#endif  // LIB_UART_UART_H_
