Software APIs
dif_rv_core_ibex.h
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_RV_CORE_IBEX_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_RV_CORE_IBEX_H_
7 
8 #include <stdint.h>
9 
13 
14 #include "sw/device/lib/dif/autogen/dif_rv_core_ibex_autogen.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif // __cplusplus
19 
20 /**
21  * Address translation slot selection.
22  */
23 typedef enum dif_rv_core_ibex_addr_translation_slot {
24  kDifRvCoreIbexAddrTranslationSlot_0,
25  kDifRvCoreIbexAddrTranslationSlot_1,
26  kDifRvCoreIbexAddrTranslationSlotCount,
27 } dif_rv_core_ibex_addr_translation_slot_t;
28 
29 /**
30  * Address translation bus selection.
31  */
32 typedef enum dif_rv_core_ibex_addr_translation_bus {
33  kDifRvCoreIbexAddrTranslationDBus,
34  kDifRvCoreIbexAddrTranslationIBus,
35  kDifRvCoreIbexAddrTranslationBusCount,
36 } dif_rv_core_ibex_addr_translation_bus_t;
37 
38 /**
39  * Address translation matching region.
40  *
41  * The value programmed is done at power-of-2 alignment. For example, if the
42  * intended matching region is 0x8000_0000 to 0x8000_FFFF, the value
43  * programmed is 0x8000_7FFF.
44  *
45  * The value programmed can be determined from the translation granule. Assume
46  * the user wishes to translate a specific 64KB block to a different address:
47  * 64KB has a hex value of 0x10000. Subtract 1 from this value and then right
48  * shift by one to obtain 0x7FFF. This value is then logically OR'd with the
49  * upper address bits that would select which 64KB to translate.
50  */
52  /**
53  * Matching address (Virtual address).
54  * When an incoming transaction matches the matching
55  * region, it is redirected to the new address. If a transaction does not
56  * match, then it is directly passed through.
57  */
58  uintptr_t matching_addr;
59 
60  /**
61  * Remap address (Physical address).
62  * The region where the matched transtaction will be
63  * redirected to.
64  */
65  uintptr_t remap_addr;
66 
67  /**
68  * Address region size.
69  */
70  size_t size;
72 
73 /**
74  * Ibex error status detected by `rv_core_ibex` peripheral.
75  */
76 typedef enum dif_rv_core_ibex_error_status {
77  /**
78  * Register transmission integrity error.
79  */
80  kDifRvCoreIbexErrorStatusRegisterTransmissionIntegrity = 1 << 0,
81 
82  /**
83  * Response integrity error.
84  */
85  kDifRvCoreIbexErrorStatusFatalResponseIntegrity = 1 << 8,
86 
87  /**
88  * Fatal internal error (`alert_major_internal_o` from Ibex seen).
89  */
90  kDifRvCoreIbexErrorStatusFatalInternalError = 1 << 9,
91 
92  /**
93  * recoverable internal error (`alert_minor` from Ibex seen).
94  */
95  kDifRvCoreIbexErrorStatusRecoverableInternal = 1 << 10,
96 
97  /**
98  * All errors combined.
99  */
100  kDifRvCoreIbexErrorStatusAll = (1 << 0 | 1 << 8 | 1 << 9 | 1 << 10),
101 } dif_rv_core_ibex_error_status_t;
102 
103 typedef enum dif_rv_core_ibex_rnd_status_code {
104  /**
105  * The current rnd word is valid.
106  */
107  kDifRvCoreIbexRndStatusValid = 1 << 0,
108  /**
109  * The current rnd word is fips compliant.
110  */
111  kDifRvCoreIbexRndStatusFipsCompliant = 1 << 1,
112 } dif_rv_core_ibex_rnd_status_code_t;
113 
114 /**
115  * Bitmask with the `dif_rv_core_ibex_rnd_status_code_t` values.
116  */
117 typedef uint32_t dif_rv_core_ibex_rnd_status_t;
118 
119 /**
120  * NMI enabled status and current state.
121  */
123  /**
124  * NMI alert is currently enabled.
125  */
127  /**
128  * Alert has been raised.
129  */
131  /**
132  * NMI watchdog is currently enabled.
133  */
135  /**
136  * Watchdog has barked.
137  */
140 
141 typedef enum dif_rv_core_ibex_nmi_source {
142  /**
143  * NMI alert handler.
144  */
145  kDifRvCoreIbexNmiSourceAlert = 1 << 0,
146  /**
147  * NMI watchdog bark.
148  */
149  kDifRvCoreIbexNmiSourceWdog = 1 << 1,
150  /**
151  * All ibex NMIs.
152  */
153  kDifRvCoreIbexNmiSourceAll = 0x3,
154 } dif_rv_core_ibex_nmi_source_t;
155 
157  /**
158  * The last exception address.
159  */
160  uint32_t mtval;
161 
162  /**
163  * The last exception PC.
164  */
165  uint32_t mpec;
166 
167  /**
168  * The last data access address.
169  */
170  uint32_t mdaa;
171 
172  /**
173  * The next PC.
174  */
175  uint32_t mnpc;
176 
177  /**
178  * The current PC.
179  */
180  uint32_t mcpc;
182 
184  /**
185  * The exception address for the previous crash.
186  */
187  uint32_t mtval;
188 
189  /**
190  * The last exception PC for the previous crash.
191  */
192  uint32_t mpec;
194 
195 /**
196  * Under normal circumstances, only the current crash dump state is valid. When
197  * the CPU encounters a double fault, the current crash dump is moved to
198  * previous, and the new crash dump is shown in current.
199  */
201  /**
202  * The crash dump state for the current execution.
203  */
205 
206  /**
207  * The crash dump state for the previous execution. It will only contain valid
208  * data in case of a double fault, which will be indicated by the
209  * `double_fault` member.
210  */
212 
213  /**
214  * `kDifToggleEnabled` if a double fault happened, otherwise
215  * `kDifToggleDisabled`
216  */
219 
220 /**
221  * Configure address translation for
222  * the given `bus` (either instruction or data) in the `slot`.
223  *
224  * @param rv_core_ibex Handle.
225  * @param slot Slot to be used.
226  * @param bus Bus to be translated.
227  * @param addr_map Address mapping description.
228  * @return The result of the operation.
229  */
231 dif_result_t dif_rv_core_ibex_configure_addr_translation(
232  const dif_rv_core_ibex_t *rv_core_ibex,
233  dif_rv_core_ibex_addr_translation_slot_t slot,
234  dif_rv_core_ibex_addr_translation_bus_t bus,
236 
237 /**
238  * Enable address translation for
239  * the given `bus` (either instruction or data) in the `slot`.
240  *
241  * @param rv_core_ibex Handle.
242  * @param slot Slot to be used.
243  * @param bus Bus to be translated.
244  * @return The result of the operation.
245  */
247 dif_result_t dif_rv_core_ibex_enable_addr_translation(
248  const dif_rv_core_ibex_t *rv_core_ibex,
249  dif_rv_core_ibex_addr_translation_slot_t slot,
250  dif_rv_core_ibex_addr_translation_bus_t bus);
251 
252 /**
253  * Disable address translation for
254  * the given `bus` (either instruction or data) in the `slot`.
255  *
256  * @param rv_core_ibex Handle.
257  * @param slot Slot to be used.
258  * @param bus Bus to be translated.
259  * @return The result of the operation.
260  */
262 dif_result_t dif_rv_core_ibex_disable_addr_translation(
263  const dif_rv_core_ibex_t *rv_core_ibex,
264  dif_rv_core_ibex_addr_translation_slot_t slot,
265  dif_rv_core_ibex_addr_translation_bus_t bus);
266 
267 /**
268  * Read a discription of the address mapping configured on a given `slot`
269  * for a given `bus`.
270  *
271  * @param rv_core_ibex Handle.
272  * @param slot Slot of interest.
273  * @param bus Bus of interest.
274  * @param[out] addr_map Description of address mapping.
275  * @return The result of the operation.
276  */
278 dif_result_t dif_rv_core_ibex_read_addr_translation(
279  const dif_rv_core_ibex_t *rv_core_ibex,
280  dif_rv_core_ibex_addr_translation_slot_t slot,
281  dif_rv_core_ibex_addr_translation_bus_t bus,
283 
284 /**
285  * Lock the address translation settings for a given `slot` and `bus` registers.
286  * Once locked it can no longer be unlocked until the next system reset. This
287  * function will quietly do nothing if the settings are already locked.
288  *
289  * @param rv_core_ibex Handle.
290  * @param slot Slot to be locked.
291  * @param bus Translated bus to be locked.
292  * @return The result of the operation.
293  */
295 dif_result_t dif_rv_core_ibex_lock_addr_translation(
296  const dif_rv_core_ibex_t *rv_core_ibex,
297  dif_rv_core_ibex_addr_translation_slot_t slot,
298  dif_rv_core_ibex_addr_translation_bus_t bus);
299 
300 /**
301  * Read the ibex error status.
302  *
303  * @param rv_core_ibex Handle.
304  * @param error_status Pointer to receive the error status value.
305  * @return The result of the operation.
306  */
308 dif_result_t dif_rv_core_ibex_get_error_status(
309  const dif_rv_core_ibex_t *rv_core_ibex,
310  dif_rv_core_ibex_error_status_t *error_status);
311 
312 /**
313  * Clear the ibex error status, after the software has handled it.
314  *
315  * @param rv_core_ibex Handle.
316  * @param error_status The error to be cleared.
317  * @return The result of the operation.
318  */
320 dif_result_t dif_rv_core_ibex_clear_error_status(
321  const dif_rv_core_ibex_t *rv_core_ibex,
322  dif_rv_core_ibex_error_status_t error_status);
323 
324 /**
325  * Enables NMI support for security alert events and watchdog bark.
326  *
327  * @param rv_core_ibex Handle.
328  * @param nmi A bitmask with nmi sources to be enabled.
329  * @return The result of the operation.
330  */
332 dif_result_t dif_rv_core_ibex_enable_nmi(const dif_rv_core_ibex_t *rv_core_ibex,
333  dif_rv_core_ibex_nmi_source_t nmi);
334 
335 /**
336  * Read the NMI enable status and current event state.
337  *
338  * @param rv_core_ibex Handle.
339  * @param[out] nmi_state The nmi state.
340  * @return The result of the operation.
341  */
343 dif_result_t dif_rv_core_ibex_get_nmi_state(
344  const dif_rv_core_ibex_t *rv_core_ibex,
345  dif_rv_core_ibex_nmi_state_t *nmi_state);
346 
347 /**
348  * Clear the NMI current event state.
349  *
350  * @param rv_core_ibex Handle
351  * @param nmi A bitmask with nmi sources to be cleared.
352  * @return The result of the operation.
353  */
355 dif_result_t dif_rv_core_ibex_clear_nmi_state(
356  const dif_rv_core_ibex_t *rv_core_ibex, dif_rv_core_ibex_nmi_source_t nmi);
357 
358 /**
359  * Gets whether the rnd data is either valid or is FIPS compliant.
360  *
361  * @param rv_core_ibex Handle.
362  * @param[out] status Pointer to be filled with the current rnd status.
363  * @return The result of the operation.
364  */
366 dif_result_t dif_rv_core_ibex_get_rnd_status(
367  const dif_rv_core_ibex_t *rv_core_ibex,
368  dif_rv_core_ibex_rnd_status_t *status);
369 
370 /**
371  * Reads a random word from the RISC-V Ibex core wrapper.
372  *
373  * @param rv_core_ibex Handle.
374  * @param[out] data Pointer to be filled with the random word.
375  * @return The result of the operation.
376  */
378 dif_result_t dif_rv_core_ibex_read_rnd_data(
379  const dif_rv_core_ibex_t *rv_core_ibex, uint32_t *data);
380 
381 typedef uint32_t dif_rv_core_ibex_fpga_info_t;
382 
383 /**
384  * Read the FPGA build timestamp info. This function only returns valid data for
385  * fpga environments, for all other environments it is simply 0.
386  *
387  * @param rv_core_ibex Handle.
388  * @param[out] info A pointer to receive the FPGA timestamp info.
389  * @return The result of the operation.
390  */
392 dif_result_t dif_rv_core_ibex_read_fpga_info(
393  const dif_rv_core_ibex_t *rv_core_ibex, dif_rv_core_ibex_fpga_info_t *info);
394 
395 /**
396  * Software fatal alert. When triggered,
397  * a fatal alert is sent. Note, this alert once cleared cannot be set and
398  * will continuously cause alert events.
399  */
400 
401 /**
402  * Get the software recoverable alert sate.
403  *
404  * @param rv_core_ibex Handle.
405  * @param[out] enabled Returns `true` if enabled.
406  * @return The result of the operation.
407  */
408 OT_WARN_UNUSED_RESULT dif_result_t dif_rv_core_ibex_get_sw_recov_err_alert(
409  const dif_rv_core_ibex_t *rv_core_ibex, bool *enabled);
410 
411 /**
412  * Software recoverable alert. When triggered, a recoverable alert is sent. Once
413  * the alert is sent, the register is then reset to disabled.
414  *
415  * @param rv_core_ibex Handle.
416  * @return The result of the operation.
417  */
419 dif_result_t dif_rv_core_ibex_trigger_sw_recov_err_alert(
420  const dif_rv_core_ibex_t *rv_core_ibex);
421 
422 /**
423  * Get the software fatal alert trigger status.
424  *
425  * @param rv_core_ibex Handle.
426  * @param[out] enabled Returns `true` if enabled.
427  * @return The result of the operation.
428  */
430 dif_result_t dif_rv_core_ibex_get_sw_fatal_err_alert(
431  const dif_rv_core_ibex_t *rv_core_ibex, bool *enabled);
432 
433 /**
434  * Software fatal alert. When triggered, a fatal alert is sent. Note, once this
435  * alert is triggered it cannot be reset and will continuously cause alert
436  * events.
437  *
438  * @param rv_core_ibex Handle.
439  * @return The result of the operation.
440  */
442 dif_result_t dif_rv_core_ibex_trigger_sw_fatal_err_alert(
443  const dif_rv_core_ibex_t *rv_core_ibex);
444 
445 /**
446  * Parse the cpu info read from the rstmgr.
447  *
448  * @param rv_core_ibex Handle.
449  * @param cpu_info Buffer with the cpu info read from the rstmgr.
450  * @param cpu_info_len The amount of words in the `cpu_info` buffer.
451  * @param[out] crash_dump_info Parsed dump.
452  * @return The result of the operation.
453  */
455 dif_result_t dif_rv_core_ibex_parse_crash_dump(
456  const dif_rv_core_ibex_t *rv_core_ibex, uint32_t *cpu_info,
457  uint32_t cpu_info_len, dif_rv_core_ibex_crash_dump_info_t *crash_dump_info);
458 
459 #ifdef __cplusplus
460 } // extern "C"
461 #endif // __cplusplus
462 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_RV_CORE_IBEX_H_