// Copyright 2017 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 <inttypes.h>
#include <lib/console.h>
#include <lib/counters.h>
#include <lib/zbi-format/driver-config.h>
#include <string.h>
#include <trace.h>

#include <arch/arm64.h>
#include <arch/arm64/smccc.h>
#include <dev/psci.h>
#include <ktl/atomic.h>
#include <pdev/power.h>
#include <vm/handoff-end.h>

#define LOCAL_TRACE 0

namespace {

bool psci_set_suspend_mode_supported = false;

// The number of PSCI CPU_SUSPEND calls that completed successfully and resulted in a powered down
// state.
KCOUNTER(counter_psci_cpu_suspend_powered_down, "psci.cpu_suspend.ok.powered_down")

// The number of PSCI CPU_SUSPEND calls that completed successfully, but where state was retained
// (i.e. did not reach a powered down state for whatever reason).
KCOUNTER(counter_psci_cpu_suspend_retained, "psci.cpu_suspend.ok.retained")

// The number of PSCI CPU_SUSPEND calls that failed with PSCI_INVALID_PARAMETERS.
KCOUNTER(counter_psci_cpu_suspend_invalid_parameters, "psci.cpu_suspend.invalid_parameters")

// The number of PSCI CPU_SUSPEND calls that failed with PSCI_DENIED.
KCOUNTER(counter_psci_cpu_suspend_denied, "psci.cpu_suspend.psci_denied")

uint64_t shutdown_args[3] = {0, 0, 0};
uint64_t reboot_args[3] = {0, 0, 0};
uint64_t reboot_bootloader_args[3] = {0, 0, 0};
uint64_t reboot_recovery_args[3] = {0, 0, 0};
uint32_t reset_command = PSCI64_SYSTEM_RESET;

// Specifies which power_state format is used by this PSCI implementation.
enum class PowerStateFormat {
  Unknown,
  Original,  // Section 5.4.2.1 of "Arm Power State Coordination Interface", DEN0022F.b.
  Extended,  // Section 5.4.2.2 of "Arm Power State Coordination Interface", DEN0022F.b.
};
PowerStateFormat power_state_format;

// Returns true iff |power_state| is a "powerdown" power_state (as opposed to a
// standby or retention state).
bool psci_is_powerdown_power_state(uint32_t power_state) {
  switch (power_state_format) {
    case PowerStateFormat::Original:
      // In the original format, StateType is bit-16.  If StateType is 1, it's a powerdown state.
      return (power_state & (1 << 16)) != 0;
    case PowerStateFormat::Extended:
      // In the extended format, StateType is bit-30.
      return (power_state & (1 << 30)) != 0;
    default:
      panic("unknown power_state_format %u", static_cast<uint32_t>(power_state_format));
  };
}

// SuspendDomain has two jobs.  First, it keeps track of the CPUs that are part of a given "power
// domain" (in the PSCI CPU_SUSPEND sense).  Second, it provides the correct power state value for a
// given CPU_SUSPEND operation based on the current state of the domain.
//
// SuspendDomain is designed to handle race conditions associated with current CPU_SUSPEND
// operations that might otherwise result in the domain being "left on" when it should not be.
// Note, even with SuspendDomain, some race conditions exist, however, the PSCI implementation is
// designed to handle these by denying invalid CPU_SUSPEND requests with PSCI_DENIED.  See section
// 6.2 of "Arm Power State Coordination Interface", DEN0022F.b.
//
// When a CPU is powered on, it must be registered with its SuspendDomain instance.  Likewise, just
// before it's powered off, it must be unregistered.
//
// An instance of SuspendDomain is safe for concurrent use (i.e. it's thread-safe).
class SuspendDomain {
 public:
  SuspendDomain() = default;

