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

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

#include "sw/device/lib/base/bitfield.h"
#include "sw/device/lib/base/csr.h"
#include "sw/device/lib/base/macros.h"

// "Volume II: RISC-V Privileged Architectures V20190608-Priv-MSU-Ratified",
// "3.6.1 Physical Memory Protection CSRs",
// "Figure 3.28: PMP configuration register format".
#define PMP_CFG_CSR_R 0
#define PMP_CFG_CSR_W 1
#define PMP_CFG_CSR_X 2
#define PMP_CFG_CSR_A 3
#define PMP_CFG_CSR_L 7

#define PMP_CFG_FIELDS_PER_REG 4
#define PMP_CFG_FIELD_WIDTH 8
#define PMP_CFG_FIELD_MASK 0xff

// "Volume II: RISC-V Privileged Architectures V20190608-Priv-MSU-Ratified",
// "3.6.1 Physical Memory Protection CSRs", "Address Matching".
#define PMP_CFG_CSR_MODE_OFF 0
#define PMP_CFG_CSR_MODE_TOR 1
#define PMP_CFG_CSR_MODE_NA4 2
#define PMP_CFG_CSR_MODE_NAPOT 3
#define PMP_CFG_CSR_MODE_MASK 0x3

typedef enum pmp_csr_access_type {
  kPmpCsrAccessTypeRead = 0,
  kPmpCsrAccessTypeWrite,
} pmp_csr_access_type_t;

static const bitfield_field32_t kPmpCfgModeField = {
    .mask = PMP_CFG_CSR_MODE_MASK,
    .index = PMP_CFG_CSR_A,
};

/**
 * This is an X-Macro used for automatically deriving switch statements which
 * link PMP region identifiers to associated information including their
 * configuration register identifier.
 *
 * This macro should be invoked with a macro argument with the following
 * signature:
 *
 * @param region_id PMP Region Identifier.
 * @param config_reg_id Configuration Register ID for a given PMP Region (for
 * Ibex).
 */
#define PMP_REGIONS(X) \
  X(0, 0)              \
  X(1, 0)              \
  X(2, 0)              \
  X(3, 0)              \
                       \
  X(4, 1)              \
  X(5, 1)              \
  X(6, 1)              \
  X(7, 1)              \
                       \
  X(8, 2)              \
  X(9, 2)              \
  X(10, 2)             \
  X(11, 2)             \
                       \
  X(12, 3)             \
  X(13, 3)             \
  X(14, 3)             \
  X(15, 3)

/**
 * Reads the pmpcfg for a given region.
 *
 * This reads the entire `pmpcfgN` value, not just the word associated with the
 * current region.
 *
 * @param region PMP Region ID to read.
 * @param[out] value Where to put the result of the read.
 * @return `true` if `pmp_region_index_t` is valid and value was read, `false`
 * otherwise.
 */
