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

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#include "rv_plic_regs.h"  // Generated.
#include "sw/device/lib/base/mmio.h"

// If either of these static assertions fail, then the assumptions in this DIF
// implementation should be revisited. In particular, `plic_target_reg_offsets`
// may need updating,
_Static_assert(RV_PLIC_PARAM_NUMSRC == 83,
               "PLIC instantiation parameters have changed.");
_Static_assert(RV_PLIC_PARAM_NUMTARGET == 1,
               "PLIC instantiation parameters have changed.");

const uint32_t kDifPlicMinPriority = 0;
const uint32_t kDifPlicMaxPriority = 0x3u;

/**
 * PLIC register info.
 *
 * This data type is used to store IRQ source bit offset within a register,
 * and the offset of this register inside the PLIC.
 */
typedef struct plic_reg_info {
  ptrdiff_t offset;  /*<< Register offset. */
  uint8_t bit_index; /*<< Bit index within the register. */
} plic_reg_info_t;

/**
 * PLIC target specific register offsets.
 *
 * PLIC is designed to support multiple targets, and every target has a set
 * of its own registers. This data type is used to store PLIC target specific
 * register offsets.
 */
typedef struct plic_target_reg_offset {
  ptrdiff_t ie;        /*<< Interrupt Enable register offset. */
  ptrdiff_t cc;        /*<< Claim/complete register offset. */
  ptrdiff_t threshold; /*<< Threshold register offset. */
} plic_target_reg_offset_t;

// This array gives a way of getting the target-specific register offsets from
// a `dif_plic_target_t`.
//
// There should be an instance of `plic_target_reg_offset_t` for each possible
// target, so there should be `RV_PLIC_PARAM_NUMTARGET` entries in this array.
// The `i`th entry should contain the offsets of the `i`th target specific
// registers:
// - `RV_PLIC_IE<i>0_REG_OFFSET` (the first IE reg for target `i`).
// - `RV_PLIC_CC<i>_REG_OFFSET`
// - `RV_PLIC_THRESHOLD<i>_REG_OFFSET`
static const plic_target_reg_offset_t plic_target_reg_offsets[] = {
        [0] =
            {
                .ie = RV_PLIC_IE00_REG_OFFSET,
                .cc = RV_PLIC_CC0_REG_OFFSET,
                .threshold = RV_PLIC_THRESHOLD0_REG_OFFSET,
            },
};
_Static_assert(
    sizeof(plic_target_reg_offsets) / sizeof(*plic_target_reg_offsets) ==
        RV_PLIC_PARAM_NUMTARGET,
    "There should be an entry in plic_target_reg_offsets for every target");

/**
 * Get an IE, IP or LE register offset (IE00, IE01, ...) from an IRQ source ID.
 *
 * With more than 32 IRQ sources, there is a multiple of these registers to
 * accommodate all the bits (1 bit per IRQ source). This function calculates
 * the offset for a specific IRQ source ID (ID 32 would be IE01, ...).
 */
static ptrdiff_t plic_offset_from_reg0(dif_plic_irq_id_t irq) {
  uint8_t register_index = irq / RV_PLIC_PARAM_REG_WIDTH;
  return register_index * sizeof(uint32_t);
}

/**
 * Get an IE, IP, LE register bit index from an IRQ source ID.
 *
 * With more than 32 IRQ sources, there is a multiple of these registers to
 * accommodate all the bits (1 bit per IRQ source). This function calculates
 * the bit position within a register for a specifci IRQ source ID (ID 32 would
 * be bit 0).
 */
static uint8_t plic_reg_bit_index_from_irq_id(dif_plic_irq_id_t irq) {
  return irq % RV_PLIC_PARAM_REG_WIDTH;
}

/**
 * Get a target and an IRQ source specific Interrupt Enable register info.
 */
static void plic_irq_enable_reg_info(dif_plic_irq_id_t irq,
                                     dif_plic_target_t target,
                                     plic_reg_info_t *reg_info) {
  ptrdiff_t offset = plic_offset_from_reg0(irq);
  reg_info->offset = plic_target_reg_offsets[target].ie + offset;
  reg_info->bit_index = plic_reg_bit_index_from_irq_id(irq);
}

