// 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_edn.h"

#include "sw/device/lib/base/bitfield.h"
#include "sw/device/lib/base/multibits.h"
#include "sw/device/lib/dif/dif_csrng_shared.h"

#include "edn_regs.h"  // Generated

static dif_result_t check_locked(const dif_edn_t *edn) {
  if (mmio_region_read32(edn->base_addr, EDN_REGWEN_REG_OFFSET) == 0) {
    return kDifLocked;
  }
  return kDifOk;
}

dif_result_t dif_edn_configure(const dif_edn_t *edn) {
  if (edn == NULL) {
    return kDifBadArg;
  }
  DIF_RETURN_IF_ERROR(check_locked(edn));

  uint32_t reg = mmio_region_read32(edn->base_addr, EDN_CTRL_REG_OFFSET);
  reg = bitfield_field32_write(reg, EDN_CTRL_EDN_ENABLE_FIELD,
                               kMultiBitBool4True);
  mmio_region_write32(edn->base_addr, EDN_CTRL_REG_OFFSET, reg);

  return kDifOk;
}

dif_result_t dif_edn_lock(const dif_edn_t *edn) {
  if (edn == NULL) {
    return kDifBadArg;
  }
  mmio_region_write32(edn->base_addr, EDN_REGWEN_REG_OFFSET, 0);
  return kDifOk;
}

dif_result_t dif_edn_is_locked(const dif_edn_t *edn, bool *is_locked) {
  if (edn == NULL || is_locked == NULL) {
    return kDifBadArg;
  }
  *is_locked = check_locked(edn) != kDifOk;
  return kDifOk;
}

dif_result_t dif_edn_set_boot_mode(const dif_edn_t *edn) {
  if (edn == NULL) {
    return kDifBadArg;
  }
  DIF_RETURN_IF_ERROR(check_locked(edn));

  uint32_t reg = mmio_region_read32(edn->base_addr, EDN_CTRL_REG_OFFSET);
  reg = bitfield_field32_write(reg, EDN_CTRL_BOOT_REQ_MODE_FIELD,
                               kMultiBitBool4True);
  mmio_region_write32(edn->base_addr, EDN_CTRL_REG_OFFSET, reg);

  return kDifOk;
}

dif_result_t dif_edn_set_auto_mode(const dif_edn_t *edn,
                                   dif_edn_auto_params_t config) {
  if (edn == NULL) {
    return kDifBadArg;
  }
  DIF_RETURN_IF_ERROR(check_locked(edn));

  // Check that EDN is disabled.  If it is not disabled (e.g., through a call
  // to `dif_edn_stop()`), we are not ready to change mode.
  uint32_t ctrl_reg = mmio_region_read32(edn->base_addr, EDN_CTRL_REG_OFFSET);
  const uint32_t edn_en =
      bitfield_field32_read(ctrl_reg, EDN_CTRL_EDN_ENABLE_FIELD);
  if (dif_multi_bit_bool_to_toggle(edn_en) != kDifToggleDisabled) {
    return kDifError;
  }

  // Ensure neither automatic nor boot request mode is set.
  ctrl_reg = bitfield_field32_write(ctrl_reg, EDN_CTRL_AUTO_REQ_MODE_FIELD,
                                    kMultiBitBool4False);
  ctrl_reg = bitfield_field32_write(ctrl_reg, EDN_CTRL_BOOT_REQ_MODE_FIELD,
                                    kMultiBitBool4False);
  mmio_region_write32(edn->base_addr, EDN_CTRL_REG_OFFSET, ctrl_reg);

  // Clear the reseed command FIFO and the generate command FIFO.
  ctrl_reg = bitfield_field32_write(ctrl_reg, EDN_CTRL_CMD_FIFO_RST_FIELD,
                                    kMultiBitBool4True);
  mmio_region_write32(edn->base_addr, EDN_CTRL_REG_OFFSET, ctrl_reg);

  // Restore command FIFOs to normal operation mode.  This is a prerequisite
  // before any further commands can be issued to these FIFOs.
  ctrl_reg = bitfield_field32_write(ctrl_reg, EDN_CTRL_CMD_FIFO_RST_FIELD,
                                    kMultiBitBool4False);
  mmio_region_write32(edn->base_addr, EDN_CTRL_REG_OFFSET, ctrl_reg);

  // Fill the reseed command FIFO.
  for (size_t i = 0; i < config.reseed_material.len; ++i) {
    mmio_region_write32(edn->base_addr, EDN_RESEED_CMD_REG_OFFSET,
                        config.reseed_material.data[i]);
  }

  // Fill the generate command FIFO.
  for (size_t i = 0; i < config.generate_material.len; ++i) {
    mmio_region_write32(edn->base_addr, EDN_GENERATE_CMD_REG_OFFSET,
                        config.generate_material.data[i]);
  }

  // Set the maximum number of requests between reseeds.
  mmio_region_write32(edn->base_addr,
                      EDN_MAX_NUM_REQS_BETWEEN_RESEEDS_REG_OFFSET,
                      config.reseed_interval);

  // Re-enable EDN in automatic request mode.
  ctrl_reg = bitfield_field32_write(ctrl_reg, EDN_CTRL_EDN_ENABLE_FIELD,
                                    kMultiBitBool4True);
  ctrl_reg = bitfield_field32_write(ctrl_reg, EDN_CTRL_AUTO_REQ_MODE_FIELD,
                                    kMultiBitBool4True);
  mmio_region_write32(edn->base_addr, EDN_CTRL_REG_OFFSET, ctrl_reg);

  // Wait until EDN is ready to accept commands.
  bool ready = false;
  while (!ready) {
    DIF_RETURN_IF_ERROR(dif_edn_get_status(edn, kDifEdnStatusReady, &ready));
  }

  // Command CSRNG Instantiate.  As soon as CSRNG acknowledges this command,
  // EDN will start automatically sending reseed and generate commands.
  DIF_RETURN_IF_ERROR(
      dif_edn_instantiate(edn, kDifEdnEntropySrcToggleEnable, NULL));

  // Wait until CSRNG acknowledges command.
  ready = false;
  while (!ready) {
    DIF_RETURN_IF_ERROR(dif_edn_get_status(edn, kDifEdnStatusReady, &ready));
  }

  // Read request acknowledge error and return accordingly.
  bool ack_err;
  DIF_RETURN_IF_ERROR(dif_edn_get_status(edn, kDifEdnStatusCsrngAck, &ack_err));
  return ack_err ? kDifError : kDifOk;
}

