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
17extern "C" {
18#endif // __cplusplus
19
20/**
21 * Address translation slot selection.
22 */
23typedef 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 */
32typedef 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;
71} dif_rv_core_ibex_addr_translation_mapping_t;
72
73/**
74 * Ibex error status detected by `rv_core_ibex` peripheral.
75 */
76typedef 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
103typedef 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 */
117typedef 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 */
139} dif_rv_core_ibex_nmi_state_t;
140
141typedef 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;
181} dif_rv_core_ibex_crash_dump_state_t;
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;
193} dif_rv_core_ibex_previous_crash_dump_state_t;
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 */
204 dif_rv_core_ibex_crash_dump_state_t fault_state;
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 */
211 dif_rv_core_ibex_previous_crash_dump_state_t previous_fault_state;
212
213 /**
214 * `kDifToggleEnabled` if a double fault happened, otherwise
215 * `kDifToggleDisabled`
216 */
218} dif_rv_core_ibex_crash_dump_info_t;
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 */
231dif_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,
235 dif_rv_core_ibex_addr_translation_mapping_t addr_map);
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 */
247dif_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 */
262dif_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 */
278dif_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,
282 dif_rv_core_ibex_addr_translation_mapping_t *addr_map);
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 */
295dif_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 */
308dif_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 */
320dif_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 */
332dif_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 */
343dif_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 */
355dif_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 */
366dif_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 */
378dif_result_t dif_rv_core_ibex_read_rnd_data(
379 const dif_rv_core_ibex_t *rv_core_ibex, uint32_t *data);
380
381typedef 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 */
392dif_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 */
408OT_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 */
419dif_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 */
430dif_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 */
442dif_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 */
455dif_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_