/**
 * Get an IRQ source specific Level/Edge register info.
 */
static void plic_irq_trigger_type_reg_info(dif_plic_irq_id_t irq,
                                           plic_reg_info_t *reg_info) {
  ptrdiff_t offset = plic_offset_from_reg0(irq);
  reg_info->offset = RV_PLIC_LE0_REG_OFFSET + offset;
  reg_info->bit_index = plic_reg_bit_index_from_irq_id(irq);
}

/**
 * Get an IRQ source specific Interrupt Pending register info.
 */
static void plic_irq_pending_reg_info(dif_plic_irq_id_t irq,
                                      plic_reg_info_t *reg_info) {
  ptrdiff_t offset = plic_offset_from_reg0(irq);
  reg_info->offset = RV_PLIC_IP0_REG_OFFSET + offset;
  reg_info->bit_index = plic_reg_bit_index_from_irq_id(irq);
}

/**
 * Get a PRIO register offset (PRIO0, PRIO1, ...) from an IRQ source ID.
 *
 * There is one PRIO register per IRQ source, this function calculates the IRQ
 * source specific PRIO register offset.
 */
static ptrdiff_t plic_priority_reg_offset(dif_plic_irq_id_t irq) {
  ptrdiff_t offset = irq * sizeof(uint32_t);
  return RV_PLIC_PRIO0_REG_OFFSET + offset;
}

/**
 * Reset the requested PLIC peripheral.
 *
 * This function resets all the relevant PLIC registers, apart from the CC
 * register. There is no reliable way of knowing the ID of an IRQ that has
 * claimed the CC register, so we assume that the previous "owner" of the
 * resource has cleared/completed the CC access.
 */
static void plic_reset(const dif_plic_t *plic) {
  // Clear all of the Interrupt Enable registers.
  for (int i = 0; i < RV_PLIC_IE0_MULTIREG_COUNT; ++i) {
    ptrdiff_t offset = RV_PLIC_IE00_REG_OFFSET + (i * sizeof(uint32_t));
    mmio_region_write32(plic->base_addr, offset, 0);
  }

  // Clear all of the Level/Edge registers.
  for (int i = 0; i < RV_PLIC_LE_MULTIREG_COUNT; ++i) {
    ptrdiff_t offset = RV_PLIC_LE0_REG_OFFSET + (i * sizeof(uint32_t));
    mmio_region_write32(plic->base_addr, offset, 0);
  }

  // Clear all of the priority registers.
  for (int i = 0; i < RV_PLIC_PARAM_NUMSRC; ++i) {
    ptrdiff_t offset = plic_priority_reg_offset(i);
    mmio_region_write32(plic->base_addr, offset, 0);
  }

  // Clear all of the target threshold registers.
  for (dif_plic_target_t target = 0; target < RV_PLIC_PARAM_NUMTARGET;
       ++target) {
    ptrdiff_t offset = plic_target_reg_offsets[target].threshold;
    mmio_region_write32(plic->base_addr, offset, 0);
  }

  // Clear software interrupt pending register.
  mmio_region_write32(plic->base_addr, RV_PLIC_MSIP0_REG_OFFSET, 0);
}

dif_plic_result_t dif_plic_init(mmio_region_t base_addr, dif_plic_t *plic) {
  if (plic == NULL) {
    return kDifPlicBadArg;
  }

  plic->base_addr = base_addr;

  plic_reset(plic);

  return kDifPlicOk;
}

dif_plic_result_t dif_plic_irq_enable_set(const dif_plic_t *plic,
                                          dif_plic_irq_id_t irq,
                                          dif_plic_target_t target,
                                          dif_plic_enable_t enable) {
  if (plic == NULL || irq >= RV_PLIC_PARAM_NUMSRC ||
      target >= RV_PLIC_PARAM_NUMTARGET) {
    return kDifPlicBadArg;
  }

  // Get a target and an IRQ source specific Interrupt Enable register info.
  plic_reg_info_t reg_info;
  plic_irq_enable_reg_info(irq, target, &reg_info);

  if (enable == kDifPlicEnable) {
    mmio_region_nonatomic_set_bit32(plic->base_addr, reg_info.offset,
                                    reg_info.bit_index);
  } else {
    mmio_region_nonatomic_clear_bit32(plic->base_addr, reg_info.offset,
                                      reg_info.bit_index);
  }

  return kDifPlicOk;
}