  // Initializes this instance with the given, optional, power state values.  An instance must be
  // initialized exactly once.
  //
  // If no value is provided for |power_state_target_cpu|, suspend support will be disabled.  See
  // |IsCpuSuspendSupported|.
  //
  // It is an error to provide a value for |power_state_target_power_domain|, without also providing
  // a value for |power_state_target_cpu|.
  void Init(ktl::optional<uint32_t> power_state_target_cpu,
            ktl::optional<uint32_t> power_state_target_power_domain) {
    DEBUG_ASSERT(power_state_target_cpu.has_value() ||
                 !power_state_target_power_domain.has_value());

    DEBUG_ASSERT(target_cpu_ == ktl::nullopt);
    target_cpu_ = power_state_target_cpu;
    target_cpu_is_powerdown_state_ =
        target_cpu_.has_value() ? psci_is_powerdown_power_state(power_state_target_cpu.value())
                                : false;

    DEBUG_ASSERT(target_power_domain_ == ktl::nullopt);
    target_power_domain_ = power_state_target_power_domain;
    target_power_domain_is_powerdown_state_ =
        target_power_domain_.has_value()
            ? psci_is_powerdown_power_state(power_state_target_power_domain.value())
            : false;
  }

  // Registers a CPU with this instance.
  //
  // This method should be called once for each CPU shortly after it is powered on.
  void RegisterCpu() {
    [[maybe_unused]] uint32_t count = count_.fetch_add(1, ktl::memory_order_relaxed);
    DEBUG_ASSERT(count < SMP_MAX_CPUS);
  }

  // Unregisters a CPU with this instance.
  //
  // This method should be called once for each CPU just before it is powered off.
  void UnregisterCpu() {
    [[maybe_unused]] uint32_t count = count_.fetch_add(-1, ktl::memory_order_relaxed);
    DEBUG_ASSERT(count > 0);
  }

  // Returns true if PSCI CPU_SUSPEND is supported for this domain.
  //
  // Requirements for PSCI CPU_SUSPEND support:
  //
  // * The device has PSCI version 1.0 or better, and
  // * PSCI FEATURES reports that CPU_ CPU_SUSPEND is supported, and
  // * ZBI contains a supported CPU suspend state configuration.
  //
  // The ZBI-supplied CPU suspend state configuration is considered supported if it contains at
  // least one entry where:
  //
  //   * No unknown flags are specified, and
  //   * ZBI_ARM_PSCI_CPU_SUSPEND_STATE_FLAGS_TARGETS_POWER_DOMAIN is not set.
  bool IsCpuSuspendSupported() const { return target_cpu_.has_value(); }

  // Returns true if a call to CPU_SUSPEND might result in a powerdown state.
  bool SuspendMightPowerdown() const {
    return target_cpu_is_powerdown_state_ || target_power_domain_is_powerdown_state_;
  }

  // An RAII helper intended to be instantiated in a scope just before issuing a PSCI CPU_SUSPEND.
  // Used to obtain the "best" power state value given the number of currently
  // running-but-not-yet-suspended CPUs for the domain.
  //
  // E.g.
  //
  // {
  //   SuspendDomain::Guard(domain, max_scope);
  //   psci_do_suspend(..., guard.power_state(), ...);
  // }
  //
  class Guard {
   public:
    // Construct a Guard for the given |domain|.
    //
    // |max_scope| controls whether the value returned by |power_state()| applies to just the
    // calling CPU or to the enclosing power domain.
    Guard(SuspendDomain& domain, PsciCpuSuspendMaxScope max_scope);
    ~Guard();

    // Returns the "best" power state value for the PSCI CPU_SUSPEND in the calling scope.
    uint32_t power_state() const { return power_state_; }

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

   private:
    SuspendDomain& domain_;
    uint32_t power_state_;
  };

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

 private:
  friend class Guard;

  // When supported, this variable contains a power_state value to be passed in a CPU_SUSPEND call.
  // When not supported, this variable contains ktl::nullopt.
  ktl::optional<uint32_t> target_cpu_;

  // Optionally contains a PSCI CPU_SUSPEND power_state value that targets a power domain (think
  // cluster or whole system).  Will only contain a value if |target_cpu_| contains a value.
  ktl::optional<uint32_t> target_power_domain_;

  // The number of powered-on-but-not-suspended CPUs.
  ktl::atomic<uint32_t> count_{};

