blob: d989f345adc9d329f7364f27311a9e6915c4310e [file] [log] [blame]
Miguel Young de la Sotadddf1ed2019-12-18 12:24:43 -06001// Copyright lowRISC contributors.
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
Miguel Young de la Sota960fd8e2020-01-14 13:52:13 -05005#ifndef OPENTITAN_SW_DEVICE_LIB_RUNTIME_IBEX_H_
6#define OPENTITAN_SW_DEVICE_LIB_RUNTIME_IBEX_H_
Miguel Young de la Sotadddf1ed2019-12-18 12:24:43 -06007
8#include <stddef.h>
9
10#include "sw/device/lib/base/stdasm.h"
11
12/**
Sam Elliott2b9bb302020-02-21 14:10:11 +000013 * @file
14 * @brief This header provides Ibex-specific functions, such as cycle-accurate
15 * busy loops.
Miguel Young de la Sotadddf1ed2019-12-18 12:24:43 -060016 */
17
18/**
Alphan Ulusoy3e4cd9d2020-01-21 15:03:01 -050019 * Read the cycle counter.
Miguel Young de la Sotadddf1ed2019-12-18 12:24:43 -060020 *
Sam Elliott812eb332020-03-31 17:29:35 +010021 * The value of the counter is stored across two 32-bit registers: `mcycle` and
22 * `mcycleh`. This function is guaranteed to return a valid 64-bit cycle
23 * counter value, even if `mcycle` overflows before reading `mcycleh`.
Miguel Young de la Sotadddf1ed2019-12-18 12:24:43 -060024 *
Alphan Ulusoy3e4cd9d2020-01-21 15:03:01 -050025 * Adapted from: The RISC-V Instruction Set Manual, Volume I: Unprivileged ISA
26 * V20191213, pp. 61.
Miguel Young de la Sotadddf1ed2019-12-18 12:24:43 -060027 */
Sam Elliott5e5a9dd2020-11-10 10:45:48 +000028inline uint64_t ibex_mcycle_read(void) {
Alphan Ulusoy3e4cd9d2020-01-21 15:03:01 -050029 uint32_t cycle_low = 0;
30 uint32_t cycle_high = 0;
31 uint32_t cycle_high_2 = 0;
Miguel Young de la Sotadddf1ed2019-12-18 12:24:43 -060032 asm volatile(
Alphan Ulusoy3e4cd9d2020-01-21 15:03:01 -050033 "read%=:"
Sam Elliott812eb332020-03-31 17:29:35 +010034 " csrr %0, mcycleh;" // Read `mcycleh`.
35 " csrr %1, mcycle;" // Read `mcycle`.
36 " csrr %2, mcycleh;" // Read `mcycleh` again.
37 " bne %0, %2, read%=;" // Try again if `mcycle` overflowed before
38 // reading `mcycleh`.
Alphan Ulusoy3e4cd9d2020-01-21 15:03:01 -050039 : "+r"(cycle_high), "=r"(cycle_low), "+r"(cycle_high_2)
40 :);
41 return (uint64_t)cycle_high << 32 | cycle_low;
Miguel Young de la Sotadddf1ed2019-12-18 12:24:43 -060042}
43
Timothy Trippel15a07842021-09-14 19:01:39 +000044/**
45 * Reads the mcause register.
46 *
47 * When an exception is encountered, the corresponding exception code is stored
48 * in mcause register.
49 *
50 * A list of the exception codes can be found at:
51 * https://ibex-core.readthedocs.io/en/latest/03_reference/
52 * exception_interrupts.html#exceptions
53 */
54uint32_t ibex_mcause_read(void);
55
56/**
57 * Reads the mtval register.
58 *
59 * When an exception is encountered, the Machine Trap Value (mtval) register
60 * can holds exception-specific information to assist software in handling the
61 * trap.
62 *
63 * From the Ibex documentation (found at
64 * https://ibex-core.readthedocs.io/en/latest/03_reference/cs_registers.html)
65 * - In the case of errors in the load-store unit mtval holds the address of
66 * the transaction causing the error.
67 *
68 * - If a transaction is misaligned, mtval holds the address of the missing
69 * transaction part.
70 *
71 * - In the case of illegal instruction exceptions, mtval holds the actual
72 * faulting instruction.
73 *
74 * - For all other exceptions, mtval is 0.
75 */
76uint32_t ibex_mtval_read(void);
77
Miguel Young de la Sota960fd8e2020-01-14 13:52:13 -050078#endif // OPENTITAN_SW_DEVICE_LIB_RUNTIME_IBEX_H_