OT_WARN_UNUSED_RESULT
static bool pmp_cfg_csr_read(pmp_region_index_t region, uint32_t *value) {
#define PMP_READ_CONFIG_(region_id, config_reg_id)  \
  case region_id: {                                 \
    CSR_READ(CSR_REG_PMPCFG##config_reg_id, value); \
    return true;                                    \
  }

  switch (region) {
    PMP_REGIONS(PMP_READ_CONFIG_)
    default:
      return false;
  }
}

/**
 * Writes the pmpcfg for a given region.
 *
 * This writes the entire `pmpcfgN` value, not just the word associated with the
 * current region.
 *
 * @param region PMP Region ID to write.
 * @param value the value to write.
 * @return `true` if `pmp_region_index_t` is valid and value was written,
 * `false` otherwise.
 */
OT_WARN_UNUSED_RESULT
static bool pmp_cfg_csr_write(pmp_region_index_t region, uint32_t value) {
#define PMP_WRITE_CONFIG_(region_id, config_reg_id)  \
  case region_id: {                                  \
    CSR_WRITE(CSR_REG_PMPCFG##config_reg_id, value); \
    return true;                                     \
  }

  switch (region) {
    PMP_REGIONS(PMP_WRITE_CONFIG_)
    default:
      return false;
  }
}

/**
 * Reads the pmpaddr for a given region.
 *
 * @param region PMP Region ID to read.
 * @param[out] value Where to put the result of the read.
 * @return `true` if `pmp_region_index_t` is valid and value was read, `false`
 * otherwise.
 */
OT_WARN_UNUSED_RESULT
static bool pmp_addr_csr_read(pmp_region_index_t region, uint32_t *value) {
#define PMP_READ_ADDR_(region_id, _)             \
  case region_id: {                              \
    CSR_READ(CSR_REG_PMPADDR##region_id, value); \
    return true;                                 \
  }

  switch (region) {
    PMP_REGIONS(PMP_READ_ADDR_)
    default:
      return false;
  }
}

/**
 * Writes the pmpcfg for a given region.
 *
 * @param region PMP region ID to get/set.
 * @param value Value to write into a CSR.
 * @return `pmp_region_configure_result_t`.
 */
OT_WARN_UNUSED_RESULT
static bool pmp_addr_csr_write(pmp_region_index_t region, uint32_t value) {
#define PMP_WRITE_ADDR_(region_id, _)             \
  case region_id: {                               \
    CSR_WRITE(CSR_REG_PMPADDR##region_id, value); \
    return true;                                  \
  }

  switch (region) {
    PMP_REGIONS(PMP_WRITE_ADDR_)
    default:
      return false;
  }
}

/**
 * Retrievs configuration information for the requested `region`.
 *
 * A single `pmpcfg` CSR packs configuration information for `N` regions.
 *
 * @param region PMP region ID.
 * @param field_value Configuration information for the `region`.
 * @return `pmp_region_configure_result_t`.
 */
OT_WARN_UNUSED_RESULT
static pmp_region_configure_result_t pmp_csr_cfg_field_read(
    pmp_region_index_t region, uint32_t *field_value) {
  uint32_t cfg_csr_original;
  if (!pmp_cfg_csr_read(region, &cfg_csr_original)) {
    return kPmpRegionConfigureError;
  }

  size_t field_index = (region % PMP_CFG_FIELDS_PER_REG) * PMP_CFG_FIELD_WIDTH;
  bitfield_field32_t pmp_csr_cfg_field = {
      .mask = PMP_CFG_FIELD_MASK,
      .index = field_index,
  };

  *field_value = bitfield_field32_read(cfg_csr_original, pmp_csr_cfg_field);

  return kPmpRegionConfigureOk;
}

/**
 * Writes configuration information for the requested `region`.
 *
 * A single `pmpcfg` CSR packs configuration information for `N` regions.
 *
 * @param region PMP region ID.
 * @param field_value Configuration information for the `region`.
 * @return `pmp_region_configure_result_t`.
 */
OT_WARN_UNUSED_RESULT
static pmp_region_configure_result_t pmp_csr_cfg_field_write(
    pmp_region_index_t region, uint32_t field_value) {
  uint32_t cfg_csr_current;
  if (!pmp_cfg_csr_read(region, &cfg_csr_current)) {
    return kPmpRegionConfigureError;
  }

  // Determine the pmpcfg field index based on the `region`.
  size_t field_index = (region % PMP_CFG_FIELDS_PER_REG) * PMP_CFG_FIELD_WIDTH;
  bitfield_field32_t pmp_csr_cfg_field = {
      .mask = PMP_CFG_FIELD_MASK,
      .index = field_index,
  };

  uint32_t cfg_csr_new =
      bitfield_field32_write(cfg_csr_current, pmp_csr_cfg_field, field_value);

  if (!pmp_cfg_csr_write(region, cfg_csr_new)) {
    return kPmpRegionConfigureError;
  }

  if (!pmp_cfg_csr_read(region, &cfg_csr_current)) {
    return kPmpRegionConfigureError;
  }

  if (cfg_csr_current != cfg_csr_new) {
    return kPmpRegionConfigureWarlError;
  }

  return kPmpRegionConfigureOk;
}

/**
 * Writes `address` to a pmpaddr CSRs.
 *
 * The corresponding pmpaddrN index N is determined by `region`.
 *
 * PMP address must be at least 4bytes aligned, and pmpaddr holds only bits
 * 33:2. This means that before writing an address to a pmpaddr CSR, it must be
 * shifted 2 bits to the right.
 *
 * Please see:
 * "Volume II: RISC-V Privileged Architectures V20190608-Priv-MSU-Ratified",
 * "3.6.1 Physical Memory Protection CSRs",
 * "Figure 3.26: PMP address register format, RV32".
 *
 * @param region PMP region to configure and set address for.
 * @param address Address to be set.
 * @return `pmp_region_configure_result_t`.
 */
pmp_region_configure_result_t pmp_csr_address_write(pmp_region_index_t region,
                                                    uintptr_t address) {
  uint32_t address_shifted = address >> PMP_ADDRESS_SHIFT;
  if (!pmp_addr_csr_write(region, address_shifted)) {
    return kPmpRegionConfigureError;
  }

  uint32_t addr_csr_after_write;
  if (!pmp_addr_csr_read(region, &addr_csr_after_write)) {
    return kPmpRegionConfigureError;
  }

  if (address_shifted != addr_csr_after_write) {
    return kPmpRegionConfigureWarlError;
  }

  return kPmpRegionConfigureOk;
}

/**
 * Set PMP region permissions.
 *
 * @param perm Memory access permissions.
 * @param bitfield Bitfield to set.
 * @return `true` on success, `false` on failure.
 */
OT_WARN_UNUSED_RESULT
static bool pmp_cfg_permissions_set(pmp_region_permissions_t perm,
                                    uint32_t *bitfield) {
  switch (perm) {
    case kPmpRegionPermissionsNone:
      // No access is allowed.
      break;
    case kPmpRegionPermissionsReadOnly:
      *bitfield = bitfield_bit32_write(*bitfield, PMP_CFG_CSR_R, true);
      break;
    case kPmpRegionPermissionsExecuteOnly:
      *bitfield = bitfield_bit32_write(*bitfield, PMP_CFG_CSR_X, true);
      break;
    case kPmpRegionPermissionsReadExecute:
      *bitfield = bitfield_bit32_write(*bitfield, PMP_CFG_CSR_R, true);
      *bitfield = bitfield_bit32_write(*bitfield, PMP_CFG_CSR_X, true);
      break;
    case kPmpRegionPermissionsReadWrite:
      *bitfield = bitfield_bit32_write(*bitfield, PMP_CFG_CSR_R, true);
      *bitfield = bitfield_bit32_write(*bitfield, PMP_CFG_CSR_W, true);
      break;
    case kPmpRegionPermissionsReadWriteExecute:
      *bitfield = bitfield_bit32_write(*bitfield, PMP_CFG_CSR_R, true);
      *bitfield = bitfield_bit32_write(*bitfield, PMP_CFG_CSR_W, true);
      *bitfield = bitfield_bit32_write(*bitfield, PMP_CFG_CSR_X, true);
      break;
    default:
      return false;
  }

  return true;
}

/**
 * Set PMP region lock.
 *
 * @param lock Lock to indicate whether the region must be locked.
 * @param bitfield Bitfield to set.
 */
static void pmp_cfg_mode_lock_set(pmp_region_lock_t lock, uint32_t *bitfield) {
  bool flag = (lock == kPmpRegionLockLocked) ? true : false;
  *bitfield = bitfield_bit32_write(*bitfield, PMP_CFG_CSR_L, flag);
}

/**
 * Check whether `address` is correctly aligned.
 *
 * The alignment depend on the granularity, which is implementation specific,
 * and for Ibex is `PMP_GRANULARITY_IBEX`. Default granularity "G" is 0, which
 * means a minimal alignment of 4bytes. Please see:
 * "Volume II: RISC-V Privileged Architectures V20190608-Priv-MSU-Ratified",
 * "3.6 Physical Memory Protection", "Figure 3.26" and section
 * "Address Matching".
 *
 * @param address System address.
 * @return `true` on success, `false` on failure.
 */
static bool pmp_address_aligned(uintptr_t address) {
  return address == (address & PMP_ADDRESS_ALIGNMENT_INVERTED_MASK);
}

/**
 * Constructs a NAPOT address from the requested system address and size.
 *
 * This function makes sure that the `address` and `size` are valid, and then
 * constructs a corresponding NAPOT address. Please see:
 * "Volume II: RISC-V Privileged Architectures V20190608-Priv-MSU-Ratified",
 * "3.6 Physical Memory Protection", "Figure 3.26" and "Table 3.10".
 *
 * @param address Conventional system address.
 * @param size The size of a range to protect.
 * @param pmp_address_napot Constructed NAPOT address.
 * @return `pmp_region_configure_napot_result_t`.
 */
OT_WARN_UNUSED_RESULT
static pmp_region_configure_napot_result_t pmp_napot_address_construct(
    uintptr_t address, uint32_t size, uintptr_t *pmp_address_napot) {
  // Must be at least the size of the minimal alignment adjusted for
  // granularity, and the minimal allowed size for the NAPOT mode.
  if (size < PMP_ADDRESS_ALIGNMENT || size < PMP_ADDRESS_MIN_ALIGNMENT_NAPOT) {
    return kPmpRegionConfigureNapotBadAddress;
  }

  // Check if the `size` is a Power Of Two.
  uint32_t size_mask = size - 1;
  if ((size & size_mask) != 0) {
    return kPmpRegionConfigureNapotBadSize;
  }

  // Check if the address is aligned to the `size`.
  if (address != (address & (~size_mask))) {
    return kPmpRegionConfigureNapotBadAddress;
  }

  // `size_mask` must be right shifted, as the minimal legal size in NAPOT
  // mode is 8 bytes.
  *pmp_address_napot = address | (size_mask >> 1);

  return kPmpRegionConfigureNapotOk;
}

pmp_region_configure_result_t pmp_region_configure_off(
    pmp_region_index_t region, uintptr_t address) {
  if (region >= PMP_REGIONS_NUM) {
    return kPmpRegionConfigureBadRegion;
  }

  if (!pmp_address_aligned(address)) {
    return kPmpRegionConfigureBadAddress;
  }

  // Address registers must be written prior to the configuration registers to
  // ensure that they are not locked.
  pmp_region_configure_result_t result = pmp_csr_address_write(region, address);
  if (result != kPmpRegionConfigureOk) {
    return result;
  }

  // Clear the appropriate region field of the pmpcfg CSR.
  result = pmp_csr_cfg_field_write(region, 0);
  if (result != kPmpRegionConfigureOk) {
    return result;
  }

  return kPmpRegionConfigureOk;
}

pmp_region_configure_na4_result_t pmp_region_configure_na4(
    pmp_region_index_t region, pmp_region_config_t config, uintptr_t address) {
  if (PMP_GRANULARITY_IBEX > 0) {
    return kPmpRegionConfigureNa4Unavailable;
  }

  if (region >= PMP_REGIONS_NUM) {
    return kPmpRegionConfigureNa4BadRegion;
  }

  if (!pmp_address_aligned(address)) {
    return kPmpRegionConfigureNa4BadAddress;
  }

  uint32_t field_value = 0;
  if (!pmp_cfg_permissions_set(config.permissions, &field_value)) {
    return kPmpRegionConfigureNa4Error;
  }

  pmp_cfg_mode_lock_set(config.lock, &field_value);

  field_value = bitfield_field32_write(field_value, kPmpCfgModeField,
                                       PMP_CFG_CSR_MODE_NA4);

  // Address registers must be written prior to the configuration registers to
  // ensure that they are not locked.
  pmp_region_configure_result_t result = pmp_csr_address_write(region, address);
  if (result != kPmpRegionConfigureOk) {
    return (pmp_region_configure_na4_result_t)result;
  }

  result = pmp_csr_cfg_field_write(region, field_value);
  if (result != kPmpRegionConfigureOk) {
    return (pmp_region_configure_na4_result_t)result;
  }

  return kPmpRegionConfigureNa4Ok;
}

pmp_region_configure_napot_result_t pmp_region_configure_napot(
    pmp_region_index_t region, pmp_region_config_t config, uintptr_t address,
    uint32_t size) {
  if (region >= PMP_REGIONS_NUM) {
    return kPmpRegionConfigureNapotBadRegion;
  }

  uintptr_t napot_address;
  pmp_region_configure_napot_result_t napot_result =
      pmp_napot_address_construct(address, size, &napot_address);
  if (napot_result != kPmpRegionConfigureNapotOk) {
    return napot_result;
  }

  uint32_t field_value = 0;
  if (!pmp_cfg_permissions_set(config.permissions, &field_value)) {
    return kPmpRegionConfigureNapotError;
  }

  pmp_cfg_mode_lock_set(config.lock, &field_value);

  field_value = bitfield_field32_write(field_value, kPmpCfgModeField,
                                       PMP_CFG_CSR_MODE_NAPOT);

  // Address registers must be written prior to the configuration registers to
  // ensure that they are not locked.
  pmp_region_configure_result_t result =
      pmp_csr_address_write(region, napot_address);
  if (result != kPmpRegionConfigureOk) {
    return (pmp_region_configure_napot_result_t)result;
  }

  result = pmp_csr_cfg_field_write(region, field_value);
  if (result != kPmpRegionConfigureOk) {
    return (pmp_region_configure_napot_result_t)result;
  }

  return kPmpRegionConfigureNapotOk;
}

pmp_region_configure_result_t pmp_region_configure_tor(
    pmp_region_index_t region_end, pmp_region_config_t config,
    uintptr_t address_start, uintptr_t address_end) {
  if (region_end >= PMP_REGIONS_NUM) {
    return kPmpRegionConfigureBadRegion;
  }

  if (region_end == 0 && address_start > 0) {
    return kPmpRegionConfigureBadAddress;
  }

  if (region_end > 0 && !pmp_address_aligned(address_start)) {
    return kPmpRegionConfigureBadAddress;
  }

  if (!pmp_address_aligned(address_end)) {
    return kPmpRegionConfigureBadAddress;
  }

  uint32_t field_value = 0;
  if (!pmp_cfg_permissions_set(config.permissions, &field_value)) {
    return kPmpRegionConfigureError;
  }

  pmp_cfg_mode_lock_set(config.lock, &field_value);

  field_value = bitfield_field32_write(field_value, kPmpCfgModeField,
                                       PMP_CFG_CSR_MODE_TOR);

  // Address registers must be written prior to the configuration registers to
  // ensure that they are not locked.
  if (region_end != 0) {
    pmp_region_configure_result_t result =
        pmp_csr_address_write(region_end - 1, address_start);
    if (result != kPmpRegionConfigureOk) {
      return result;
    }
  }

  pmp_region_configure_result_t result =
      pmp_csr_address_write(region_end, address_end);
  if (result != kPmpRegionConfigureOk) {
    return result;
  }

  result = pmp_csr_cfg_field_write(region_end, field_value);
  if (result != kPmpRegionConfigureOk) {
    return result;
  }

  return kPmpRegionConfigureOk;
}

pmp_region_configure_result_t pmp_cfg_mode_lock_status_get(
    pmp_region_index_t region, pmp_region_lock_t *lock) {
  if (region >= PMP_REGIONS_NUM) {
    return kPmpRegionConfigureBadRegion;
  }

  if (lock == NULL) {
    return kPmpRegionConfigureBadArg;
  }

  uint32_t field_value;
  pmp_region_configure_result_t result =
      pmp_csr_cfg_field_read(region, &field_value);
  if (result != kPmpRegionConfigureOk) {
    return result;
  }

  bool flag = bitfield_bit32_read(field_value, PMP_CFG_CSR_L);
  *lock = flag ? kPmpRegionLockLocked : kPmpRegionLockUnlocked;

  return kPmpRegionConfigureOk;
}