  // Whether |target_cpu_| is present and is a powerdown state.
  bool target_cpu_is_powerdown_state_{};

  // Whether |targetpower_domain_| is present and is a powerdown state.
  bool target_power_domain_is_powerdown_state_{};
};

SuspendDomain::Guard::Guard(SuspendDomain& domain, PsciCpuSuspendMaxScope max_scope)
    : domain_(domain) {
  DEBUG_ASSERT(domain.IsCpuSuspendSupported());

  uint32_t count = domain_.count_.fetch_add(-1, ktl::memory_order_relaxed);
  DEBUG_ASSERT(count >= 1);

  if (count == 1 && max_scope == PsciCpuSuspendMaxScope::CpuAndMore &&
      domain_.target_power_domain_.has_value()) {
    power_state_ = domain_.target_power_domain_.value();
  } else {
    DEBUG_ASSERT(domain_.target_cpu_.has_value());
    power_state_ = domain_.target_cpu_.value();
  }
}

SuspendDomain::Guard::~Guard() { domain_.count_.fetch_add(1, ktl::memory_order_relaxed); }

SuspendDomain gSuspendDomain;

zx_status_t psci_status_to_zx_status(uint64_t psci_result);
zx_status_t psci_status_to_zx_status(uint64_t psci_result) {
  int64_t status = static_cast<int64_t>(psci_result);
  switch (status) {
    case PSCI_SUCCESS:
      return ZX_OK;
    case PSCI_NOT_SUPPORTED:
    case PSCI_DISABLED:
      return ZX_ERR_NOT_SUPPORTED;
    case PSCI_INVALID_PARAMETERS:
      return ZX_ERR_INVALID_ARGS;
    case PSCI_INVALID_ADDRESS:
      return ZX_ERR_OUT_OF_RANGE;
    case PSCI_DENIED:
      return ZX_ERR_ACCESS_DENIED;
    case PSCI_ALREADY_ON:
      return ZX_ERR_BAD_STATE;
    case PSCI_ON_PENDING:
      return ZX_ERR_SHOULD_WAIT;
    case PSCI_INTERNAL_FAILURE:
      return ZX_ERR_INTERNAL;
    case PSCI_NOT_PRESENT:
      return ZX_ERR_NOT_FOUND;
    default:
      return ZX_ERR_BAD_STATE;
  }
}

uint64_t psci_smc_call(uint32_t function, uint64_t arg0, uint64_t arg1, uint64_t arg2) {
  LTRACEF("0x%x 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 "\n", function, arg0, arg1, arg2);
  return arm_smccc_smc(function, arg0, arg1, arg2, 0, 0, 0, 0).x0;
}

uint64_t psci_hvc_call(uint32_t function, uint64_t arg0, uint64_t arg1, uint64_t arg2) {
  return arm_smccc_hvc(function, arg0, arg1, arg2, 0, 0, 0, 0).x0;
}
using psci_call_proc = uint64_t (*)(uint32_t, uint64_t, uint64_t, uint64_t);

psci_call_proc do_psci_call = psci_smc_call;

// Parse and print |config|, setting the relevant global power state variables.
//
// Intended to be called once as part of |PsciInit| after |power_state_format| has bee set.
void parse_cpu_suspend_power_states(ktl::span<const zbi_dcfg_arm_psci_cpu_suspend_state_t> config) {
  DEBUG_ASSERT(power_state_format != PowerStateFormat::Unknown);

  if (config.empty()) {
    dprintf(INFO, "PSCI power_states: none\n");
    return;
  }

  constexpr uint32_t kKnownFlags = ZBI_ARM_PSCI_CPU_SUSPEND_STATE_FLAGS_LOCAL_TIMER_STOPS |
                                   ZBI_ARM_PSCI_CPU_SUSPEND_STATE_FLAGS_TARGETS_POWER_DOMAIN;

  dprintf(INFO, "PSCI power_state format: %s\n",
          power_state_format == PowerStateFormat::Original ? "original" : "extended");
  dprintf(INFO, "PSCI power_states:\n");

  ktl::optional<uint32_t> target_cpu;
  ktl::optional<uint32_t> target_power_domain;

  // Iterate over every element.  The elements are in no particular order.  The last-one-wins
  // behavior of this loop is somewhat arbitrary.
  for (const zbi_dcfg_arm_psci_cpu_suspend_state_t& elem : config) {
    // Ignore any power state that contains flags we don't know about as they may indicate a
    // requirement that must be met before invoking that power state.
    const bool skip = elem.flags & ~kKnownFlags;

    dprintf(INFO, "  id=0x%x, power_state=0x%x, flags=0x%x, powerdown=%d%s\n", elem.id,
            elem.power_state, elem.flags, psci_is_powerdown_power_state(elem.power_state),
            skip ? " SKIPPED" : "");
    dprintf(INFO, "    entry_latency_us=%u, exit_latency_us=%u, min_residency_us=%u\n",
            elem.entry_latency_us, elem.exit_latency_us, elem.min_residency_us);

    if (skip) {
      continue;
    }

    if ((elem.flags & ZBI_ARM_PSCI_CPU_SUSPEND_STATE_FLAGS_TARGETS_POWER_DOMAIN) == 0) {
      target_cpu = elem.power_state;
    } else {
      target_power_domain = elem.power_state;
    }
  }

  // Initialize the one and only suspend domain and register the calling CPU.
  gSuspendDomain.Init(target_cpu, target_power_domain);
  gSuspendDomain.RegisterCpu();
}

}  // anonymous namespace

// Saves register state in |context|, then issues a PSCI call, using
// |psci_call|, for the specified |psci_func|, passing along the supplied
// |power_state|, |entry|, and |context| arguments.
//
// This function is designed to be called with PSCI64_CPU_SUSPEND and work with
// |psci_do_resume| and |arm64_secondary_start|.
//
// In all cases, this function will always appear to return to its caller.
// Depending on the PSCI implementation and the conditions, it may do so
// directly, or in the case of a successful CPU_SUSPEND, it may do so via
// |arm64_secondary_start| and |psci_do_resume|.
//
// If the return value is less than or equal to zero, then control did not
// branch to |entry| and the return value should be interpreted as a PSCI return
// value (see section 5.4.5 of DEN0022F.b):
//
//   PSCI_SUCCESS - The CPU_SUSPEND call succeeded.  However, the CPU did not
//   reach a powerdown state because of a pending interrupt, or simply because
//   the requested |power_state| is not a powerdown state.
//
//   PSCI_INVALID_PARAMETERS - The |power_state| is invalid, or a low-power
//   state was requested for a higher-than-core-level topology node
//   (e.g. cluster) and at least one of the children in that node is in a local
//   low-power state that is incompatible with the request.
//
//   PSCI_DENIED - A low-power state is requested for a higher-than-core-level
//   topology node (e.g. cluster) and all the cores that are in an incompatible
//   state with the request are running, as opposed to being in a low-power
//   state.
//
//   PSCI_INVALID_ADDRESS - |entry| is not a valid physical address.
//
// If the return value is greater than zero, then the CPU did in fact suspend
// and resume execution at |entry| before returning to the caller.
//
// Implemented in assembly.
extern "C" int64_t psci_do_suspend(psci_call_proc psci_call, uint32_t power_state, paddr_t entry,
                                   psci_cpu_resume_context* context);
extern "C" zx_status_t psci_do_resume(psci_cpu_resume_context* context) __NO_RETURN;

zx_status_t psci_system_off() {
  return psci_status_to_zx_status(
      do_psci_call(PSCI64_SYSTEM_OFF, shutdown_args[0], shutdown_args[1], shutdown_args[2]));
}

uint32_t psci_get_version() {
  return static_cast<uint32_t>(do_psci_call(PSCI64_PSCI_VERSION, 0, 0, 0));
}

/* powers down the calling cpu - only returns if call fails */
zx_status_t psci_cpu_off() {
  gSuspendDomain.UnregisterCpu();
  return psci_status_to_zx_status(do_psci_call(PSCI64_CPU_OFF, 0, 0, 0));
}

zx_status_t psci_cpu_on(uint64_t mpid, paddr_t entry, uint64_t context) {
  LTRACEF("CPU_ON mpid %#" PRIx64 ", entry %#" PRIx64 "\n", mpid, entry);
  gSuspendDomain.RegisterCpu();
  return psci_status_to_zx_status(do_psci_call(PSCI64_CPU_ON, mpid, entry, context));
}

bool psci_might_powerdown() { return gSuspendDomain.SuspendMightPowerdown(); }

PsciCpuSuspendResult psci_cpu_suspend(PsciCpuSuspendMaxScope max_scope) {
  LTRACE_ENTRY;

  DEBUG_ASSERT(arch_ints_disabled());

  if (!psci_is_cpu_suspend_supported()) {
    return zx::error(ZX_ERR_NOT_SUPPORTED);
  }

  const paddr_t entry_pa = KernelPhysicalAddressOf<arm64_secondary_start>();
  psci_cpu_resume_context context{};
  int64_t result;
  uint32_t power_state;

  {
    SuspendDomain::Guard guard(gSuspendDomain, max_scope);
    power_state = guard.power_state();

    LTRACEF("cpu %u, psci_call_routine 0x%" PRIx64 ", power_state 0x%x, entry 0x%" PRIx64
            ", context %p\n",
            arch_curr_cpu_num(), reinterpret_cast<uintptr_t>(do_psci_call), power_state, entry_pa,
            &context);
    result = psci_do_suspend(do_psci_call, power_state, entry_pa, &context);
  }

  if (result > 0) {
    // We took the "long way" and restored CPU context from a powerdown state.
    kcounter_add(counter_psci_cpu_suspend_powered_down, 1);
    return zx::ok(CpuPoweredDown::Yes);
  }

  switch (result) {
    case PSCI_SUCCESS:
      kcounter_add(counter_psci_cpu_suspend_retained, 1);
      return zx::ok(CpuPoweredDown::No);
    case PSCI_INVALID_PARAMETERS:
      kcounter_add(counter_psci_cpu_suspend_invalid_parameters, 1);
      return zx::error(ZX_ERR_INVALID_ARGS);
    case PSCI_DENIED:
      kcounter_add(counter_psci_cpu_suspend_denied, 1);
      return zx::error(ZX_ERR_ACCESS_DENIED);
    default:
      panic("cpu %u, psci_call_routine 0x%" PRIx64 ", power_state 0x%x, entry 0x%" PRIx64
            ", context %p\n",
            arch_curr_cpu_num(), reinterpret_cast<uintptr_t>(do_psci_call), power_state, entry_pa,
            &context);
  };
}

int64_t psci_get_affinity_info(uint64_t mpid) {
  return static_cast<int64_t>(do_psci_call(PSCI64_AFFINITY_INFO, mpid, 0, 0));
}

zx::result<power_cpu_state> psci_get_cpu_state(uint64_t mpid) {
  int64_t aff_info = psci_get_affinity_info(mpid);
  switch (aff_info) {
    case 0:
      return zx::success(power_cpu_state::ON);
    case 1:
      return zx::success(power_cpu_state::OFF);
    case 2:
      return zx::success(power_cpu_state::ON_PENDING);
    default:
      return zx::error(psci_status_to_zx_status(aff_info));
  }
}

uint32_t psci_get_feature(uint32_t psci_call) {
  return static_cast<uint32_t>(do_psci_call(PSCI64_PSCI_FEATURES, psci_call, 0, 0));
}

zx_status_t psci_system_reset2_raw(uint32_t reset_type, uint32_t cookie) {
  dprintf(INFO, "PSCI SYSTEM_RESET2: %#" PRIx32 " %#" PRIx32 "\n", reset_type, cookie);

  uint64_t psci_status = do_psci_call(PSCI64_SYSTEM_RESET2, reset_type, cookie, 0);

  dprintf(INFO, "PSCI SYSTEM_RESET2 returns %" PRIi64 "\n", static_cast<int64_t>(psci_status));

  return psci_status_to_zx_status(psci_status);
}

zx_status_t psci_system_reset(power_reboot_flags flags) {
  uint64_t* args = reboot_args;

  if (flags == power_reboot_flags::REBOOT_BOOTLOADER) {
    args = reboot_bootloader_args;
  } else if (flags == power_reboot_flags::REBOOT_RECOVERY) {
    args = reboot_recovery_args;
  }

  dprintf(INFO, "PSCI reboot: %#" PRIx32 " %#" PRIx64 " %#" PRIx64 " %#" PRIx64 "\n", reset_command,
          args[0], args[1], args[2]);
  return psci_status_to_zx_status(do_psci_call(reset_command, args[0], args[1], args[2]));
}

zx_status_t psci_set_suspend_mode(psci_suspend_mode mode) {
  return psci_status_to_zx_status(do_psci_call(PSCI64_PSCI_SET_SUSPEND_MODE, mode, 0, 0));
}

bool psci_is_set_suspend_mode_supported() { return psci_set_suspend_mode_supported; }

bool psci_is_cpu_suspend_supported() { return gSuspendDomain.IsCpuSuspendSupported(); }

void PsciInit(const zbi_dcfg_arm_psci_driver_t& config,
              ktl::span<const zbi_dcfg_arm_psci_cpu_suspend_state_t> psci_cpu_suspend_config) {
  do_psci_call = config.use_hvc ? psci_hvc_call : psci_smc_call;
  memcpy(shutdown_args, config.shutdown_args, sizeof(shutdown_args));
  memcpy(reboot_args, config.reboot_args, sizeof(reboot_args));
  memcpy(reboot_bootloader_args, config.reboot_bootloader_args, sizeof(reboot_bootloader_args));
  memcpy(reboot_recovery_args, config.reboot_recovery_args, sizeof(reboot_recovery_args));

  // read information about the psci implementation
  uint32_t result = psci_get_version();
  uint32_t major = (result >> 16) & 0xffff;
  uint32_t minor = result & 0xffff;
  dprintf(INFO, "PSCI version %u.%u\n", major, minor);

  if (major >= 1 && major != 0xffff) {
    // query features
    dprintf(INFO, "PSCI supported features:\n");

    // Prints info about the features and returns supported flags or nullopt if not supported.
    auto probe_feature = [](uint32_t feature, const char* feature_name) -> ktl::optional<uint32_t> {
      uint32_t result = psci_get_feature(feature);
      if (static_cast<int32_t>(result) < 0) {
        // Not supported
        return ktl::nullopt;
      }
      dprintf(INFO, "\t%s (0x%x)\n", feature_name, result);
      return result;
    };

    const ktl::optional<uint32_t> cpu_suspend_result =
        probe_feature(PSCI64_CPU_SUSPEND, "CPU_SUSPEND");
    probe_feature(PSCI64_CPU_OFF, "CPU_OFF");
    probe_feature(PSCI64_CPU_ON, "CPU_ON");
    probe_feature(PSCI64_AFFINITY_INFO, "AFFINITY_INFO");
    probe_feature(PSCI64_MIGRATE, "MIGRATE");
    probe_feature(PSCI64_MIGRATE_INFO_TYPE, "MIGRATE_INFO_TYPE");
    probe_feature(PSCI64_MIGRATE_INFO_UP_CPU, "MIGRATE_INFO_UP_CPU");
    probe_feature(PSCI64_SYSTEM_OFF, "SYSTEM_OFF");
    probe_feature(PSCI64_SYSTEM_RESET, "SYSTEM_RESET");
    if (probe_feature(PSCI64_SYSTEM_RESET2, "SYSTEM_RESET2").has_value()) {
      // Prefer RESET2 if present. It explicitly supports arguments, but some vendors have
      // extended RESET to behave the same way.
      reset_command = PSCI64_SYSTEM_RESET2;
    }
    probe_feature(PSCI64_CPU_FREEZE, "CPU_FREEZE");
    probe_feature(PSCI64_CPU_DEFAULT_SUSPEND, "CPU_DEFAULT_SUSPEND");
    probe_feature(PSCI64_NODE_HW_STATE, "NODE_HW_STATE");
    probe_feature(PSCI64_SYSTEM_SUSPEND, "SYSTEM_SUSPEND");
    psci_set_suspend_mode_supported =
        probe_feature(PSCI64_PSCI_SET_SUSPEND_MODE, "PSCI_SET_SUSPEND_MODE").has_value();
    probe_feature(PSCI64_PSCI_STAT_RESIDENCY, "PSCI_STAT_RESIDENCY");
    probe_feature(PSCI64_PSCI_STAT_COUNT, "PSCI_STAT_COUNT");
    probe_feature(PSCI64_MEM_PROTECT, "MEM_PROTECT");
    probe_feature(PSCI64_MEM_PROTECT_RANGE, "MEM_PROTECT_RANGE");

    probe_feature(PSCI64_SMCCC_VERSION, "PSCI64_SMCCC_VERSION");

    // Print the power_state format and power_states after printing all the supported features.
    if (cpu_suspend_result.has_value()) {
      // Determine and set the power_state_format.
      const uint32_t options = cpu_suspend_result.value();
      // If bit-1 is zero, then it's original format.
      if ((options & (1 << 1)) == 0) {
        power_state_format = PowerStateFormat::Original;
      } else {
        power_state_format = PowerStateFormat::Extended;
      }

      parse_cpu_suspend_power_states(psci_cpu_suspend_config);
    }
  }

  // Register with the pdev power driver.
  static const pdev_power_ops psci_ops = {
      .reboot = psci_system_reset,
      .shutdown = psci_system_off,
      .cpu_off = psci_cpu_off,
      .cpu_on = psci_cpu_on,
      .get_cpu_state = psci_get_cpu_state,
  };

  pdev_register_power(&psci_ops);
}

namespace {

int cmd_psci(int argc, const cmd_args* argv, uint32_t flags) {
  if (argc < 2) {
  notenoughargs:
    printf("not enough arguments\n");
    printf("%s system_reset\n", argv[0].str);
    printf("%s system_off\n", argv[0].str);
    printf("%s cpu_on <mpidr>\n", argv[0].str);
    printf("%s affinity_info <cluster> <cpu>\n", argv[0].str);
    printf("%s <function_id> [arg0] [arg1] [arg2]\n", argv[0].str);
    return -1;
  }

  if (!strcmp(argv[1].str, "system_reset")) {
    psci_system_reset(power_reboot_flags::REBOOT_NORMAL);
  } else if (!strcmp(argv[1].str, "system_off")) {
    psci_system_off();
  } else if (!strcmp(argv[1].str, "cpu_on")) {
    if (argc < 3) {
      goto notenoughargs;
    }

    paddr_t secondary_entry_paddr = KernelPhysicalAddressOf<arm64_secondary_start>();
    uint32_t ret = psci_cpu_on(argv[2].u, secondary_entry_paddr, 0);
    printf("psci_cpu_on returns %u\n", ret);
  } else if (!strcmp(argv[1].str, "affinity_info")) {
    if (argc < 4) {
      goto notenoughargs;
    }

    int64_t ret = psci_get_affinity_info(ARM64_MPID(argv[2].u, argv[3].u));
    printf("affinity info returns %ld\n", ret);
  } else {
    uint32_t function = static_cast<uint32_t>(argv[1].u);
    uint64_t arg0 = (argc >= 3) ? argv[2].u : 0;
    uint64_t arg1 = (argc >= 4) ? argv[3].u : 0;
    uint64_t arg2 = (argc >= 5) ? argv[4].u : 0;

    uint64_t ret = do_psci_call(function, arg0, arg1, arg2);
    printf("do_psci_call returned %" PRIu64 "\n", ret);
  }
  return 0;
}

STATIC_COMMAND_START
STATIC_COMMAND_MASKED("psci", "execute PSCI command", &cmd_psci, CMD_AVAIL_ALWAYS)
STATIC_COMMAND_END(psci)

}  // anonymous namespace
