// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <lib/boot-options/boot-options.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <platform.h>
#include <reg.h>
#include <string.h>
#include <zircon/boot/driver-config.h>
#include <zircon/types.h>

#include <arch/arm64/periphmap.h>
#include <kernel/lockdep.h>
#include <kernel/spinlock.h>
#include <kernel/timer.h>
#include <pdev/driver.h>
#include <pdev/watchdog.h>
#include <vm/physmap.h>

class GenericWatchdog32 {
 public:
  constexpr GenericWatchdog32() {}

  // TODO(johngro) : for now, don't actually declare a destructor.  We don't
  // want to end up registering a global .dtor for no reason.  If/when we get to
  // the point where the kernel can actually "exit" for sanitizer analysis, we
  // will want to come back here and enable this.
  //~GenericWatchdog32() { pet_timer_.Cancel(); }

  // Early init takes place while we are still single threaded, and don't need
  // to worry about thread safety.
  void InitEarly(const void* driver_data, uint32_t length);
  void Init(const void*, uint32_t);

  // Actions
  void Pet() TA_EXCL(lock_) {
    Guard<SpinLock, IrqSave> guard{&lock_};
    PetLocked();
  }

  zx_status_t SetEnabled(bool enb) TA_EXCL(lock_) {
    Guard<SpinLock, IrqSave> guard{&lock_};

    // Nothing to do if we are already in the desired state.
    if (enb == is_enabled_) {
      return ZX_OK;
    }

    if (!(enb ? cfg_.enable_action.addr : cfg_.disable_action.addr)) {
      return ZX_ERR_NOT_SUPPORTED;
    }

    is_enabled_ = enb;

    if (is_enabled_) {
      // Enable the timer, then immediately pet the watchdog, and set up the pet
      // timer.
      TakeAction(cfg_.enable_action);
      HandlePetTimer();
    } else {
      // Disable the watchdog and cancel any in-flight timer.
      TakeAction(cfg_.disable_action);
      pet_timer_.Cancel();
    }

    return ZX_OK;
  }

  // Accessors
  zx_duration_t timeout_nsec() const { return cfg_.watchdog_period_nsec; }
  bool is_enabled() const TA_EXCL(lock_) {
    Guard<SpinLock, IrqSave> guard{&lock_};
    return is_enabled_;
  }

  zx_time_t last_pet_time() const TA_EXCL(lock_) {
    Guard<SpinLock, IrqSave> guard{&lock_};
    return last_pet_time_;
  }

  void SuppressPetting(bool suppress) TA_EXCL(lock_) {
    Guard<SpinLock, IrqSave> guard{&lock_};
    is_petting_suppressed_ = suppress;
  }

  bool IsPettingSuppressed() const TA_EXCL(lock_) {
    Guard<SpinLock, IrqSave> guard{&lock_};
    return is_petting_suppressed_;
  }

 private:
  static bool TranslatePAddr(uint64_t* paddr);
  void TakeAction(const dcfg_generic_32bit_watchdog_action_t& action) TA_REQ(lock_) {
    uint32_t val = readl(action.addr);
    val &= ~action.clr_mask;
    val |= action.set_mask;
    writel(val, action.addr);
  }

  zx_time_t PetLocked() TA_REQ(lock_) {
    // Even if petting is suppressed, take a look at the time just before the
    // pet was supposed to happen.  This is the value we will use when computing
    // the next pet timer, instead of basing it on the last_pet_time_.  This is
    // important because we want the last_pet_time_ to reflect the last time we
    // _actually_ pet the dog, but if we use it to schedule our next timer
    // deadline, we might end up scheduling our timers in the past, causing our
    // core to get stuck in its timer handler.
    zx_time_t now = current_time();
    if (!is_petting_suppressed_) {
      last_pet_time_ = now;
      TakeAction(cfg_.pet_action);
    }
    return now;
  }
  void HandlePetTimer() TA_REQ(lock_);
  void PretendLocked() TA_ASSERT(lock_) {}

