// 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;
}