dif_result_t dif_edn_get_status(const dif_edn_t *edn, dif_edn_status_t flag,
                                bool *set) {
  if (edn == NULL || set == NULL) {
    return kDifBadArg;
  }

  uint32_t bit;
  switch (flag) {
    case kDifEdnStatusReady:
      bit = EDN_SW_CMD_STS_CMD_RDY_BIT;
      break;
    case kDifEdnStatusCsrngAck:
      bit = EDN_SW_CMD_STS_CMD_STS_BIT;
      break;
    default:
      return kDifBadArg;
  }

  uint32_t reg = mmio_region_read32(edn->base_addr, EDN_SW_CMD_STS_REG_OFFSET);
  *set = bitfield_bit32_read(reg, bit);
  return kDifOk;
}

dif_result_t dif_edn_get_errors(const dif_edn_t *edn, uint32_t *unhealthy_fifos,
                                uint32_t *errors) {
  if (edn == NULL || unhealthy_fifos == NULL || errors == NULL) {
    return kDifBadArg;
  }
  *unhealthy_fifos = 0;
  *errors = 0;

  uint32_t reg = mmio_region_read32(edn->base_addr, EDN_ERR_CODE_REG_OFFSET);
  *unhealthy_fifos =
      bitfield_bit32_copy(*unhealthy_fifos, kDifEdnFifoReseedCmd, reg,
                          EDN_ERR_CODE_SFIFO_RESCMD_ERR_BIT);
  *unhealthy_fifos =
      bitfield_bit32_copy(*unhealthy_fifos, kDifEdnFifoGenerateCmd, reg,
                          EDN_ERR_CODE_SFIFO_GENCMD_ERR_BIT);

  *errors = bitfield_bit32_copy(*errors, kDifEdnErrorAckSm, reg,
                                EDN_ERR_CODE_EDN_ACK_SM_ERR_BIT);
  *errors = bitfield_bit32_copy(*errors, kDifEdnErrorMainSm, reg,
                                EDN_ERR_CODE_EDN_MAIN_SM_ERR_BIT);
  *errors = bitfield_bit32_copy(*errors, kDifEdnErrorCounterFault, reg,
                                EDN_ERR_CODE_EDN_CNTR_ERR_BIT);
  *errors = bitfield_bit32_copy(*errors, kDifEdnErrorFifoWrite, reg,
                                EDN_ERR_CODE_FIFO_WRITE_ERR_BIT);
  *errors = bitfield_bit32_copy(*errors, kDifEdnErrorFifoRead, reg,
                                EDN_ERR_CODE_FIFO_READ_ERR_BIT);
  *errors = bitfield_bit32_copy(*errors, kDifEdnErrorFifoFullAndEmpty, reg,
                                EDN_ERR_CODE_FIFO_STATE_ERR_BIT);

  return kDifOk;
}

