Software APIs
dif_lc_ctrl.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors.
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_LC_CTRL_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_LC_CTRL_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/lc_ctrl/doc/">Lifecycle Controller</a> Device
11  * Interface Functions
12  */
13 
14 #include <stdbool.h>
15 #include <stdint.h>
16 
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif // __cplusplus
23 
24 /**
25  * A lifecycle controller status code.
26  *
27  * See `dif_lc_ctrl_get_status()`.
28  */
30  /**
31  * Indicates that the controller has been successfully initialized.
32  */
34  /**
35  * Indicates that the last lifecycle transition succeeded.
36  */
38  /**
39  * Indicates that too many hardware transitions have occurred, and the
40  * hardware will not transition the lifecycle any further.
41  */
43  /**
44  * Indicates that an invalid lifecycle transition was attempted.
45  */
47  /**
48  * Indicates that a bad token was supplied for conditional transition.
49  */
51  /**
52  * Indicates an error during an OTP operation.
53  *
54  * This error will raise an alert.
55  */
57  /**
58  * Indicates an error in the controller's internal state.
59  *
60  * This error will raise an alert.
61  */
64 
65 /**
66  * A bit-vector of `dif_lc_ctrl_status_code_t`s.
67  *
68  * Whether a particular status is contained in this vector can be discovered by
69  * using it as a bit index: `bitfield_bit32_read(status, status_code);`.
70  */
71 typedef uint32_t dif_lc_ctrl_status_t;
72 
73 /**
74  * A lifecycle state.
75  *
76  * This enum represents all states that the lifecycle state register can be in;
77  * some of these do not correspond to "real" lifecycle states, and cannot be
78  * transitioned to.
79  */
80 typedef enum dif_lc_ctrl_state_t {
81  /**
82  * The initial post-manufacture state.
83  *
84  * All functions are disabled.
85  */
87  /**
88  * The zeroth test state.
89  *
90  * Debug functions are enabled.
91  */
93  /**
94  * The zeroth locked test state.
95  *
96  * All functions are disabled.
97  */
99  /**
100  * The first test state.
101  *
102  * Debug functions are enabled.
103  */
105  /**
106  * The first locked test state.
107  *
108  * All functions are disabled.
109  */
111  /**
112  * The second test state.
113  *
114  * Debug functions are enabled.
115  */
117  /**
118  * The second locked test state.
119  *
120  * All functions are disabled.
121  */
123  /**
124  * The third test state.
125  *
126  * Debug functions are enabled.
127  */
129  /**
130  * The development state.
131  *
132  * Some debug functions are enabled.
133  */
135  /**
136  * The main production state.
137  *
138  * No debug functions are enabled.
139  */
141  /**
142  * The EOL production state.
143  *
144  * Same as Prod, except Rma cannot be transitioned to.
145  */
147  /**
148  * RMA manufacturer analysis state.
149  */
151  /**
152  * The scrap EOL state.
153  *
154  * Cannot be transitioned from; all functions are disabled.
155  */
157 
158  /**
159  * State entered immediately after a transition occurs.
160  *
161  * Not a real state.
162  */
164  /**
165  * State entered immediately after an alert is raised.
166  *
167  * Not a real state.
168  */
170  /**
171  * Indicates that the encoded lifecycle is invalid.
172  *
173  * Not a real state.
174  */
177 
178 /**
179  * A personalization state, indicating whether the device has been successfully
180  * personalized.
181  */
182 typedef enum dif_lc_ctrl_id_state {
183  /**
184  * Indicates that the device has not yet been personalized.
185  */
187  /**
188  * Indicates that the device has been personalized.
189  */
191  /**
192  * Indicates that the personalization state is corrupt.
193  */
196 
197 /**
198  * A 128-bit unlock token used for certain kinds of lifecycle transitions.
199  */
200 typedef struct dif_lc_ctrl_token {
201  uint8_t data[128 / 8];
203 
204 /**
205  * Hardware instantiation parameters for a lifecycle controller.
206  *
207  * This struct describes information about the underlying hardware that is
208  * not determined until the hardware design is used as part of a top-level
209  * design.
210  */
211 typedef struct dif_lc_ctrl_params {
212  /**
213  * The base address for the lifecycle controller hardware registers.
214  */
217 
218 /**
219  * A handle to a lifecycle controller.
220  *
221  * This type should be treated as opaque by users.
222  */
223 typedef struct dif_lc_ctrl {
224  dif_lc_ctrl_params_t params;
225 } dif_lc_ctrl_t;
226 
227 /**
228  * The result of a lifecycle controller operation.
229  */
230 typedef enum dif_lc_ctrl_result {
231  /**
232  * Indicates that the operation succeeded.
233  */
235  /**
236  * Indicates some unspecified failure.
237  */
239  /**
240  * Indicates that some parameter passed into a function failed a
241  * precondition.
242  *
243  * When this value is returned, no hardware operations occurred.
244  */
247 
248 /**
249  * The result of a lifecycle attempt counter operation.
250  */
252  /**
253  * Indicates that the operation succeeded.
254  */
256  /**
257  * Indicates some unspecified failure.
258  */
260  /**
261  * Indicates that some parameter passed into a function failed a
262  * precondition.
263  *
264  * When this value is returned, no hardware operations occurred.
265  */
267  /**
268  * Indicates that too many lifecycle transitions have occurred, such that the
269  * hardware can no longer keep a count.
270  */
273 
274 /**
275  * The result of a lifecycle controller operation involving the hardware mutex.
276  */
278  /**
279  * Indicates that the operation succeeded.
280  */
282  /**
283  * Indicates some unspecified failure.
284  */
286  /**
287  * Indicates that some parameter passed into a function failed a
288  * precondition.
289  *
290  * When this value is returned, no hardware operations occurred.
291  */
293 
294  /**
295  * Indicates that a mutex-guarded operation failed because someone (other
296  * than software) is holding it.
297  */
300 
301 /**
302  * An alert that can be raised by the hardware.
303  */
304 typedef enum dif_lc_ctrl_alert {
305  /**
306  * The alert triggered by a `kDifLcCtrlStatusCodeOtpError`.
307  */
309  /**
310  * The alert triggered by a `kDifLcCtrlStatusCodeCorrupt`.
311  */
314 
315 /**
316  * Creates a new handle for the lifecycle controller.
317  *
318  * This function does not actuate the hardware.
319  *
320  * @param params Hardware instantiation parameters.
321  * @param[out] lc Out param for the initialized handle.
322  * @return The result of the operation.
323  */
326  dif_lc_ctrl_t *lc);
327 
328 /**
329  * Returns the current state of the lifecycle controller.
330  *
331  * @param lc A lifecycle handle.
332  * @param[out] state Out-param for the controller's state.
333  * @return The result of the operation.
334  */
337  dif_lc_ctrl_state_t *state);
338 
339 /**
340  * Returns the number of lifecycle transitions that this device has attempted,
341  * up to 16.
342  *
343  * @param lc A lifecycle handle.
344  * @param[out] count Out-param for the number of attempts.
345  * @return The result of the operation.
346  */
348 dif_lc_ctrl_attempts_result_t dif_lc_ctrl_get_attempts(const dif_lc_ctrl_t *lc,
349  uint8_t *count);
350 
351 /**
352  * Returns the current status of the lifecycle controller.
353  *
354  * @param lc A lifecycle handle.
355  * @param[out] status Out-param for the controller's status.
356  * @return The result of the operation.
357  */
360  dif_lc_ctrl_status_t *status);
361 
362 /**
363  * Returns the current personalization state of the lifecycle controller.
364  *
365  * @param lc A lifecycle handle.
366  * @param[out] state Out-param for the controller's personalization state.
367  * @return The result of the operation.
368  */
371  dif_lc_ctrl_id_state_t *state);
372 
373 /**
374  * Forces a particular alert, causing it to be escalated as if the hardware had
375  * raised it.
376  *
377  * @param lc A lifecycle handle.
378  * @param alert The alert to force.
379  * @return The result of the operation.
380  */
383  dif_lc_ctrl_alert_t alert);
384 
385 /**
386  * Attempts to acquire the lifecycle controller's HW mutex.
387  *
388  * Returns `kDifLcCtrlMutexHeld` if acquisition fails. It is recommended to
389  * call this function in a busy loop to acquire the mutex.
390  *
391  * @param lc A lifecycle handle.
392  * @return The result of the operation.
393  */
394 // Open Q: do we want to be checking REGWEN for all operations dependent on the
395 // mutex?
398  const dif_lc_ctrl_t *lc);
399 
400 /**
401  * Releases the lifecycle controller's HW mutex.
402  *
403  * Calls to this function must be sequenced with successful calls to
404  * `dif_lc_ctrl_mutex_try_acquire()`.
405  *
406  * @param lc A lifecycle handle.
407  * @return The result of the operation.
408  */
411 
412 /**
413  * Performs a lifecycle transition.
414  *
415  * Note that not all transitions require an unlock token; in that case, NULL
416  * should be passed as the token.
417  *
418  * @param lc A lifecycle handle.
419  * @param state The state to transition to.
420  * @param token A token for unlocking the transition; may be null.
421  * @return The result of the operation.
422  */
425  const dif_lc_ctrl_t *lc, dif_lc_ctrl_state_t state,
426  const dif_lc_ctrl_token_t *token);
427 
428 #ifdef __cplusplus
429 } // extern "C"
430 #endif // __cplusplus
431 
432 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_LC_CTRL_H_