1 /*
2  * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 #include <stdint.h>
14 #include <stddef.h>
15 #include <stdbool.h>
16 
17 /** \defgroup efuse_APIs efuse APIs
18   * @brief     ESP32 efuse read/write APIs
19   * @attention
20   *
21   */
22 
23 /** @addtogroup efuse_APIs
24   * @{
25   */
26 
27 typedef enum {
28     ETS_EFUSE_KEY_PURPOSE_USER = 0,
29     ETS_EFUSE_KEY_PURPOSE_RESERVED = 1,
30     ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_1 = 2,
31     ETS_EFUSE_KEY_PURPOSE_XTS_AES_256_KEY_2 = 3,
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 set timing accroding the apb clock, so no read error or write error happens.
60  *
61  * @param clock: apb clock in HZ, only accept 5M(in FPGA), 10M(in FPGA), 20M, 40M, 80M.
62  *
63  * @return : 0 if success, others if clock not accepted
64  */
65 int ets_efuse_set_timing(uint32_t clock);
66 
67 /**
68   * @brief  Efuse read operation: copies data from physical efuses to efuse read registers.
69   *
70   * @param  null
71   *
72   * @return : 0 if success, others if apb clock is not accepted
73   */
74 int ets_efuse_read(void);
75 
76 /**
77   * @brief  Efuse write operation: Copies data from efuse write registers to efuse. Operates on a single block of efuses at a time.
78   *
79   * @note This function does not update read efuses, call ets_efuse_read() once all programming is complete.
80   *
81   * @return : 0 if success, others if apb clock is not accepted
82   */
83 int ets_efuse_program(ets_efuse_block_t block);
84 
85 /**
86  * @brief Set all Efuse program registers to zero.
87  *
88  * Call this before writing new data to the program registers.
89  */
90 void ets_efuse_clear_program_registers(void);
91 
92 /**
93  * @brief Program a block of key data to an efuse block
94  *
95  * @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).
96  * @param purpose Purpose to set for this key. Purpose must be already unset.
97  * @param data Pointer to data to write.
98  * @param data_len Length of data to write.
99  *
100  * @note This function also calls ets_efuse_program() for the specified block, and for block 0 (setting the purpose)
101  */
102 int ets_efuse_write_key(ets_efuse_block_t key_block, ets_efuse_purpose_t purpose, const void *data, size_t data_len);
103 
104 
105 /* @brief Return the address of a particular efuse block's first read register
106  *
107  * @param block Index of efuse block to look up
108  *
109  * @return 0 if block is invalid, otherwise a numeric read register address
110  * of the first word in the block.
111  */
112 uint32_t ets_efuse_get_read_register_address(ets_efuse_block_t block);
113 
114 /**
115  * @brief Return the current purpose set for an efuse key block
116  *
117  * @param key_block Block to read purpose for. Must be in range ETS_EFUSE_BLOCK_KEY0 to ETS_EFUSE_BLOCK_KEY6.
118  */
119 ets_efuse_purpose_t ets_efuse_get_key_purpose(ets_efuse_block_t key_block);
120 
121 /**
122  * @brief Find a key block with the particular purpose set
123  *
124  * @param purpose Purpose to search for.
125  * @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.
126  * @return true if found, false if not found. If false, value at key_block pointer is unchanged.
127  */
128 bool ets_efuse_find_purpose(ets_efuse_purpose_t purpose, ets_efuse_block_t *key_block);
129 
130 /**
131  * Return true if the key block is unused, false otherwise.
132  *
133  * An unused key block is all zero content, not read or write protected,
134  * and has purpose 0 (ETS_EFUSE_KEY_PURPOSE_USER)
135  *
136  * @param key_block key block to check.
137  *
138  * @return true if key block is unused, false if key block or used
139  * or the specified block index is not a key block.
140  */
141 bool ets_efuse_key_block_unused(ets_efuse_block_t key_block);
142 
143 
144 /**
145  * @brief Search for an unused key block and return the first one found.
146  *
147  * See @ref ets_efuse_key_block_unused for a description of an unused key block.
148  *
149  * @return First unused key block, or ETS_EFUSE_BLOCK_MAX if no unused key block is found.
150  */
151 ets_efuse_block_t ets_efuse_find_unused_key_block(void);
152 
153 /**
154  * @brief Return the number of unused efuse key blocks (0-6)
155  */
156 unsigned ets_efuse_count_unused_key_blocks(void);
157 
158 /**
159  * @brief Calculate Reed-Solomon Encoding values for a block of efuse data.
160  *
161  * @param data Pointer to data buffer (length 32 bytes)
162  * @param rs_values Pointer to write encoded data to (length 12 bytes)
163  */
164 void ets_efuse_rs_calculate(const void *data, void *rs_values);
165 
166 /**
167   * @brief  Read spi flash pads configuration from Efuse
168   *
169   * @return
170   * - 0 for default SPI pins.
171   * - 1 for default HSPI pins.
172   * - Other values define a custom pin configuration mask. Pins are encoded as per the EFUSE_SPICONFIG_RET_SPICLK,
173   *   EFUSE_SPICONFIG_RET_SPIQ, EFUSE_SPICONFIG_RET_SPID, EFUSE_SPICONFIG_RET_SPICS0, EFUSE_SPICONFIG_RET_SPIHD macros.
174   *   WP pin (for quad I/O modes) is not saved in efuse and not returned by this function.
175   */
176 uint32_t ets_efuse_get_spiconfig(void);
177 
178 /**
179   * @brief  Read spi flash wp pad from Efuse
180   *
181   * @return
182   * - 0x3f for invalid.
183   * - 0~46 is valid.
184   */
185 uint32_t ets_efuse_get_wp_pad(void);
186 
187 /**
188   * @brief  Read if download mode disabled from Efuse
189   *
190   * @return
191   * - true for efuse disable download mode.
192   * - false for efuse doesn't disable download mode.
193   */
194 bool ets_efuse_download_modes_disabled(void);
195 
196 /**
197   * @brief  Read if legacy spi flash boot mode disabled from Efuse
198   *
199   * @return
200   * - true for efuse disable legacy spi flash boot mode.
201   * - false for efuse doesn't disable legacy spi flash boot mode.
202   */
203 bool ets_efuse_legacy_spi_boot_mode_disabled(void);
204 
205 /**
206   * @brief  Read if uart print control value from Efuse
207   *
208   * @return
209   * - 0 for uart force print.
210   * - 1 for uart print when GPIO46 is low when digital reset.
211   *   2 for uart print when GPIO46 is high when digital reset.
212   *   3 for uart force slient
213   */
214 uint32_t ets_efuse_get_uart_print_control(void);
215 
216 /**
217   * @brief  Read if USB-Serial-JTAG print during rom boot is disabled from Efuse
218   *
219   * @return
220   * - 1 for efuse disable USB-Serial-JTAG print during rom boot.
221   * - 0 for efuse doesn't disable USB-Serial-JTAG print during rom boot.
222   */
223 uint32_t ets_efuse_usb_serial_jtag_print_is_disabled(void);
224 
225 /**
226   * @brief  Read if usb download mode disabled from Efuse
227   *
228   * (Also returns true if security download mode is enabled, as this mode
229   * disables USB download.)
230   *
231   * @return
232   * - true for efuse disable usb download mode.
233   * - false for efuse doesn't disable usb download mode.
234   */
235 bool ets_efuse_usb_download_mode_disabled(void);
236 
237 
238 /**
239   * @brief  Read if usb module disabled from Efuse
240   *
241   * @return
242   * - true for efuse disable usb module.
243   * - false for efuse doesn't disable usb module.
244   */
245 bool ets_efuse_usb_module_disabled(void);
246 
247 /**
248   * @brief  Read if security download modes enabled from Efuse
249   *
250   * @return
251   * - true for efuse enable security download mode.
252   * - false for efuse doesn't enable security download mode.
253   */
254 bool ets_efuse_security_download_modes_enabled(void);
255 
256 /**
257  * @brief Return true if secure boot is enabled in EFuse
258  */
259 bool ets_efuse_secure_boot_enabled(void);
260 
261 /**
262  * @brief Return true if secure boot aggressive revoke is enabled in EFuse
263  */
264 bool ets_efuse_secure_boot_aggressive_revoke_enabled(void);
265 
266 /**
267  * @brief Return true if cache encryption (flash, PSRAM, etc) is enabled from boot via EFuse
268  */
269 bool ets_efuse_cache_encryption_enabled(void);
270 
271 /**
272  * @brief Return true if OPI pins GPIO33-37 are powered by VDDSPI, otherwise by VDD33CPU
273  */
274 bool ets_efuse_flash_opi_5pads_power_sel_vddspi(void);
275 
276 /**
277  * @brief Return true if EFuse indicates to send a flash resume command.
278  */
279 bool ets_efuse_force_send_resume(void);
280 
281 /**
282   * @brief  return the time in us ROM boot need wait flash to power on from Efuse
283   *
284   * @return
285   * - uint32_t the time in us.
286   */
287 uint32_t ets_efuse_get_flash_delay_us(void);
288 
289 #define EFUSE_SPICONFIG_SPI_DEFAULTS 0
290 #define EFUSE_SPICONFIG_HSPI_DEFAULTS 1
291 
292 #define EFUSE_SPICONFIG_RET_SPICLK_MASK         0x3f
293 #define EFUSE_SPICONFIG_RET_SPICLK_SHIFT        0
294 #define EFUSE_SPICONFIG_RET_SPICLK(ret)         (((ret) >> EFUSE_SPICONFIG_RET_SPICLK_SHIFT) & EFUSE_SPICONFIG_RET_SPICLK_MASK)
295 
296 #define EFUSE_SPICONFIG_RET_SPIQ_MASK           0x3f
297 #define EFUSE_SPICONFIG_RET_SPIQ_SHIFT          6
298 #define EFUSE_SPICONFIG_RET_SPIQ(ret)           (((ret) >> EFUSE_SPICONFIG_RET_SPIQ_SHIFT) & EFUSE_SPICONFIG_RET_SPIQ_MASK)
299 
300 #define EFUSE_SPICONFIG_RET_SPID_MASK           0x3f
301 #define EFUSE_SPICONFIG_RET_SPID_SHIFT          12
302 #define EFUSE_SPICONFIG_RET_SPID(ret)           (((ret) >> EFUSE_SPICONFIG_RET_SPID_SHIFT) & EFUSE_SPICONFIG_RET_SPID_MASK)
303 
304 #define EFUSE_SPICONFIG_RET_SPICS0_MASK         0x3f
305 #define EFUSE_SPICONFIG_RET_SPICS0_SHIFT        18
306 #define EFUSE_SPICONFIG_RET_SPICS0(ret)         (((ret) >> EFUSE_SPICONFIG_RET_SPICS0_SHIFT) & EFUSE_SPICONFIG_RET_SPICS0_MASK)
307 
308 
309 #define EFUSE_SPICONFIG_RET_SPIHD_MASK          0x3f
310 #define EFUSE_SPICONFIG_RET_SPIHD_SHIFT         24
311 #define EFUSE_SPICONFIG_RET_SPIHD(ret)          (((ret) >> EFUSE_SPICONFIG_RET_SPIHD_SHIFT) & EFUSE_SPICONFIG_RET_SPIHD_MASK)
312 
313 /**
314  * @brief Enable JTAG temporarily by writing a JTAG HMAC "key" into
315  * the JTAG_CTRL registers.
316  *
317  * Works if JTAG has been "soft" disabled by burning the EFUSE_SOFT_DIS_JTAG efuse.
318  *
319  * 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.
320  *
321  * @param jtag_hmac_key Pointer to a 32 byte array containing a valid key. Supplied by user.
322  * @param key_block Index of a key block containing the source for this key.
323  *
324  * @return ETS_FAILED if HMAC operation fails or invalid parameter, ETS_OK otherwise. ETS_OK doesn't necessarily mean that JTAG was enabled.
325  */
326 int ets_jtag_enable_temporarily(const uint8_t *jtag_hmac_key, ets_efuse_block_t key_block);
327 
328 /**
329   * @brief  A crc8 algorithm used for MAC addresses in efuse
330   *
331   * @param  unsigned char const *p : Pointer to original data.
332   *
333   * @param  unsigned int len : Data length in byte.
334   *
335   * @return unsigned char: Crc value.
336   */
337 unsigned char esp_crc8(unsigned char const *p, unsigned int len);
338 
339 /**
340   * @}
341   */
342 
343 #ifdef __cplusplus
344 }
345 #endif
346