Software APIs
dif_base.h
Go to the documentation of this file.
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_BASE_H_
6#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_BASE_H_
7
8/**
9 * @file
10 * @brief Shared macros and headers for DIFs.
11 */
12
13#include <stdbool.h>
14
16#include "sw/device/lib/base/multibits.h"
17
18#define USING_INTERNAL_STATUS
19#include "sw/device/lib/base/internal/status.h"
20#undef USING_INTERNAL_STATUS
21
22#ifdef __cplusplus
23extern "C" {
24#endif // __cplusplus
25
26/**
27 * Evaluate an expression and return if the result is an error.
28 *
29 * @param expr_ An expression which results in an dif_result_t.
30 */
31#define DIF_RETURN_IF_ERROR(expr_) \
32 do { \
33 dif_result_t local_error_ = (expr_); \
34 if (local_error_ != kDifOk) { \
35 return local_error_; \
36 } \
37 } while (false)
38
39/**
40 * The result of a DIF operation.
41 *
42 * NOTE: additional result values can be defined in the manually-implemented
43 * header by creating an additional *_result_t enum type. See the Lifecycle
44 * Controller DIF for how this may be implemented.
45 */
46typedef enum dif_result {
47 /**
48 * Indicates that the operation succeeded.
49 */
50 kDifOk = kOk,
51 /**
52 * Indicates some unspecified failure.
53 */
54 kDifError = kInternal,
55 /**
56 * Indicates that some parameter passed into a function failed a
57 * precondition.
58 *
59 * When this value is returned, no hardware operations occurred.
60 */
61 kDifBadArg = kInvalidArgument,
62 /**
63 * The operation failed because writes to a required register are
64 * disabled.
65 */
66 kDifLocked = kFailedPrecondition,
67 /**
68 * The operation failed because the IP is processing an operation, and will
69 * finish in some amount of time. A function that returns this error may be
70 * retried at any time, and is guaranteed to have not produced any side
71 * effects.
72 */
73 kDifUnavailable = kUnavailable,
74 /**
75 * Indicates that the Ip's FIFO (if it has one or more of) is full.
76 */
77 kDifIpFifoFull = kResourceExhausted,
78 /**
79 * Indicates that the attempted operation would attempt a read/write to an
80 * address that would go out of range.
81 */
82 kDifOutOfRange = kOutOfRange,
83 /**
84 * Indicates that the attempted operation would attempt a read/write to an
85 * address that is not aligned.
86 */
87 kDifUnaligned = kUnimplemented,
89
90/**
91 * A toggle state: enabled, or disabled.
92 *
93 * This enum may be used instead of a `bool` when describing an enabled/disabled
94 * state.
95 */
96typedef enum dif_toggle {
97 /**
98 * The "disabled" state.
99 */
101 /**
102 * The "enabled" state.
103 */
106
107/**
108 * An interrupt type: event, or status.
109 *
110 * This enum may be used instead when describing an interrupt type.
111 * Specifically, event interrupts require software to manually clear them by
112 * writing to the interrupt status register (after handling the root cause),
113 * while status interrupts clear immediately when the root cause of the iterrupt
114 * has been handled.
115 */
116typedef enum dif_irq_type {
117 /**
118 * Event type interrupt.
119 */
121 /**
122 * Status type interrupt.
123 */
126
127/**
128 * Checks if a DIF toggle type is valid.
129 *
130 * @param val A potential dif_toggle_t value.
131 * @return Bool indicating validity of toggle value.
132 */
135 switch (val) {
137 return true;
139 return true;
140 default:
141 return false;
142 }
143}
144
145/**
146 * Converts a `dif_toggle_t` to a `bool`.
147 *
148 * @param val A dif_toggle_t value.
149 * @return Corresponding bool value.
150 */
153 switch (val) {
155 return true;
157 return false;
158 default:
159 return false;
160 }
161}
162
163/**
164 * Converts a bool to a `dif_toggle_t`.
165 *
166 * @param val A bool value.
167 * @return Corresponding dif_toggle_t value.
168 */
172}
173
174/**
175 * Converts a multi-bit bool to a `dif_toggle_t`.
176 *
177 * @param val A multi-bit bool value.
178 * @return Corresponding dif_toggle_t value.
179 */
181inline dif_toggle_t dif_multi_bit_bool_to_toggle(multi_bit_bool_t val) {
182 switch (val) {
183 case kMultiBitBool4True:
184 case kMultiBitBool8True:
185 case kMultiBitBool12True:
186 case kMultiBitBool16True:
187 return kDifToggleEnabled;
188 default:
189 return kDifToggleDisabled;
190 }
191}
192
193/**
194 * Converts a `dif_toggle_t` to a `multi_bit_bool_t` of 4 bits.
195 *
196 * @param val A `dif_toggle_t` value.
197 * @return Corresponding `multi_bit_bool_t` value. Invalid values resolve to
198 * "false".
199 */
201inline multi_bit_bool_t dif_toggle_to_multi_bit_bool4(dif_toggle_t val) {
202 if (val == kDifToggleEnabled) {
203 return kMultiBitBool4True;
204 } else {
205 return kMultiBitBool4False;
206 }
207}
208
209/**
210 * Converts a `dif_toggle_t` to a `multi_bit_bool_t` of 8 bits.
211 *
212 * @param val A `dif_toggle_t` value.
213 * @return Corresponding `multi_bit_bool_t` value. Invalid values resolve to
214 * "false".
215 */
217inline multi_bit_bool_t dif_toggle_to_multi_bit_bool8(dif_toggle_t val) {
218 if (val == kDifToggleEnabled) {
219 return kMultiBitBool8True;
220 } else {
221 return kMultiBitBool8False;
222 }
223}
224
225/**
226 * Converts a `dif_toggle_t` to a `multi_bit_bool_t` of 12 bits.
227 *
228 * @param val A `dif_toggle_t` value.
229 * @return Corresponding `multi_bit_bool_t` value. Invalid values resolve to
230 * "false".
231 */
233inline multi_bit_bool_t dif_toggle_to_multi_bit_bool12(dif_toggle_t val) {
234 if (val == kDifToggleEnabled) {
235 return kMultiBitBool12True;
236 } else {
237 return kMultiBitBool12False;
238 }
239}
240
241/**
242 * Converts a `dif_toggle_t` to a `multi_bit_bool_t` of 16 bits.
243 *
244 * @param val A `dif_toggle_t` value.
245 * @return Corresponding `multi_bit_bool_t` value. Invalid values resolve to
246 * "false".
247 */
249inline multi_bit_bool_t dif_toggle_to_multi_bit_bool16(dif_toggle_t val) {
250 if (val == kDifToggleEnabled) {
251 return kMultiBitBool16True;
252 } else {
253 return kMultiBitBool16False;
254 }
255}
256
257#ifdef __cplusplus
258} // extern "C"
259#endif // __cplusplus
260
261#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_BASE_H_