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

#ifndef OPENTITAN_SW_DEVICE_LIB_RUNTIME_IBEX_H_
#define OPENTITAN_SW_DEVICE_LIB_RUNTIME_IBEX_H_

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

#include "sw/device/lib/arch/device.h"
#include "sw/device/lib/base/math.h"
#include "sw/device/lib/base/stdasm.h"

// IBEX_SPIN_FOR needs a dependency on check.h, but the build fails if a
// dependency on sw_lib_testing_check is added.

/**
 * @file
 * @brief This header provides Ibex-specific functions and enums, such as
 * cycle-accurate busy loops.
 */

/**
 * An Ibex exception type.
 *
 * This enum is used to decode RISC-V exception causes generated by Ibex.
 */
typedef enum ibex_exc {
  kIbexExcInstrMisaligned = 0,
  kIbexExcInstrAccessFault = 1,
  kIbexExcIllegalInstrFault = 2,
  kIbexExcBreakpoint = 3,
  kIbexExcLoadAccessFault = 5,
  kIbexExcStoreAccessFault = 7,
  kIbexExcUserECall = 8,
  kIbexExcMachineECall = 11,
  kIbexExcMax = 31
} ibex_exc_t;

/**
 * An Ibex internal IRQ type.
 *
 * This enum is used to decode RISC-V internal IRQs generated by Ibex.
 */
typedef enum ibex_internal_irq {
  kIbexInternalIrqLoadInteg = 0xffffffe0,
  kIbexInternalIrqNmi = 0x8000001f
} ibex_internal_irq_t;

/**
 * A spinwait timeout type.
 */
typedef struct ibex_timeout {
  /**
   * The number of cycles to timeout.
   */
  uint64_t cycles;
  /**
   * The initial cycle count.
   */
  uint64_t start;
} ibex_timeout_t;

/**
 * Read the cycle counter.
 *
 * The value of the counter is stored across two 32-bit registers: `mcycle` and
 * `mcycleh`. This function is guaranteed to return a valid 64-bit cycle
 * counter value, even if `mcycle` overflows before reading `mcycleh`.
 *
 * Adapted from: The RISC-V Instruction Set Manual, Volume I: Unprivileged ISA
 * V20191213, pp. 61.
 */
inline uint64_t ibex_mcycle_read(void) {
  uint32_t cycle_low = 0;
  uint32_t cycle_high = 0;
  uint32_t cycle_high_2 = 0;
  asm volatile(
      "1:"
      "  csrr %0, mcycleh;"  // Read `mcycleh`.
      "  csrr %1, mcycle;"   // Read `mcycle`.
      "  csrr %2, mcycleh;"  // Read `mcycleh` again.
      "  bne  %0, %2, 1b;"   // Try again if `mcycle` overflowed before
                             // reading `mcycleh`.
      : "=r"(cycle_high), "=r"(cycle_low), "=r"(cycle_high_2)
      :);
  return (uint64_t)cycle_high << 32 | cycle_low;
}

/**
 * Reads the mcause register.
 *
 * When an exception is encountered, the corresponding exception code is stored
 * in mcause register.
 *
 * A list of the exception codes can be found at:
 * https://ibex-core.readthedocs.io/en/latest/03_reference/
 * exception_interrupts.html#exceptions
 */
uint32_t ibex_mcause_read(void);

/**
 * Reads the mtval register.
 *
 * When an exception is encountered, the Machine Trap Value (mtval) register
 * can holds exception-specific information to assist software in handling the
 * trap.
 *
 * From the Ibex documentation (found at
 * https://ibex-core.readthedocs.io/en/latest/03_reference/cs_registers.html)
 * - In the case of errors in the load-store unit mtval holds the address of
 * the transaction causing the error.
 *
 * - If a transaction is misaligned, mtval holds the address of the missing
 *   transaction part.
 *
 * - In the case of illegal instruction exceptions, mtval holds the actual
 * faulting instruction.
 *
 * - For all other exceptions, mtval is 0.
 */
uint32_t ibex_mtval_read(void);

/**
 * Reads the mepc register.
 *
 * When an exception is encountered, the current program counter is saved in
 * mepc, and the core jumps to the exception address. When an MRET instruction
 * is executed, the value from mepc replaces the current program counter.
 *
 * From the Ibex documentation (found at
 * https://ibex-core.readthedocs.io/en/latest/03_reference/cs_registers.html)
 *
 * Please note that in case of a fault, mepc must be modified to hold the
 * address of the next instruction, which can be at the 2byte (16bit) or 4byte
 * (32bit) offset, dependent on the fault cause instruction type (standard or
 * compressed).
 *
 * @return The mepc register value.
 */
uint32_t ibex_mepc_read(void);

/**
 * Writes the mepc register.
 *
 * When an exception is encountered, the current program counter is saved in
 * mepc, and the core jumps to the exception address. When an MRET instruction
 * is executed, the value from mepc replaces the current program counter.
 *
 * From the Ibex documentation (found at
 * https://ibex-core.readthedocs.io/en/latest/03_reference/cs_registers.html)
 *
 * Please note that in case of a fault, mepc must be modified to hold the
 * address of the next instruction, which can be at the 2byte (16bit) or 4byte
 * (32bit) offset, dependent on the fault cause instruction type (standard or
 * compressed).
 *
 * @param The new value to be written to the mepc register.
 */
void ibex_mepc_write(uint32_t mepc);

/**
 * Initializes the ibex timeout based on current mcycle count.
 *
 * @param timeout_usec Timeout in microseconds.
 * @return The initialized timeout value.
 */
inline ibex_timeout_t ibex_timeout_init(uint32_t timeout_usec) {
  return (ibex_timeout_t){
      .cycles = udiv64_slow(kClockFreqCpuHz * timeout_usec, 1000000, NULL),
      .start = ibex_mcycle_read(),
  };
}

/**
 * Check whether the timeout has expired.
 *
 * @param timeout Holds the counter start value.
 * @return True if the timeout has expired and false otherwise.
 */
inline bool ibex_timeout_check(const ibex_timeout_t *timeout) {
  return ibex_mcycle_read() - timeout->start > timeout->cycles;
}

/**
 * Returns the time elapsed in microseconds since `ibex_timeout_init` was
 * called.
 *
 * @param timeout Holds the counter start value..
 * @return Time elapsed in microseconds.
 */
inline uint64_t ibex_timeout_elapsed(const ibex_timeout_t *timeout) {
  return udiv64_slow((ibex_mcycle_read() - timeout->start) * 1000000,
                     kClockFreqCpuHz, NULL);
}

/**
 * Convenience macro to spin with timeout in microseconds.
 *
 * @param expr An expression that is evaluated multiple times until true.
 * @param timeout_usec Timeout in microseconds.
 */
#define IBEX_SPIN_FOR(expr, timeout_usec)                                 \
  do {                                                                    \
    const ibex_timeout_t timeout_ = ibex_timeout_init(timeout_usec);      \
    while (!(expr)) {                                                     \
      CHECK(!ibex_timeout_check(&timeout_),                               \
            "Timed out after %d usec (%d CPU cycles) waiting for " #expr, \
            timeout_usec, (uint32_t)timeout_.cycles);                     \
    }                                                                     \
  } while (0)

#endif  // OPENTITAN_SW_DEVICE_LIB_RUNTIME_IBEX_H_
