// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/lib/dif/dif_pwrmgr.h"

#include <assert.h>

#include "sw/device/lib/base/bitfield.h"
#include "sw/device/lib/base/mmio.h"

#include "pwrmgr_regs.h"  // Generated.

/**
 * Following static assertions make sure that generated values match the
 * definitions in the header, which we rely on for a simpler implementation.
 * These constants and their usages must be revisited if there is a change in
 * hardware.
 */

/**
 * Relevant bits of the control register must start at
 * `PWRMGR_CONTROL_CORE_CLK_EN_BIT` and be in the same order as
 * `dif_pwrmgr_domain_option_t` constants.
 */
static_assert(kDifPwrmgrDomainOptionCoreClockInLowPower ==
                  (1u << (PWRMGR_CONTROL_CORE_CLK_EN_BIT -
                          PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
              "Layout of control register changed.");

static_assert(kDifPwrmgrDomainOptionIoClockInLowPower ==
                  (1u << (PWRMGR_CONTROL_IO_CLK_EN_BIT -
                          PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
              "Layout of control register changed.");

static_assert(kDifPwrmgrDomainOptionUsbClockInLowPower ==
                  (1u << (PWRMGR_CONTROL_USB_CLK_EN_LP_BIT -
                          PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
              "Layout of control register changed.");

static_assert(kDifPwrmgrDomainOptionUsbClockInActivePower ==
                  (1u << (PWRMGR_CONTROL_USB_CLK_EN_ACTIVE_BIT -
                          PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
              "Layout of control register changed.");

static_assert(kDifPwrmgrDomainOptionMainPowerInLowPower ==
                  (1u << (PWRMGR_CONTROL_MAIN_PD_N_BIT -
                          PWRMGR_CONTROL_CORE_CLK_EN_BIT)),
              "Layout of control register changed.");

/**
 * Bitfield for interpreting the configuration options in the control
 * register.
 */
static const bitfield_field32_t kDomainConfigBitfield = {
    .mask = kDifPwrmgrDomainOptionCoreClockInLowPower |
            kDifPwrmgrDomainOptionIoClockInLowPower |
            kDifPwrmgrDomainOptionUsbClockInLowPower |
            kDifPwrmgrDomainOptionUsbClockInActivePower |
            kDifPwrmgrDomainOptionMainPowerInLowPower,
    .index = PWRMGR_CONTROL_CORE_CLK_EN_BIT,
};

/**
 * Relevant bits of the WAKEUP_EN and WAKE_INFO registers must start at `0` and
 * be in the same order as `dif_pwrmgr_wakeup_request_source_t` constants.
 */
static_assert(kDifPwrmgrWakeupRequestSourceOne ==
                  (1u << PWRMGR_WAKEUP_EN_EN_0_BIT),
              "Layout of WAKEUP_EN register changed.");
static_assert(kDifPwrmgrWakeupRequestSourceOne ==
                  (1u << PWRMGR_PARAM_AON_SYSRST_CTRL_WKUP_REQ_IDX),
              "Layout of WAKE_INFO register changed.");
static_assert(kDifPwrmgrWakeupRequestSourceTwo ==
                  (1u << PWRMGR_PARAM_DEBUG_CABLE_WAKEUP_IDX),
              "Layout of WAKE_INFO register changed.");
static_assert(kDifPwrmgrWakeupRequestSourceThree ==
                  (1u << PWRMGR_PARAM_AON_WKUP_REQ_IDX),
              "Layout of WAKE_INFO register changed.");
static_assert(kDifPwrmgrWakeupRequestSourceFour ==
                  (1u << PWRMGR_PARAM_USB_WKUP_REQ_IDX),
              "Layout of WAKE_INFO register changed.");
static_assert(kDifPwrmgrWakeupRequestSourceFive ==
                  (1u << PWRMGR_PARAM_AON_TIMER_WKUP_REQ_IDX),
              "Layout of WAKE_INFO register changed.");

/**
 * Relevant bits of the RESET_EN register must start at `0` and be in the same
 * order as `dif_pwrmgr_reset_request_source_t` constants.
 */
static_assert(kDifPwrmgrResetRequestSourceOne ==
                  (1u << PWRMGR_RESET_EN_EN_0_BIT),
              "Layout of RESET_EN register changed.");

/**
 * `dif_pwrmgr_irq_t` constants must match the corresponding generated values.
 */
static_assert(kDifPwrmgrIrqWakeup == PWRMGR_INTR_COMMON_WAKEUP_BIT,
              "Layout of interrupt registers changed.");

/**
 * Register information for a request type.
 */
typedef struct request_reg_info {
  ptrdiff_t write_enable_reg_offset;
  bitfield_bit32_index_t write_enable_bit_index;
  ptrdiff_t sources_enable_reg_offset;
  ptrdiff_t cur_req_sources_reg_offset;
  bitfield_field32_t bitfield;
} request_reg_info_t;

/**
 * Register information for wakeup and reset requests.
 *
 * Wakeup and reset requests follow the same logic for configuration and
 * monitoring but use different registers. Defining these constants here
 * allows us to use the same code for both types of requests.
 */
static const request_reg_info_t request_reg_infos[2] = {
    [kDifPwrmgrReqTypeWakeup] =
        {
            .write_enable_reg_offset = PWRMGR_WAKEUP_EN_REGWEN_REG_OFFSET,
            .write_enable_bit_index = PWRMGR_WAKEUP_EN_REGWEN_EN_BIT,
            .sources_enable_reg_offset = PWRMGR_WAKEUP_EN_REG_OFFSET,
            .cur_req_sources_reg_offset = PWRMGR_WAKE_STATUS_REG_OFFSET,
            .bitfield =
                {
                    .mask = kDifPwrmgrWakeupRequestSourceOne |
                            kDifPwrmgrWakeupRequestSourceTwo |
                            kDifPwrmgrWakeupRequestSourceThree |
                            kDifPwrmgrWakeupRequestSourceFour |
                            kDifPwrmgrWakeupRequestSourceFive,
                    .index = 0,
                },
        },
    [kDifPwrmgrReqTypeReset] =
        {
            .write_enable_reg_offset = PWRMGR_RESET_EN_REGWEN_REG_OFFSET,
            .write_enable_bit_index = PWRMGR_RESET_EN_REGWEN_EN_BIT,
            .sources_enable_reg_offset = PWRMGR_RESET_EN_REG_OFFSET,
            .cur_req_sources_reg_offset = PWRMGR_RESET_STATUS_REG_OFFSET,
            .bitfield =
                {
                    .mask = kDifPwrmgrResetRequestSourceOne,
                    .index = 0,
                },
        },
};

/**
 * Checks if a value is a valid `dif_pwrmgr_toggle_t` and converts it to `bool`.
 */
DIF_WARN_UNUSED_RESULT
static bool toggle_to_bool(dif_pwrmgr_toggle_t val, bool *val_bool) {
  switch (val) {
    case kDifPwrmgrToggleEnabled:
      *val_bool = true;
      break;
    case kDifPwrmgrToggleDisabled:
      *val_bool = false;
      break;
    default:
      return false;
  }
  return true;
}

/**
 * Converts a `bool` to `dif_pwrmgr_toggle_t`.
 */
static dif_pwrmgr_toggle_t bool_to_toggle(bool val) {
  return val ? kDifPwrmgrToggleEnabled : kDifPwrmgrToggleDisabled;
}

/**
 * Checks if a value is a valid `dif_pwrmgr_req_type_t`.
 */
DIF_WARN_UNUSED_RESULT
static bool is_valid_req_type(dif_pwrmgr_req_type_t val) {
  return val == kDifPwrmgrReqTypeWakeup || val == kDifPwrmgrReqTypeReset;
}

/**
 * Checks if a value is a valid `dif_pwrmgr_irq_t`.
 */
DIF_WARN_UNUSED_RESULT
static bool is_valid_irq(dif_pwrmgr_irq_t val) {
  return val >= 0 && val <= kDifPwrmgrIrqLast;
}

/**
 * Checks if a value is valid for, i.e. fits in the mask of, a
 * `bitfield_field32_t`.
 */
DIF_WARN_UNUSED_RESULT
static bool is_valid_for_bitfield(uint32_t val, bitfield_field32_t bitfield) {
  return (val & bitfield.mask) == val;
}

/**
 * Checks if the control register is locked.
 *
 * Control register is locked when low power is enabled and WFI occurs. It is
 * unlocked when the chip transitions back to active power state.
 */
DIF_WARN_UNUSED_RESULT
static bool control_register_is_locked(const dif_pwrmgr_t *pwrmgr) {
  // Control register is locked when `PWRMGR_CTRL_CFG_REGWEN_EN_BIT` bit is 0.
  return !bitfield_bit32_read(
      mmio_region_read32(pwrmgr->params.base_addr,
                         PWRMGR_CTRL_CFG_REGWEN_REG_OFFSET),
      PWRMGR_CTRL_CFG_REGWEN_EN_BIT);
}

/**
 * The configuration registers CONTROL, WAKEUP_EN, and RESET_EN are all written
 * in the fast clock domain but used in the slow clock domain. Values of these
 * registers are not propagated across the clock boundary until this function is
 * called.
 */
static void sync_slow_clock_domain_polled(const dif_pwrmgr_t *pwrmgr) {
  // Start sync and wait for it to finish.
  mmio_region_write32(
      pwrmgr->params.base_addr, PWRMGR_CFG_CDC_SYNC_REG_OFFSET,
      bitfield_bit32_write(0, PWRMGR_CFG_CDC_SYNC_SYNC_BIT, true));
  while (bitfield_bit32_read(mmio_region_read32(pwrmgr->params.base_addr,
                                                PWRMGR_CFG_CDC_SYNC_REG_OFFSET),
                             PWRMGR_CFG_CDC_SYNC_SYNC_BIT)) {
  }
}

/**
 * Checks if sources of a request type are locked.
 */
DIF_WARN_UNUSED_RESULT
static bool request_sources_is_locked(const dif_pwrmgr_t *pwrmgr,
                                      dif_pwrmgr_req_type_t req_type) {
  request_reg_info_t reg_info = request_reg_infos[req_type];
  uint32_t reg_val = mmio_region_read32(pwrmgr->params.base_addr,
                                        reg_info.write_enable_reg_offset);
  // Locked if write enable bit is set to 0.
  return !bitfield_bit32_read(reg_val, reg_info.write_enable_bit_index);
}

dif_pwrmgr_result_t dif_pwrmgr_init(dif_pwrmgr_params_t params,
                                    dif_pwrmgr_t *pwrmgr) {
  if (pwrmgr == NULL) {
    return kDifPwrmgrBadArg;
  }

  *pwrmgr = (dif_pwrmgr_t){.params = params};

  return kDifPwrmgrOk;
}

dif_pwrmgr_config_result_t dif_pwrmgr_low_power_set_enabled(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_toggle_t new_state) {
  if (pwrmgr == NULL) {
    return kDifPwrmgrConfigBadArg;
  }

  bool enable = false;
  if (!toggle_to_bool(new_state, &enable)) {
    return kDifPwrmgrConfigBadArg;
  }

  if (control_register_is_locked(pwrmgr)) {
    return kDifPwrMgrConfigLocked;
  }

  uint32_t reg_val =
      mmio_region_read32(pwrmgr->params.base_addr, PWRMGR_CONTROL_REG_OFFSET);
  reg_val =
      bitfield_bit32_write(reg_val, PWRMGR_CONTROL_LOW_POWER_HINT_BIT, enable);
  mmio_region_write32(pwrmgr->params.base_addr, PWRMGR_CONTROL_REG_OFFSET,
                      reg_val);

  // Slow clock domain must be synced for changes to take effect.
  sync_slow_clock_domain_polled(pwrmgr);

  return kDifPwrmgrConfigOk;
}

dif_pwrmgr_result_t dif_pwrmgr_low_power_get_enabled(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_toggle_t *cur_state) {
  if (pwrmgr == NULL || cur_state == NULL) {
    return kDifPwrmgrBadArg;
  }

  uint32_t reg_val =
      mmio_region_read32(pwrmgr->params.base_addr, PWRMGR_CONTROL_REG_OFFSET);
  *cur_state = bool_to_toggle(
      bitfield_bit32_read(reg_val, PWRMGR_CONTROL_LOW_POWER_HINT_BIT));

  return kDifPwrmgrOk;
}

dif_pwrmgr_config_result_t dif_pwrmgr_set_domain_config(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_domain_config_t config) {
  if (pwrmgr == NULL || !is_valid_for_bitfield(config, kDomainConfigBitfield)) {
    return kDifPwrmgrConfigBadArg;
  }

  if (control_register_is_locked(pwrmgr)) {
    return kDifPwrMgrConfigLocked;
  }

  uint32_t reg_val =
      mmio_region_read32(pwrmgr->params.base_addr, PWRMGR_CONTROL_REG_OFFSET);
  reg_val = bitfield_field32_write(reg_val, kDomainConfigBitfield, config);
  mmio_region_write32(pwrmgr->params.base_addr, PWRMGR_CONTROL_REG_OFFSET,
                      reg_val);

  // Slow clock domain must be synced for changes to take effect.
  sync_slow_clock_domain_polled(pwrmgr);

  return kDifPwrmgrConfigOk;
}

dif_pwrmgr_result_t dif_pwrmgr_get_domain_config(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_domain_config_t *config) {
  if (pwrmgr == NULL || config == NULL) {
    return kDifPwrmgrBadArg;
  }

  uint32_t reg_val =
      mmio_region_read32(pwrmgr->params.base_addr, PWRMGR_CONTROL_REG_OFFSET);
  *config = bitfield_field32_read(reg_val, kDomainConfigBitfield);

  return kDifPwrmgrOk;
}

dif_pwrmgr_config_result_t dif_pwrmgr_set_request_sources(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_req_type_t req_type,
    dif_pwrmgr_request_sources_t sources) {
  if (pwrmgr == NULL || !is_valid_req_type(req_type)) {
    return kDifPwrmgrConfigBadArg;
  }

  request_reg_info_t reg_info = request_reg_infos[req_type];

  if (!is_valid_for_bitfield(sources, reg_info.bitfield)) {
    return kDifPwrmgrConfigBadArg;
  }

  // Return early if locked.
  if (request_sources_is_locked(pwrmgr, req_type)) {
    return kDifPwrMgrConfigLocked;
  }

  // Write new value
  uint32_t reg_val = bitfield_field32_write(0, reg_info.bitfield, sources);
  mmio_region_write32(pwrmgr->params.base_addr,
                      reg_info.sources_enable_reg_offset, reg_val);
  // Slow clock domain must be synced for changes to take effect.
  sync_slow_clock_domain_polled(pwrmgr);

  return kDifPwrmgrConfigOk;
}

dif_pwrmgr_result_t dif_pwrmgr_get_request_sources(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_req_type_t req_type,
    dif_pwrmgr_request_sources_t *sources) {
  if (pwrmgr == NULL || !is_valid_req_type(req_type) || sources == NULL) {
    return kDifPwrmgrBadArg;
  }

  request_reg_info_t reg_info = request_reg_infos[req_type];
  uint32_t reg_val = mmio_region_read32(pwrmgr->params.base_addr,
                                        reg_info.sources_enable_reg_offset);
  *sources = bitfield_field32_read(reg_val, reg_info.bitfield);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_get_current_request_sources(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_req_type_t req_type,
    dif_pwrmgr_request_sources_t *sources) {
  if (pwrmgr == NULL || !is_valid_req_type(req_type) || sources == NULL) {
    return kDifPwrmgrBadArg;
  }

  request_reg_info_t reg_info = request_reg_infos[req_type];
  uint32_t reg_val = mmio_region_read32(pwrmgr->params.base_addr,
                                        reg_info.cur_req_sources_reg_offset);
  *sources = bitfield_field32_read(reg_val, reg_info.bitfield);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_request_sources_lock(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_req_type_t req_type) {
  if (pwrmgr == NULL || !is_valid_req_type(req_type)) {
    return kDifPwrmgrBadArg;
  }

  // Only a single bit of this register is significant, thus we don't perform a
  // read-modify-write. Setting this bit to 0 locks sources.
  mmio_region_write32(pwrmgr->params.base_addr,
                      request_reg_infos[req_type].write_enable_reg_offset, 0);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_request_sources_is_locked(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_req_type_t req_type,
    bool *is_locked) {
  if (pwrmgr == NULL || !is_valid_req_type(req_type) || is_locked == NULL) {
    return kDifPwrmgrBadArg;
  }

  *is_locked = request_sources_is_locked(pwrmgr, req_type);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_wakeup_request_recording_set_enabled(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_toggle_t new_state) {
  if (pwrmgr == NULL) {
    return kDifPwrmgrBadArg;
  }

  bool enable = false;
  if (!toggle_to_bool(new_state, &enable)) {
    return kDifPwrmgrBadArg;
  }

  // Only a single bit of this register is significant, thus we don't perform a
  // read-modify-write. Setting this bit to 1 disables recording.
  uint32_t reg_val =
      bitfield_bit32_write(0, PWRMGR_WAKE_INFO_CAPTURE_DIS_VAL_BIT, !enable);

  mmio_region_write32(pwrmgr->params.base_addr,
                      PWRMGR_WAKE_INFO_CAPTURE_DIS_REG_OFFSET, reg_val);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_wakeup_request_recording_get_enabled(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_toggle_t *cur_state) {
  if (pwrmgr == NULL || cur_state == NULL) {
    return kDifPwrmgrBadArg;
  }

  uint32_t reg_val = mmio_region_read32(
      pwrmgr->params.base_addr, PWRMGR_WAKE_INFO_CAPTURE_DIS_REG_OFFSET);
  // Recording is disabled if this bit is set to 1.
  *cur_state = bool_to_toggle(
      !bitfield_bit32_read(reg_val, PWRMGR_WAKE_INFO_CAPTURE_DIS_VAL_BIT));

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_wakeup_reason_get(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_wakeup_reason_t *reason) {
  if (pwrmgr == NULL || reason == NULL) {
    return kDifPwrmgrBadArg;
  }

  uint32_t reg_val =
      mmio_region_read32(pwrmgr->params.base_addr, PWRMGR_WAKE_INFO_REG_OFFSET);

  dif_pwrmgr_wakeup_types_t types = 0;
  if (bitfield_bit32_read(reg_val, PWRMGR_WAKE_INFO_FALL_THROUGH_BIT)) {
    types |= kDifPwrmgrWakeupTypeFallThrough;
  }
  if (bitfield_bit32_read(reg_val, PWRMGR_WAKE_INFO_ABORT_BIT)) {
    types |= kDifPwrmgrWakeupTypeAbort;
  }

  uint32_t request_sources = bitfield_field32_read(
      reg_val, request_reg_infos[kDifPwrmgrReqTypeWakeup].bitfield);
  if (request_sources != 0) {
    types |= kDifPwrmgrWakeupTypeRequest;
  }

  *reason = (dif_pwrmgr_wakeup_reason_t){
      .types = types,
      .request_sources = request_sources,
  };

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_wakeup_reason_clear(const dif_pwrmgr_t *pwrmgr) {
  if (pwrmgr == NULL) {
    return kDifPwrmgrBadArg;
  }

  mmio_region_write32(pwrmgr->params.base_addr, PWRMGR_WAKE_INFO_REG_OFFSET,
                      UINT32_MAX);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_irq_is_pending(const dif_pwrmgr_t *pwrmgr,
                                              dif_pwrmgr_irq_t irq,
                                              bool *is_pending) {
  if (pwrmgr == NULL || !is_valid_irq(irq) || is_pending == NULL) {
    return kDifPwrmgrBadArg;
  }

  uint32_t reg_val = mmio_region_read32(pwrmgr->params.base_addr,
                                        PWRMGR_INTR_STATE_REG_OFFSET);
  *is_pending = bitfield_bit32_read(reg_val, irq);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_irq_acknowledge(const dif_pwrmgr_t *pwrmgr,
                                               dif_pwrmgr_irq_t irq) {
  if (pwrmgr == NULL || !is_valid_irq(irq)) {
    return kDifPwrmgrBadArg;
  }

  uint32_t reg_val = bitfield_bit32_write(0, irq, true);
  mmio_region_write32(pwrmgr->params.base_addr, PWRMGR_INTR_STATE_REG_OFFSET,
                      reg_val);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_irq_get_enabled(const dif_pwrmgr_t *pwrmgr,
                                               dif_pwrmgr_irq_t irq,
                                               dif_pwrmgr_toggle_t *state) {
  if (pwrmgr == NULL || !is_valid_irq(irq) || state == NULL) {
    return kDifPwrmgrBadArg;
  }

  uint32_t reg_val = mmio_region_read32(pwrmgr->params.base_addr,
                                        PWRMGR_INTR_ENABLE_REG_OFFSET);
  *state = bool_to_toggle(bitfield_bit32_read(reg_val, irq));

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_irq_set_enabled(const dif_pwrmgr_t *pwrmgr,
                                               dif_pwrmgr_irq_t irq,
                                               dif_pwrmgr_toggle_t state) {
  if (pwrmgr == NULL || !is_valid_irq(irq)) {
    return kDifPwrmgrBadArg;
  }

  bool enable = false;
  if (!toggle_to_bool(state, &enable)) {
    return kDifPwrmgrBadArg;
  }

  uint32_t reg_val = mmio_region_read32(pwrmgr->params.base_addr,
                                        PWRMGR_INTR_ENABLE_REG_OFFSET);
  reg_val = bitfield_bit32_write(reg_val, irq, enable);
  mmio_region_write32(pwrmgr->params.base_addr, PWRMGR_INTR_ENABLE_REG_OFFSET,
                      reg_val);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_irq_force(const dif_pwrmgr_t *pwrmgr,
                                         dif_pwrmgr_irq_t irq) {
  if (pwrmgr == NULL || !is_valid_irq(irq)) {
    return kDifPwrmgrBadArg;
  }

  uint32_t reg_val = bitfield_bit32_write(0, irq, true);
  mmio_region_write32(pwrmgr->params.base_addr, PWRMGR_INTR_TEST_REG_OFFSET,
                      reg_val);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_irq_disable_all(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_irq_snapshot_t *snapshot) {
  if (pwrmgr == NULL) {
    return kDifPwrmgrBadArg;
  }

  if (snapshot != NULL) {
    *snapshot = mmio_region_read32(pwrmgr->params.base_addr,
                                   PWRMGR_INTR_ENABLE_REG_OFFSET);
  }
  mmio_region_write32(pwrmgr->params.base_addr, PWRMGR_INTR_ENABLE_REG_OFFSET,
                      0);

  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_irq_restore_all(
    const dif_pwrmgr_t *pwrmgr, dif_pwrmgr_irq_snapshot_t snapshot) {
  if (pwrmgr == NULL) {
    return kDifPwrmgrBadArg;
  }

  mmio_region_write32(pwrmgr->params.base_addr, PWRMGR_INTR_ENABLE_REG_OFFSET,
                      snapshot);
  return kDifPwrmgrOk;
}

dif_pwrmgr_result_t dif_pwrmgr_alert_force(const dif_pwrmgr_t *pwrmgr,
                                           dif_pwrmgr_alert_t alert) {
  if (pwrmgr == NULL) {
    return kDifPwrmgrBadArg;
  }

  bitfield_bit32_index_t index;
  switch (alert) {
    case kDifPwrmgrAlertFatalFault:
      index = PWRMGR_ALERT_TEST_FATAL_FAULT_BIT;
      break;
    default:
      return kDifPwrmgrBadArg;
  }

  uint32_t reg = bitfield_bit32_write(0, index, true);
  mmio_region_write32(pwrmgr->params.base_addr, PWRMGR_ALERT_TEST_REG_OFFSET,
                      reg);

  return kDifPwrmgrOk;
}
