Software APIs
lifecycle.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_SILICON_CREATOR_LIB_DRIVERS_LIFECYCLE_H_
6#define OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_LIFECYCLE_H_
7
8#include <stdbool.h>
9#include <stdint.h>
10
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
18/**
19 * Lifecycle states.
20 *
21 * This is a condensed version of the 24 possible life cycle states where
22 * TEST_UNLOCKED_* states are mapped to `kLcStateTest` and invalid states where
23 * CPU execution is disabled are omitted.
24 *
25 * Encoding generated with
26 * $ ./util/design/sparse-fsm-encode.py -d 6 -m 5 -n 32 \
27 * -s 2447090565 --language=c
28 *
29 * Minimum Hamming distance: 13
30 * Maximum Hamming distance: 19
31 * Minimum Hamming weight: 15
32 * Maximum Hamming weight: 20
33 */
34typedef enum lifecycle_state {
35 /**
36 * Unlocked test state where debug functions are enabled.
37 *
38 * Corresponds to TEST_UNLOCKED_* life cycle states.
39 */
40 kLcStateTest = 0xb2865fbb,
41 /**
42 * Development life cycle state where limited debug functionality is
43 * available.
44 */
45 kLcStateDev = 0x0b5a75e0,
46 /**
47 * Production life cycle state.
48 */
49 kLcStateProd = 0x65f2520f,
50 /**
51 * Same as PROD, but transition into RMA is not possible from this state.
52 */
53 kLcStateProdEnd = 0x91b9b68a,
54 /**
55 * RMA life cycle state.
56 */
57 kLcStateRma = 0xcf8cfaab,
58} lifecycle_state_t;
59
60enum {
61 /**
62 * Size of the device identifier in words.
63 */
64 kLifecycleDeviceIdNumWords = 8,
65};
66
67/**
68 * 256-bit device identifier that is stored in the `HW_CFG0` partition in OTP.
69 */
70typedef struct lifecycle_device_id {
71 uint32_t device_id[kLifecycleDeviceIdNumWords];
72} lifecycle_device_id_t;
73
74/**
75 * Hardware revision.
76 *
77 * Consists of a 16-bit silicon creator ID,
78 * a 16-bit product ID and an 8bit revision ID.
79 */
80typedef struct lifecycle_hw_rev {
81 uint16_t silicon_creator_id;
82 uint16_t product_id;
83 uint8_t revision_id;
84} lifecycle_hw_rev_t;
85
86/**
87 * Get the life cycle state.
88 *
89 * This function checks the value read from the hardware and returns a
90 * `life_cycle_state_t`. See `life_cyle_state_t` for more details.
91 *
92 * @return Life cycle state.
93 */
95lifecycle_state_t lifecycle_state_get(void);
96
97/**
98 * Check if the device is in prod state.
99 *
100 * Warning: This function also returns false when LCS is invalid.
101 *
102 * @return `kHardenedBoolTrue` if the device is in prod state.
103 */
105hardened_bool_t lifecycle_is_prod(void);
106
107/**
108 * Get the unprocessed life cycle state value read from the hardware.
109 *
110 * This function directly returns the `uint32_t` value read from the hardware.
111 *
112 * @return Life cycle state.
113 */
115uint32_t lifecycle_raw_state_get(void);
116
117/**
118 * Get the device identifier.
119 *
120 * @param[out] device_id 256-bit device identifier that is stored in the
121 * `HW_CFG0` partition in OTP.
122 */
123void lifecycle_device_id_get(lifecycle_device_id_t *device_id);
124
125/**
126 * Get the hardware revision.
127 *
128 * @param[out] hw_rev Hardware revision.
129 */
130void lifecycle_hw_rev_get(lifecycle_hw_rev_t *hw_rev);
131
132/**
133 * Determine if the device identification number subfield of the Device Id is
134 * equal to the supplied DIN.
135 *
136 * @returns kHardenedBoolTrue if equal, kHardenedBoolFalse if not equal.
137 */
138hardened_bool_t lifecycle_din_eq(lifecycle_device_id_t *id, uint32_t *din);
139
140typedef enum lifecycle_status_word {
141 kLifecycleStatusWordRomExtVersion = 0,
142 kLifecycleStatusWordRomExtSecVersion = 1,
143 kLifecycleStatusWordOwnerVersion = 2,
144 kLifecycleStatusWordDeviceStatus = 3,
145} lifecycle_status_word_t;
146
147/**
148 * Device Status.
149 *
150 * These identifiers refer to boot stages observed during production.
151 * Firmware will program these identifiers into the lifecycle controller's
152 * TRANSITION_TOKEN registers so they can be read out via JTAG during the
153 * manufacturing process.
154 */
155typedef enum lifecycle_device_status {
156 /** Default 0: an invalid state. */
157 kLifecycleDeviceStatusDefault = 0,
158 /**
159 * ROM_EXT:
160 * - OK: 0x00000001 - 0x00000FFF
161 * - Err: 0x10000001 - 0x10000FFF
162 */
163 kLifecycleDeviceStatusRomExtStart = 0x1,
164 /**
165 * Perso Firmware:
166 * - OK: 0x00001000 - 0x00001FFF
167 * - Err: 0x10001000 - 0x10001FFF
168 */
169 kLifecycleDeviceStatusPersoStart = 0x1000,
170 /**
171 * Owner (application) Firmware:
172 * - OK: 0x00002000 - 0x00002FFF
173 * - Err: 0x10002000 - 0x10002FFF
174 */
175 kLifecycleDeviceStatusOwnerStart = 0x2000,
176} lifecycle_device_status_t;
177
178/**
179 * Claim the lifecycle controller transition interface.
180 *
181 * @param claim Either kMultiBitBool8True to claim or kMultiBitBool8False to
182 * release.
183 * @return Whether or not the interface was claimed.
184 */
185bool lifecycle_claim(uint32_t claim);
186
187/**
188 * Write the boot stage information into the TRANSITION_TOKEN registers.
189 *
190 * Silicon_creator information is written to token registers 0-1. Silicon_owner
191 * information is written to token registers 2-3.
192 */
193void lifecycle_set_status(lifecycle_status_word_t word, uint32_t value);
194
195#ifdef __cplusplus
196}
197#endif
198#endif // OPENTITAN_SW_DEVICE_SILICON_CREATOR_LIB_DRIVERS_LIFECYCLE_H_