dif_result_t dif_edn_get_cmd_unhealthy_fifo_force(const dif_edn_t *edn,
                                                  dif_edn_fifo_t fifo) {
  if (edn == NULL) {
    return kDifBadArg;
  }

  uint32_t fifo_bit;
  switch (fifo) {
    case kDifEdnFifoReseedCmd:
      fifo_bit = EDN_ERR_CODE_SFIFO_RESCMD_ERR_BIT;
      break;
    case kDifEdnFifoGenerateCmd:
      fifo_bit = EDN_ERR_CODE_SFIFO_GENCMD_ERR_BIT;
      break;
    default:
      return kDifBadArg;
  }

  DIF_RETURN_IF_ERROR(check_locked(edn));
  mmio_region_write32(edn->base_addr, EDN_ERR_CODE_TEST_REG_OFFSET, fifo_bit);
  return kDifOk;
}

dif_result_t dif_edn_get_cmd_error_force(const dif_edn_t *edn,
                                         dif_edn_error_t error) {
  if (edn == NULL) {
    return kDifBadArg;
  }

  uint32_t error_bit;
  switch (error) {
    case kDifEdnErrorAckSm:
      error_bit = EDN_ERR_CODE_EDN_ACK_SM_ERR_BIT;
      break;
    case kDifEdnErrorMainSm:
      error_bit = EDN_ERR_CODE_EDN_MAIN_SM_ERR_BIT;
      break;
    case kDifEdnErrorCounterFault:
      error_bit = EDN_ERR_CODE_EDN_CNTR_ERR_BIT;
      break;
    case kDifEdnErrorFifoWrite:
      error_bit = EDN_ERR_CODE_FIFO_WRITE_ERR_BIT;
      break;
    case kDifEdnErrorFifoRead:
      error_bit = EDN_ERR_CODE_FIFO_READ_ERR_BIT;
      break;
    case kDifEdnErrorFifoFullAndEmpty:
      error_bit = EDN_ERR_CODE_FIFO_STATE_ERR_BIT;
      break;
    default:
      return kDifBadArg;
  }

  DIF_RETURN_IF_ERROR(check_locked(edn));
  mmio_region_write32(edn->base_addr, EDN_ERR_CODE_TEST_REG_OFFSET, error_bit);
  return kDifOk;
}

dif_result_t dif_edn_get_main_state_machine(const dif_edn_t *edn,
                                            uint32_t *state) {
  if (edn == NULL || state == NULL) {
    return kDifBadArg;
  }

  *state = mmio_region_read32(edn->base_addr, EDN_MAIN_SM_STATE_REG_OFFSET);
  return kDifOk;
}

dif_result_t dif_edn_instantiate(
    const dif_edn_t *edn, dif_edn_entropy_src_toggle_t entropy_src_enable,
    const dif_edn_seed_material_t *seed_material) {
  if (edn == NULL) {
    return kDifBadArg;
  }
  return csrng_send_app_cmd(
      edn->base_addr, EDN_SW_CMD_REQ_REG_OFFSET,
      (csrng_app_cmd_t){
          .id = kCsrngAppCmdInstantiate,
          .entropy_src_enable =
              (dif_csrng_entropy_src_toggle_t)entropy_src_enable,
          .seed_material = (const dif_csrng_seed_material_t *)seed_material,
      });
}

dif_result_t dif_edn_reseed(const dif_edn_t *edn,
                            const dif_edn_seed_material_t *seed_material) {
  if (edn == NULL || seed_material == NULL) {
    return kDifBadArg;
  }
  dif_csrng_seed_material_t seed_material2;
  memcpy(&seed_material2, seed_material, sizeof(seed_material2));
  return csrng_send_app_cmd(edn->base_addr, EDN_SW_CMD_REQ_REG_OFFSET,
                            (csrng_app_cmd_t){
                                .id = kCsrngAppCmdReseed,
                                .seed_material = &seed_material2,
                            });
}