dif_plic_result_t dif_plic_irq_trigger_type_set(const dif_plic_t *plic,
                                                dif_plic_irq_id_t irq,
                                                dif_plic_enable_t enable) {
  if (plic == NULL || irq >= RV_PLIC_PARAM_NUMSRC) {
    return kDifPlicBadArg;
  }

  // Get an IRQ source specific Level/Edge register info.
  plic_reg_info_t reg_info;
  plic_irq_trigger_type_reg_info(irq, &reg_info);

  if (enable == kDifPlicEnable) {
    mmio_region_nonatomic_set_bit32(plic->base_addr, reg_info.offset,
                                    reg_info.bit_index);
  } else {
    mmio_region_nonatomic_clear_bit32(plic->base_addr, reg_info.offset,
                                      reg_info.bit_index);
  }

  return kDifPlicOk;
}

dif_plic_result_t dif_plic_irq_priority_set(const dif_plic_t *plic,
                                            dif_plic_irq_id_t irq,
                                            uint32_t priority) {
  if (plic == NULL || irq >= RV_PLIC_PARAM_NUMSRC ||
      priority > kDifPlicMaxPriority) {
    return kDifPlicBadArg;
  }

  ptrdiff_t offset = plic_priority_reg_offset(irq);
  mmio_region_write32(plic->base_addr, offset, priority);

  return kDifPlicOk;
}

dif_plic_result_t dif_plic_target_threshold_set(const dif_plic_t *plic,
                                                dif_plic_target_t target,
                                                uint32_t threshold) {
  if (plic == NULL || target >= RV_PLIC_PARAM_NUMTARGET ||
      threshold > kDifPlicMaxPriority) {
    return kDifPlicBadArg;
  }

  ptrdiff_t threshold_offset = plic_target_reg_offsets[target].threshold;
  mmio_region_write32(plic->base_addr, threshold_offset, threshold);

  return kDifPlicOk;
}

dif_plic_result_t dif_plic_irq_pending_status_get(const dif_plic_t *plic,
                                                  dif_plic_irq_id_t irq,
                                                  dif_plic_flag_t *status) {
  if (plic == NULL || irq >= RV_PLIC_PARAM_NUMSRC || status == NULL) {
    return kDifPlicBadArg;
  }

  plic_reg_info_t reg_info;
  plic_irq_pending_reg_info(irq, &reg_info);

  if (mmio_region_get_bit32(plic->base_addr, reg_info.offset,
                            reg_info.bit_index)) {
    *status = kDifPlicSet;
  } else {
    *status = kDifPlicUnset;
  }

  return kDifPlicOk;
}

dif_plic_result_t dif_plic_irq_claim(const dif_plic_t *plic,
                                     dif_plic_target_t target,
                                     dif_plic_irq_id_t *claim_data) {
  if (plic == NULL || target >= RV_PLIC_PARAM_NUMTARGET || claim_data == NULL) {
    return kDifPlicBadArg;
  }

  // Get an IRQ ID from the target specific CC register.
  ptrdiff_t cc_offset = plic_target_reg_offsets[target].cc;
  uint32_t irq_id = mmio_region_read32(plic->base_addr, cc_offset);

  // Return the IRQ ID directly.
  *claim_data = irq_id;
  return kDifPlicOk;
}

dif_plic_result_t dif_plic_irq_complete(
    const dif_plic_t *plic, dif_plic_target_t target,
    const dif_plic_irq_id_t *complete_data) {
  if (plic == NULL || target >= RV_PLIC_PARAM_NUMTARGET ||
      complete_data == NULL) {
    return kDifPlicBadArg;
  }

  // Write back the claimed IRQ ID to the target specific CC register,
  // to notify the PLIC of the IRQ completion.
  ptrdiff_t cc_offset = plic_target_reg_offsets[target].cc;
  mmio_region_write32(plic->base_addr, cc_offset, (uint32_t)*complete_data);

  return kDifPlicOk;
}
