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
23 extern "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  */
46 typedef 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,
88 } dif_result_t;
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  */
96 typedef enum dif_toggle {
97  /**
98  * The "disabled" state.
99  */
101  /**
102  * The "enabled" state.
103  */
105 } dif_toggle_t;
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  */
116 typedef 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) {
136  case kDifToggleEnabled:
137  return true;
138  case kDifToggleDisabled:
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) {
154  case kDifToggleEnabled:
155  return true;
156  case kDifToggleDisabled:
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  */
171  return val ? kDifToggleEnabled : kDifToggleDisabled;
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  */
181 inline 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  */
201 inline 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  */
217 inline 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  */
233 inline 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  */
249 inline 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_