1 /*
2  * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _ROM_EFUSE_H_
8 #define _ROM_EFUSE_H_
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 #include <stdint.h>
15 #include <stddef.h>
16 #include <stdbool.h>
17 
18 /** \defgroup efuse_APIs efuse APIs
19   * @brief     ESP32 efuse read/write APIs
20   * @attention
21   *
22   */
23 
24 /** @addtogroup efuse_APIs
25   * @{
26   */
27 
28 typedef enum {
29     ETS_EFUSE_KEY_PURPOSE_USER = 0,
30     ETS_EFUSE_KEY_PURPOSE_ECDSA_KEY = 1,
31     ETS_EFUSE_KEY_PURPOSE_RESERVED = 2,
32     ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY = 4,
33     ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL = 5,
34     ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG = 6,
35     ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE = 7,
36     ETS_EFUSE_KEY_PURPOSE_HMAC_UP = 8,
37     ETS_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0 = 9,
38     ETS_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1 = 10,
39     ETS_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2 = 11,
40     ETS_EFUSE_KEY_PURPOSE_MAX,
41 } ets_efuse_purpose_t;
42 
43 typedef enum {
44     ETS_EFUSE_BLOCK0 = 0,
45     ETS_EFUSE_MAC_SPI_SYS_0 = 1,
46     ETS_EFUSE_BLOCK_SYS_DATA = 2,
47     ETS_EFUSE_BLOCK_USR_DATA = 3,
48     ETS_EFUSE_BLOCK_KEY0 = 4,
49     ETS_EFUSE_BLOCK_KEY1 = 5,
50     ETS_EFUSE_BLOCK_KEY2 = 6,
51     ETS_EFUSE_BLOCK_KEY3 = 7,
52     ETS_EFUSE_BLOCK_KEY4 = 8,
53     ETS_EFUSE_BLOCK_KEY5 = 9,
54     ETS_EFUSE_BLOCK_KEY6 = 10,
55     ETS_EFUSE_BLOCK_MAX,
56 } ets_efuse_block_t;
57 
58 /**
59   * @brief  Efuse read operation: copies data from physical efuses to efuse read registers.
60   *
61   * @param  null
62   *
63   * @return : 0 if success, others if apb clock is not accepted
64   */
65 int ets_efuse_read(void);
66 
67 /**
68   * @brief  Efuse write operation: Copies data from efuse write registers to efuse. Operates on a single block of efuses at a time.
69   *
70   * @note This function does not update read efuses, call ets_efuse_read() once all programming is complete.
71   *
72   * @return : 0 if success, others if apb clock is not accepted
73   */
74 int ets_efuse_program(ets_efuse_block_t block);
75 
76 /**
77  * @brief Set all Efuse program registers to zero.
78  *
79  * Call this before writing new data to the program registers.
80  */
81 void ets_efuse_clear_program_registers(void);
82 
83 /**
84  * @brief Program a block of key data to an efuse block
85  *
86  * @param key_block Block to read purpose for. Must be in range ETS_EFUSE_BLOCK_KEY0 to ETS_EFUSE_BLOCK_KEY6. Key block must be unused (@ref ets_efuse_key_block_unused).
87  * @param purpose Purpose to set for this key. Purpose must be already unset.
88  * @param data Pointer to data to write.
89  * @param data_len Length of data to write.
90  *
91  * @note This function also calls ets_efuse_program() for the specified block, and for block 0 (setting the purpose)
92  */
93 int ets_efuse_write_key(ets_efuse_block_t key_block, ets_efuse_purpose_t purpose, const void *data, size_t data_len);
94 
95 
96 /* @brief Return the address of a particular efuse block's first read register
97  *
98  * @param block Index of efuse block to look up
99  *
100  * @return 0 if block is invalid, otherwise a numeric read register address
101  * of the first word in the block.
102  */
103 uint32_t ets_efuse_get_read_register_address(ets_efuse_block_t block);
104 
105 /**
106  * @brief Return the current purpose set for an efuse key block
107  *
108  * @param key_block Block to read purpose for. Must be in range ETS_EFUSE_BLOCK_KEY0 to ETS_EFUSE_BLOCK_KEY6.
109  */
110 ets_efuse_purpose_t ets_efuse_get_key_purpose(ets_efuse_block_t key_block);
111 
112 /**
113  * @brief Find a key block with the particular purpose set
114  *
115  * @param purpose Purpose to search for.
116  * @param[out] key_block Pointer which will be set to the key block if found. Can be NULL, if only need to test the key block exists.
117  * @return true if found, false if not found. If false, value at key_block pointer is unchanged.
118  */
119 bool ets_efuse_find_purpose(ets_efuse_purpose_t purpose, ets_efuse_block_t *key_block);
120 
121 /**
122  * Return true if the key block is unused, false otherwise.
123  *
124  * An unused key block is all zero content, not read or write protected,
125  * and has purpose 0 (ETS_EFUSE_KEY_PURPOSE_USER)
126  *
127  * @param key_block key block to check.
128  *
129  * @return true if key block is unused, false if key block or used
130  * or the specified block index is not a key block.
131  */
132 bool ets_efuse_key_block_unused(ets_efuse_block_t key_block);
133 
134 
135 /**
136  * @brief Search for an unused key block and return the first one found.
137  *
138  * See @ref ets_efuse_key_block_unused for a description of an unused key block.
139  *
140  * @return First unused key block, or ETS_EFUSE_BLOCK_MAX if no unused key block is found.
141  */
142 ets_efuse_block_t ets_efuse_find_unused_key_block(void);
143 
144 /**
145  * @brief Return the number of unused efuse key blocks (0-6)
146  */
147 unsigned ets_efuse_count_unused_key_blocks(void);
148 
149 /**
150  * @brief Calculate Reed-Solomon Encoding values for a block of efuse data.
151  *
152  * @param data Pointer to data buffer (length 32 bytes)
153  * @param rs_values Pointer to write encoded data to (length 12 bytes)
154  */
155 void ets_efuse_rs_calculate(const void *data, void *rs_values);
156 
157 /**
158   * @brief  Read if download mode disabled from Efuse
159   *
160   * @return
161   * - true for efuse disable download mode.
162   * - false for efuse doesn't disable download mode.
163   */
164 bool ets_efuse_download_modes_disabled(void);
165 
166 /**
167   * @brief  Read if uart print control value from Efuse
168   *
169   * @return
170   * - 0 for uart force print.
171   * - 1 for uart print when GPIO8 is low when digital reset.
172   *   2 for uart print when GPIO8 is high when digital reset.
173   *   3 for uart force slient
174   */
175 uint32_t ets_efuse_get_uart_print_control(void);
176 
177 /**
178   * @brief  Read if usb download mode disabled from Efuse
179   *
180   * (Also returns true if security download mode is enabled, as this mode
181   * disables USB download.)
182   *
183   * @return
184   * - true for efuse disable usb download mode.
185   * - false for efuse doesn't disable usb download mode.
186   */
187 bool ets_efuse_usb_download_mode_disabled(void);
188 
189 /**
190   * @brief  Read if security download modes enabled from Efuse
191   *
192   * @return
193   * - true for efuse enable security download mode.
194   * - false for efuse doesn't enable security download mode.
195   */
196 bool ets_efuse_security_download_modes_enabled(void);
197 
198 /**
199  * @brief Return true if secure boot is enabled in EFuse
200  */
201 bool ets_efuse_secure_boot_enabled(void);
202 
203 /**
204  * @brief Return true if secure boot aggressive revoke is enabled in EFuse
205  */
206 bool ets_efuse_secure_boot_aggressive_revoke_enabled(void);
207 
208 /**
209  * @brief Return true if cache encryption (flash, etc) is enabled from boot via EFuse
210  */
211 bool ets_efuse_cache_encryption_enabled(void);
212 
213 /**
214  * @brief Return true if EFuse indicates to send a flash resume command.
215  */
216 bool ets_efuse_force_send_resume(void);
217 
218 /**
219   * @brief  return the time in us ROM boot need wait flash to power on from Efuse
220   *
221   * @return
222   * - uint32_t the time in us.
223   */
224 uint32_t ets_efuse_get_flash_delay_us(void);
225 
226 #define EFUSE_SPICONFIG_SPI_DEFAULTS 0
227 #define EFUSE_SPICONFIG_HSPI_DEFAULTS 1
228 
229 #define EFUSE_SPICONFIG_RET_SPICLK_MASK         0x3f
230 #define EFUSE_SPICONFIG_RET_SPICLK_SHIFT        0
231 #define EFUSE_SPICONFIG_RET_SPICLK(ret)         (((ret) >> EFUSE_SPICONFIG_RET_SPICLK_SHIFT) & EFUSE_SPICONFIG_RET_SPICLK_MASK)
232 
233 #define EFUSE_SPICONFIG_RET_SPIQ_MASK           0x3f
234 #define EFUSE_SPICONFIG_RET_SPIQ_SHIFT          6
235 #define EFUSE_SPICONFIG_RET_SPIQ(ret)           (((ret) >> EFUSE_SPICONFIG_RET_SPIQ_SHIFT) & EFUSE_SPICONFIG_RET_SPIQ_MASK)
236 
237 #define EFUSE_SPICONFIG_RET_SPID_MASK           0x3f
238 #define EFUSE_SPICONFIG_RET_SPID_SHIFT          12
239 #define EFUSE_SPICONFIG_RET_SPID(ret)           (((ret) >> EFUSE_SPICONFIG_RET_SPID_SHIFT) & EFUSE_SPICONFIG_RET_SPID_MASK)
240 
241 #define EFUSE_SPICONFIG_RET_SPICS0_MASK         0x3f
242 #define EFUSE_SPICONFIG_RET_SPICS0_SHIFT        18
243 #define EFUSE_SPICONFIG_RET_SPICS0(ret)         (((ret) >> EFUSE_SPICONFIG_RET_SPICS0_SHIFT) & EFUSE_SPICONFIG_RET_SPICS0_MASK)
244 
245 
246 #define EFUSE_SPICONFIG_RET_SPIHD_MASK          0x3f
247 #define EFUSE_SPICONFIG_RET_SPIHD_SHIFT         24
248 #define EFUSE_SPICONFIG_RET_SPIHD(ret)          (((ret) >> EFUSE_SPICONFIG_RET_SPIHD_SHIFT) & EFUSE_SPICONFIG_RET_SPIHD_MASK)
249 
250 /**
251  * @brief Enable JTAG temporarily by writing a JTAG HMAC "key" into
252  * the JTAG_CTRL registers.
253  *
254  * Works if JTAG has been "soft" disabled by burning the EFUSE_SOFT_DIS_JTAG efuse.
255  *
256  * Will enable the HMAC module to generate a "downstream" HMAC value from a key already saved in efuse, and then write the JTAG HMAC "key" which will enable JTAG if the two keys match.
257  *
258  * @param jtag_hmac_key Pointer to a 32 byte array containing a valid key. Supplied by user.
259  * @param key_block Index of a key block containing the source for this key.
260  *
261  * @return ETS_FAILED if HMAC operation fails or invalid parameter, ETS_OK otherwise. ETS_OK doesn't necessarily mean that JTAG was enabled.
262  */
263 int ets_jtag_enable_temporarily(const uint8_t *jtag_hmac_key, ets_efuse_block_t key_block);
264 
265 /**
266   * @brief  A crc8 algorithm used for MAC addresses in efuse
267   *
268   * @param  unsigned char const *p : Pointer to original data.
269   *
270   * @param  unsigned int len : Data length in byte.
271   *
272   * @return unsigned char: Crc value.
273   */
274 unsigned char esp_crc8(unsigned char const *p, unsigned int len);
275 
276 /**
277   * @}
278   */
279 
280 #ifdef __cplusplus
281 }
282 #endif
283 
284 #endif /* _ROM_EFUSE_H_ */
285