  mutable DECLARE_SPINLOCK(GenericWatchdog32) lock_;
  dcfg_generic_32bit_watchdog_t cfg_{};
  zx_status_t early_init_result_ = ZX_ERR_INTERNAL;
  zx_time_t last_pet_time_ TA_GUARDED(lock_) = 0;
  Timer pet_timer_ TA_GUARDED(lock_);
  bool is_enabled_ TA_GUARDED(lock_) = false;
  bool is_petting_suppressed_ TA_GUARDED(lock_) = false;
};

static GenericWatchdog32 g_watchdog;

static const pdev_watchdog_ops_t THUNKS = {
    .pet = []() { g_watchdog.Pet(); },
    .set_enabled = [](bool enb) { return g_watchdog.SetEnabled(enb); },
    .is_enabled = []() { return g_watchdog.is_enabled(); },
    .get_timeout_nsec = []() { return g_watchdog.timeout_nsec(); },
    .get_last_pet_time = []() { return g_watchdog.last_pet_time(); },
    .suppress_petting = [](bool suppress) { g_watchdog.SuppressPetting(suppress); },
    .is_petting_suppressed = []() -> bool { return g_watchdog.IsPettingSuppressed(); },
};

void GenericWatchdog32::InitEarly(const void* driver_data, uint32_t length) {
  // "Assert" that we are holding the lock.  While this is technically a no-op,
  // it tells the thread analyzer to pretend that we are holding the lock.  We
  // are in the early init stage of boot, so it is too early to need to worry
  // about multi-thread safety issues, but we don't want to actually be
  // obtaining and releasing the spin lock at this point.  Along with the
  // annotations in the class, pretending that we are holding the lock at this
  // point in time will make certain that we are following all of the locking
  // rules.
  PretendLocked();

  // Sanity check our config first.  If they are invalid, we cannot proceed
  // (and if the watchdog is already enable, we are gonna end up rebooting).
  //
  // Sadly, it is too early to do any logging.  If we manage to make it to the
  // PLATFORM init level, we will log the errors there.

  // We must have config, and that config must be of the proper length.  If that
  // checks out, go ahead and copy the config.
  if ((driver_data == nullptr) || (length != sizeof(cfg_))) {
    early_init_result_ = ZX_ERR_INVALID_ARGS;
    return;
  }
  memcpy(&cfg_, driver_data, sizeof(cfg_));

  // All generic watchdog drivers must have some way of petting the dog.
  // Enable/disable is optional, but not petting.
  if (!cfg_.pet_action.addr) {
    early_init_result_ = ZX_ERR_INVALID_ARGS;
    return;
  }

  // The watchdog period must be at least 1 mSec.  We don't want to spend 15% of
  // our CPU petting the watchdog all of the time.
  if (cfg_.watchdog_period_nsec < KDRV_GENERIC_32BIT_WATCHDOG_MIN_PERIOD) {
    early_init_result_ = ZX_ERR_INVALID_ARGS;
    return;
  }

  // Great! Things look good.  Translate the physical addresses for the various
  // actions to virtual addresses.  If we cannot translate the pet address, we
  // have a problem.  If we cannot translate the enable or disable address, then
  // so be it.  That functionality will be unavailable, but at least we can pet
  // the dog.
  if (!TranslatePAddr(&cfg_.pet_action.addr)) {
    early_init_result_ = ZX_ERR_IO;
  }

  TranslatePAddr(&cfg_.enable_action.addr);
  TranslatePAddr(&cfg_.disable_action.addr);

  // Record our initial enabled/disabled state.
  is_enabled_ = (cfg_.flags & KDRV_GENERIC_32BIT_WATCHDOG_FLAG_ENABLED) != 0;

  // If we are currently enabled, be sure to pet the dog ASAP.  We don't want it
  // to fire while we are bringing up the kernel to the point where we can do
  // stuff like set timers.  In addition, if the cmd-line flag was passed to
  // force disable the watchdog, do so if possible just after we have pet it.
  PetLocked();
  if (gBootOptions->force_watchdog_disabled && is_enabled_ && cfg_.disable_action.addr) {
    TakeAction(cfg_.disable_action);
    is_enabled_ = false;
  }

  // Register our driver.  Note that the pdev layer is going to hold onto our
  // thunk table, not make a copy.  We need to be sure that we don't let our
  // table go out of scope (which is why it is file local).
  pdev_register_watchdog(&THUNKS);

  // Things went well.  Make sure the later init stage knows that.
  early_init_result_ = ZX_OK;
}