dif_result_t dif_edn_update(const dif_edn_t *edn,
                            const dif_edn_seed_material_t *seed_material) {
  if (edn == NULL || seed_material == NULL) {
    return kDifBadArg;
  }
  dif_csrng_seed_material_t seed_material2;
  memcpy(&seed_material2, seed_material, sizeof(seed_material2));
  return csrng_send_app_cmd(edn->base_addr, EDN_SW_CMD_REQ_REG_OFFSET,
                            (csrng_app_cmd_t){
                                .id = kCsrngAppCmdUpdate,
                                .seed_material = &seed_material2,
                            });
}

dif_result_t dif_edn_generate_start(const dif_edn_t *edn, size_t len) {
  if (edn == NULL || len == 0) {
    return kDifBadArg;
  }

  // Round up the number of 128bit blocks. Aligning with respect to uint32_t.
  // TODO(#6112): Consider using a canonical reference for alignment operations.
  const uint32_t num_128bit_blocks = (len + 3) / 4;
  return csrng_send_app_cmd(edn->base_addr, EDN_SW_CMD_REQ_REG_OFFSET,
                            (csrng_app_cmd_t){
                                .id = kCsrngAppCmdGenerate,
                                .generate_len = num_128bit_blocks,
                            });
}

dif_result_t dif_edn_uninstantiate(const dif_edn_t *edn) {
  if (edn == NULL) {
    return kDifBadArg;
  }
  return csrng_send_app_cmd(edn->base_addr, EDN_SW_CMD_REQ_REG_OFFSET,
                            (csrng_app_cmd_t){
                                .id = kCsrngAppCmdUnisntantiate,
                            });
}

dif_result_t dif_edn_stop(const dif_edn_t *edn) {
  if (edn == NULL) {
    return kDifBadArg;
  }
  DIF_RETURN_IF_ERROR(check_locked(edn));

  mmio_region_write32(edn->base_addr, EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);

  // clear command fifo, see #14506
  uint32_t reg = bitfield_field32_write(
      EDN_CTRL_REG_RESVAL, EDN_CTRL_CMD_FIFO_RST_FIELD, kMultiBitBool4True);
  mmio_region_write32(edn->base_addr, EDN_CTRL_REG_OFFSET, reg);
  mmio_region_write32(edn->base_addr, EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);

  return kDifOk;
}

dif_result_t dif_edn_get_recoverable_alerts(const dif_edn_t *edn,
                                            uint32_t *alerts) {
  if (edn == NULL || alerts == NULL) {
    return kDifBadArg;
  }

  *alerts = 0;
  uint32_t reg =
      mmio_region_read32(edn->base_addr, EDN_RECOV_ALERT_STS_REG_OFFSET);
  *alerts = bitfield_bit32_copy(*alerts, kDifEdnRecoverableAlertBadEnable, reg,
                                EDN_RECOV_ALERT_STS_EDN_ENABLE_FIELD_ALERT_BIT);
  *alerts =
      bitfield_bit32_copy(*alerts, kDifEdnRecoverableAlertBadBootReqMode, reg,
                          EDN_RECOV_ALERT_STS_BOOT_REQ_MODE_FIELD_ALERT_BIT);
  *alerts =
      bitfield_bit32_copy(*alerts, kDifEdnRecoverableAlertBadAutoReqMode, reg,
                          EDN_RECOV_ALERT_STS_AUTO_REQ_MODE_FIELD_ALERT_BIT);
  *alerts =
      bitfield_bit32_copy(*alerts, kDifEdnRecoverableAlertBadFifoClear, reg,
                          EDN_RECOV_ALERT_STS_CMD_FIFO_RST_FIELD_ALERT_BIT);
  *alerts = bitfield_bit32_copy(*alerts, kDifEdnRecoverableAlertRepeatedGenBits,
                                reg, EDN_RECOV_ALERT_STS_EDN_BUS_CMP_ALERT_BIT);
  return kDifOk;
}

dif_result_t dif_edn_clear_recoverable_alerts(const dif_edn_t *edn) {
  if (edn == NULL) {
    return kDifBadArg;
  }
  mmio_region_write32(edn->base_addr, EDN_RECOV_ALERT_STS_REG_OFFSET, 0);
  return kDifOk;
}
