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