void GenericWatchdog32::Init(const void*, uint32_t) {
  Guard<SpinLock, IrqSave> guard{&lock_};

  // Ok, we are much farther along in the boot now.  We should be able to do
  // things like report errors and set timers at this point.  Start by checking
  // out how things went during early init.  If things went poorly, try to log
  // why.  Hopefully the watchdog is currently disabled, or we are going to
  // reboot Real Soon Now(tm).
  if (early_init_result_ != ZX_OK) {
    dprintf(
        INFO,
        "WDT: Generic watchdog driver attempted to load, but failed during early init (res %d).\n",
        early_init_result_);
    return;
  }

  // Report that the driver has successfully loaded, along with some handy info
  // about the hardware state.
  dprintf(INFO, "WDT: Generic watchdog driver loaded.  Period (%ld.%03ld mSec) Enabled (%s)\n",
          timeout_nsec() / ZX_MSEC(1), (timeout_nsec() % ZX_MSEC(1)) / ZX_USEC(1),
          is_enabled_ ? "yes" : "no");

  // If the force disable cmd line flag was passed, report that here.
  if (gBootOptions->force_watchdog_disabled) {
    if (cfg_.disable_action.addr) {
      dprintf(INFO, "WDT: %s was set, watchdog was force-disabled\n",
              kForceWatchdogDisabledName.data());
    } else {
      dprintf(INFO,
              "WDT: %s was set, but the watchdog cannot be disabled.  It is "
              "currently %s.\n",
              kForceWatchdogDisabledName.data(), is_enabled_ ? "enabled" : "disabled");
    }
  }

  // If we are enabled, pet the dog now and set our pet timer.
  HandlePetTimer();
}

void GenericWatchdog32::HandlePetTimer() {
  if (is_enabled_) {
    zx_time_t next_pet_time = zx_time_add_duration(PetLocked(), timeout_nsec() / 2);
    Deadline next_pet_deadline{next_pet_time, {(timeout_nsec() / 4), TIMER_SLACK_EARLY}};
    pet_timer_.Set(
        next_pet_deadline,
        [](Timer*, zx_time_t now, void* arg) {
          auto thiz = reinterpret_cast<GenericWatchdog32*>(arg);
          Guard<SpinLock, IrqSave> guard{&thiz->lock_};
          thiz->HandlePetTimer();
        },
        this);
  }
}

bool GenericWatchdog32::TranslatePAddr(uint64_t* paddr) {
  // Translate a register's physical address to a virtual address so we can read
  // and write it.  If we cannot, for some reason, return an error.  If the
  // address is already nullptr, just leave it that way.  This is not an error,
  // it just means that the register for this action is not available.
  if (*paddr == 0) {
    return true;
  }

  *paddr = periph_paddr_to_vaddr(static_cast<paddr_t>(*paddr));

  return (*paddr != 0);
}

LK_PDEV_INIT(
    generic_32bit_watchdog_init_early, KDRV_GENERIC_32BIT_WATCHDOG,
    [](const void* driver_data, uint32_t length) { g_watchdog.InitEarly(driver_data, length); },
    LK_INIT_LEVEL_PLATFORM_EARLY)
LK_PDEV_INIT(
    generic_32bit_watchdog_init, KDRV_GENERIC_32BIT_WATCHDOG,
    [](const void* driver_data, uint32_t length) { g_watchdog.Init(driver_data, length); },
    LK_INIT_LEVEL_PLATFORM)
