Miguel Young de la Sota | dddf1ed | 2019-12-18 12:24:43 -0600 | [diff] [blame] | 1 | // 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 Sota | 960fd8e | 2020-01-14 13:52:13 -0500 | [diff] [blame] | 5 | #ifndef OPENTITAN_SW_DEVICE_LIB_RUNTIME_IBEX_H_ |
| 6 | #define OPENTITAN_SW_DEVICE_LIB_RUNTIME_IBEX_H_ |
Miguel Young de la Sota | dddf1ed | 2019-12-18 12:24:43 -0600 | [diff] [blame] | 7 | |
| 8 | #include <stddef.h> |
| 9 | |
| 10 | #include "sw/device/lib/base/stdasm.h" |
| 11 | |
| 12 | /** |
Sam Elliott | 2b9bb30 | 2020-02-21 14:10:11 +0000 | [diff] [blame] | 13 | * @file |
| 14 | * @brief This header provides Ibex-specific functions, such as cycle-accurate |
| 15 | * busy loops. |
Miguel Young de la Sota | dddf1ed | 2019-12-18 12:24:43 -0600 | [diff] [blame] | 16 | */ |
| 17 | |
| 18 | /** |
Alphan Ulusoy | 3e4cd9d | 2020-01-21 15:03:01 -0500 | [diff] [blame] | 19 | * Read the cycle counter. |
Miguel Young de la Sota | dddf1ed | 2019-12-18 12:24:43 -0600 | [diff] [blame] | 20 | * |
Sam Elliott | 812eb33 | 2020-03-31 17:29:35 +0100 | [diff] [blame] | 21 | * 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 Sota | dddf1ed | 2019-12-18 12:24:43 -0600 | [diff] [blame] | 24 | * |
Alphan Ulusoy | 3e4cd9d | 2020-01-21 15:03:01 -0500 | [diff] [blame] | 25 | * Adapted from: The RISC-V Instruction Set Manual, Volume I: Unprivileged ISA |
| 26 | * V20191213, pp. 61. |
Miguel Young de la Sota | dddf1ed | 2019-12-18 12:24:43 -0600 | [diff] [blame] | 27 | */ |
Sam Elliott | 5e5a9dd | 2020-11-10 10:45:48 +0000 | [diff] [blame] | 28 | inline uint64_t ibex_mcycle_read(void) { |
Alphan Ulusoy | 3e4cd9d | 2020-01-21 15:03:01 -0500 | [diff] [blame] | 29 | uint32_t cycle_low = 0; |
| 30 | uint32_t cycle_high = 0; |
| 31 | uint32_t cycle_high_2 = 0; |
Miguel Young de la Sota | dddf1ed | 2019-12-18 12:24:43 -0600 | [diff] [blame] | 32 | asm volatile( |
Alphan Ulusoy | 3e4cd9d | 2020-01-21 15:03:01 -0500 | [diff] [blame] | 33 | "read%=:" |
Sam Elliott | 812eb33 | 2020-03-31 17:29:35 +0100 | [diff] [blame] | 34 | " 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 Ulusoy | 3e4cd9d | 2020-01-21 15:03:01 -0500 | [diff] [blame] | 39 | : "+r"(cycle_high), "=r"(cycle_low), "+r"(cycle_high_2) |
| 40 | :); |
| 41 | return (uint64_t)cycle_high << 32 | cycle_low; |
Miguel Young de la Sota | dddf1ed | 2019-12-18 12:24:43 -0600 | [diff] [blame] | 42 | } |
| 43 | |
Timothy Trippel | 15a0784 | 2021-09-14 19:01:39 +0000 | [diff] [blame^] | 44 | /** |
| 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 | */ |
| 54 | uint32_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 | */ |
| 76 | uint32_t ibex_mtval_read(void); |
| 77 | |
Miguel Young de la Sota | 960fd8e | 2020-01-14 13:52:13 -0500 | [diff] [blame] | 78 | #endif // OPENTITAN_SW_DEVICE_LIB_RUNTIME_IBEX_H_ |