Software APIs
dif_sram_ctrl.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_SRAM_CTRL_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SRAM_CTRL_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/sram_ctrl/doc/">SRAM Controller</a> Device Interface
11  * Functions
12  */
13 
14 #include <stdint.h>
15 
16 #include "sw/device/lib/base/multibits.h"
17 
18 #include "sw/device/lib/dif/autogen/dif_sram_ctrl_autogen.h"
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif // __cplusplus
23 
24 /**
25  * SRAM Controller status information bitfield.
26  */
28 
29 /**
30  * SRAM Controller status flags.
31  *
32  * Invariants are used to extract information encoded in
33  * `dif_sram_ctrl_status_bitfield_t`.
34  *
35  * More than one status flag can be set at the same time, and a caller may use
36  * these invariants to look-up individual or a group of flags.
37  *
38  * Note: these must match the autogenerated register definition bit offsets.
39  */
40 typedef enum dif_sram_ctrl_status {
41  /**
42  * Bus integrity fault is detected. This error triggers a fatal_error alert.
43  * This condition is terminal.
44  */
46  /**
47  * Initialization counter has reached an invalid state. This error triggers
48  * a fatal_error alert. This condition is terminal.
49  */
51  /**
52  * SRAM Controller has received an escalate request, the scrambling keys have
53  * been reset to the default values and all subsequent memory requests will
54  * be blocked. This condition is terminal.
55  */
57  /**
58  * New scrambling key has been successfully obtained from OTP. If the flag is
59  * not set, the SRAM contents are still scrambled, but a default all-zero key
60  * and nonce are used to do so.
61  */
63  /**
64  * Scrambling key has been derived from a valid key seed in OTP. When
65  * `kDifSramCtrlStatusScrKeyValid` is set, but this flag is unset - the
66  * scrambling key is still ephemeral (i.e., it is derived using entropy from
67  * CSRNG), but a default all-zero value is used as the key seed. This could
68  * happen when the scrambling key seeds have not yet been provisioned to OTP.
69  */
71  /**
72  * Hardware initialization triggered via `dif_sram_ctrl_scramble` or
73  * `dif_sram_ctrl_wipe` has completed.
74  */
77 
78 /**
79  * SRAM Controller lockable functionality.
80  */
81 typedef enum dif_sram_ctrl_lock {
82  /**
83  * SRAM scrambling key renewal and "wiping" lock, which includes the following
84  * API: `dif_sram_ctrl_scramble`, `dif_sram_ctrl_request_new_key`
85  * and `dif_sram_ctrl_wipe`.
86  */
88  /**
89  * Code execution from SRAM lock, which includes the following API:
90  * `dif_sram_ctrl_exec_set_enabled`.
91  *
92  * Note: this setting may not be available depending on the OTP configuration
93  * of the chip (EN_SRAM_IFETCH fuse).
94  */
96  /**
97  * Readback feature lock. When locked, disabling or enabling the SRAM readback
98  * feature is not available anymore. Includes the following API:
99  * `dif_sram_ctrl_readback_set`.
100  */
103 
104 /**
105  * Performs blocking SRAM scrambling operation.
106  *
107  * This function should only be called when the data is no longer used.
108  *
109  * This is a compound operation covering both data and address "scrambling".
110  * In other words logical re-mapping of the physical addresses and data
111  * scrambling, followed by the entire SRAM overwriting with a pseudo-random
112  * data.
113  *
114  * The intention of this operation is to ensure that there is no predefined
115  * values or predictable data that could potentially make "unscrambling"
116  * easier.
117  *
118  * This operation is expected to take a significant amount of CPU cycles. If
119  * a non-blocking alternative is required, then `dif_sram_ctrl_request_new_key`,
120  * should be used followed by `dif_sram_ctrl_wipe`. The status of these
121  * operations can be found through `dif_sram_ctrl_get_status`.
122  *
123  * Note: when dealing with the Main RAM, additional implication is that the
124  * C runtime can be invalidated by the call to this function, and must be
125  * re-configured prior to any C code execution.
126  *
127  * @param sram_ctrl A SRAM Controller handle.
128  * @return The result of the operation.
129  */
131 dif_result_t dif_sram_ctrl_scramble(const dif_sram_ctrl_t *sram_ctrl);
132 
133 /**
134  * Requests a new scrambling key.
135  *
136  * This function should only be called when the data is no longer used.
137  *
138  * On successful completion SRAM addresses (due to different logical mapping of
139  * the physical addresses) and the data are scrambled. However, it is
140  * recommended to additionally overwrite SRAM with pseudo-random data by calling
141  * `dif_sram_ctrl_wipe`. This should minimize the chances of revealing the XOR
142  * key-stream.
143  *
144  * This operation is expected to take a significant amount of CPU cycles. The
145  * status can be checked via `kDifSramCtrlStatusScrKeyValid`, which is useful
146  * when a non-blocking work flow is desirable. Otherwise any SRAM access will
147  * automatically block until this operation has finished.
148  *
149  * Note: when dealing with the Main RAM, additional implication is that the
150  * C runtime can be invalidated by the call to this function, and must be
151  * re-configured prior to any C code execution.
152  *
153  * Note: during an ongoing memory initialization, the hardware ignores the key
154  * request.
155  *
156  * @param sram_ctrl A SRAM Controller handle.
157  * @return The result of the operation.
158  */
160 dif_result_t dif_sram_ctrl_request_new_key(const dif_sram_ctrl_t *sram_ctrl);
161 
162 /**
163  * Overwrites "wipes" the entire SRAM with pseudo-random data.
164  *
165  * This function should only be called when the data is no longer used.
166  *
167  * This operation is expected to take a significant amount of CPU cycles. The
168  * status can be checked via `kDifSramCtrlStatusInitDone`, which is useful when
169  * a non-blocking work flow is desirable. Otherwise any SRAM access will
170  * automatically block until this operation has finished.
171  *
172  * Note: when dealing with the Main RAM, additional implication is that the
173  * C runtime can be invalidated by the call to this function, and must be
174  * re-configured prior to any C code execution.
175  *
176  * Note: during this memory initialization, the hardware ignores key requests
177  * that are issued while this operation is pending.
178  *
179  * @param sram_ctrl A SRAM Controller handle.
180  * @return The result of the operation.
181  */
183 dif_result_t dif_sram_ctrl_wipe(const dif_sram_ctrl_t *sram_ctrl);
184 
185 /**
186  * Checks whether execution from SRAM is currently enabled or disabled.
187  *
188  * @param sram_ctrl A SRAM Controller handle.
189  * @param[out] state Out-param toggle state of the SRAM execution.
190  * @return The result of the operation.
191  */
193 dif_result_t dif_sram_ctrl_exec_get_enabled(const dif_sram_ctrl_t *sram_ctrl,
194  dif_toggle_t *state);
195 
196 /**
197  * Sets whether execution from SRAM enabled or disabled.
198  *
199  * @param sram_ctrl A SRAM Controller handle.
200  * @param state The new toggle state for the SRAM execution.
201  * @return The result of the operation.
202  */
204 dif_result_t dif_sram_ctrl_exec_set_enabled(const dif_sram_ctrl_t *sram_ctrl,
205  dif_toggle_t state);
206 
207 /**
208  * Sets whether the SRAM readback feature is enabled or disabled.
209  *
210  * @param sram_ctrl A SRAM Controller handle.
211  * @param state The new toggle state for the SRAM readback feature.
212  * @return The result of the operation.
213  */
215 dif_result_t dif_sram_ctrl_readback_set(const dif_sram_ctrl_t *sram_ctrl,
216  dif_toggle_t state);
217 
218 /**
219  * Queries the SRAM Controller status.
220  *
221  * `dif_sram_ctrl_status_t` is used to then extract individual status bits.
222  *
223  * @param sram_ctrl A SRAM Controller handle.
224  * @param[out] SRAM Controller status bitfield.
225  * @return The result of the operation.
226  */
228 dif_result_t dif_sram_ctrl_get_status(const dif_sram_ctrl_t *sram_ctrl,
230 
231 /**
232  * Locks out requested SRAM Controller functionality.
233  *
234  * This function is reentrant: calling it while functionality is locked will
235  * have no effect and return `kDifOk`.
236  *
237  * @param sram_ctrl A SRAM Controller handle.
238  * @param lock SRAM functionality to lock.
239  * @return The result of the operation.
240  */
242 dif_result_t dif_sram_ctrl_lock(const dif_sram_ctrl_t *sram_ctrl,
243  dif_sram_ctrl_lock_t lock);
244 
245 /**
246  * Checks whether requested SRAM Controller functionality is locked.
247  *
248  * @param sram_ctrl A SRAM Controller handle.
249  * @param lock SRAM functionality to query locked state for.
250  * @param[out] is_locked Out-param for the locked state.
251  * @return The result of the operation.
252  */
254 dif_result_t dif_sram_ctrl_is_locked(const dif_sram_ctrl_t *sram_ctrl,
256  bool *is_locked);
257 
258 /**
259  * Checks whether requested SRAM Controller successfully obtained a new key.
260  *
261  * success is set to kMultiBitBool4True if a key rotation was successful.
262  *
263  * The clear parameter can be set to kMultiBitBool4True in order to clear
264  * the key rotation state back to kMultiBitBool4False after reading it.
265  * If the state should not be cleared, set clear to kMultiBitBool4False.
266  *
267  * @param sram_ctrl A SRAM Controller handle.
268  * @param[out] success Outparam for the success state.
269  * @param clear Parameter indicating whether to CSR should be cleared after
270  * reading.
271  * @return The result of the operation.
272  */
274 dif_result_t dif_sram_ctrl_scr_key_rotated(const dif_sram_ctrl_t *sram_ctrl,
275  multi_bit_bool_t *success,
276  multi_bit_bool_t clear);
277 
278 #ifdef __cplusplus
279 } // extern "C"
280 #endif // __cplusplus
281 
282 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_SRAM_CTRL_H_