1 /*
2 * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "esp_efuse_utility.h"
8
9 #include "soc/efuse_periph.h"
10 #include "esp_log.h"
11 #include "esp_rom_sys.h"
12 #include "assert.h"
13 #include "sdkconfig.h"
14 #include <sys/param.h>
15
16 static const char *TAG = "efuse";
17
18 // This counter is used to implement independent read access for efuses.
19 // During the read operation, the counter should be unchanged and even.
20 // If it is not so, we must repeat the read to make sure that the burn operation does not affect the read data.
21 static volatile unsigned s_burn_counter = 0;
22
23 // Array for emulate efuse registers.
24 #ifdef CONFIG_EFUSE_VIRTUAL
25 uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK];
26
27 #ifndef BOOTLOADER_BUILD
28 #ifndef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
29 /* Call the update function to seed virtual efuses during initialization */
30 __attribute__((constructor)) void esp_efuse_utility_update_virt_blocks(void);
31 #endif // CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
32 #endif // NOT BOOTLOADER_BUILD
33
34 #endif // CONFIG_EFUSE_VIRTUAL
35
36 extern const esp_efuse_range_addr_t range_read_addr_blocks[];
37 extern const esp_efuse_range_addr_t range_write_addr_blocks[];
38
39 static int get_reg_num(int bit_start, int bit_count, int i_reg);
40 static int get_starting_bit_num_in_reg(int bit_start, int i_reg);
41 static uint32_t get_mask(unsigned int bit_count, unsigned int shift);
42 static int get_count_bits_in_reg(int bit_start, int bit_count, int i_reg);
43 static void write_reg(esp_efuse_block_t blk, unsigned int num_reg, uint32_t value);
44 static uint32_t fill_reg(int bit_start_in_reg, int bit_count_in_reg, uint8_t* blob, int* filled_bits_blob);
45 static uint32_t set_cnt_in_reg(int bit_start_in_reg, int bit_count_used_in_reg, uint32_t reg_masked, size_t* cnt);
46 static bool check_range_of_bits(esp_efuse_block_t blk, int offset_in_bits, int size_bits);
47
48 // This function processes the field by calling the passed function.
esp_efuse_utility_process(const esp_efuse_desc_t * field[],void * ptr,size_t ptr_size_bits,efuse_func_proc_t func_proc)49 esp_err_t esp_efuse_utility_process(const esp_efuse_desc_t* field[], void* ptr, size_t ptr_size_bits, efuse_func_proc_t func_proc)
50 {
51 esp_err_t err = ESP_OK;
52 int bits_counter = 0;
53
54 // get and check size.
55 int field_len = esp_efuse_get_field_size(field);
56 int req_size = (ptr_size_bits == 0) ? field_len : MIN(ptr_size_bits, field_len);
57
58 int i = 0;
59 unsigned count_before = s_burn_counter;
60 while (err == ESP_OK && req_size > bits_counter && field[i] != NULL) {
61 if (check_range_of_bits(field[i]->efuse_block, field[i]->bit_start, field[i]->bit_count) == false) {
62 ESP_EARLY_LOGE(TAG, "Range of data does not match the coding scheme");
63 err = ESP_ERR_CODING;
64 }
65 int i_reg = 0;
66 int num_reg;
67 while (err == ESP_OK && req_size > bits_counter &&
68 (num_reg = get_reg_num(field[i]->bit_start, field[i]->bit_count, i_reg)) != -1) {
69
70 int start_bit = get_starting_bit_num_in_reg(field[i]->bit_start, i_reg);
71 int num_bits = get_count_bits_in_reg(field[i]->bit_start, field[i]->bit_count, i_reg);
72 if ((bits_counter + num_bits) > req_size) { // Limits the length of the field.
73 num_bits = req_size - bits_counter;
74 }
75 ESP_EARLY_LOGD(TAG, "In EFUSE_BLK%d__DATA%d_REG is used %d bits starting with %d bit",
76 (int)field[i]->efuse_block, num_reg, num_bits, start_bit);
77 err = func_proc(num_reg, field[i]->efuse_block, start_bit, num_bits, ptr, &bits_counter);
78 ++i_reg;
79 }
80 i++;
81 }
82 unsigned count_after = s_burn_counter;
83 if (err == ESP_OK &&
84 (func_proc == esp_efuse_utility_fill_buff || func_proc == esp_efuse_utility_count_once) && // these functions are used for read APIs: read_field_blob and read_field_cnt
85 (count_before != count_after || (count_after & 1) == 1)) {
86 err = ESP_ERR_DAMAGED_READING;
87 }
88 assert(bits_counter <= req_size);
89 return err;
90 }
91
92
93 // Read efuse register and write this value to array.
esp_efuse_utility_fill_buff(unsigned int num_reg,esp_efuse_block_t efuse_block,int bit_start,int bit_count,void * arr_out,int * bits_counter)94 esp_err_t esp_efuse_utility_fill_buff(unsigned int num_reg, esp_efuse_block_t efuse_block, int bit_start, int bit_count, void* arr_out, int* bits_counter)
95 {
96 uint8_t* blob = (uint8_t *) arr_out;
97 uint32_t reg = esp_efuse_utility_read_reg(efuse_block, num_reg);
98 uint64_t reg_of_aligned_bits = (reg >> bit_start) & get_mask(bit_count, 0);
99
100 int shift_bit = (*bits_counter) % 8;
101 if (shift_bit != 0) {
102 blob[(*bits_counter) / 8] |= (uint8_t)(reg_of_aligned_bits << shift_bit);
103 shift_bit = ((8 - shift_bit) < bit_count) ? (8 - shift_bit) : bit_count;
104 (*bits_counter) += shift_bit;
105 bit_count -= shift_bit;
106 }
107
108 int sum_shift = 0;
109 while (bit_count > 0) {
110 sum_shift += shift_bit;
111 blob[(*bits_counter) / 8] |= (uint8_t)(reg_of_aligned_bits >> sum_shift);
112 shift_bit = (bit_count > 8) ? 8 : bit_count;
113 (*bits_counter) += shift_bit;
114 bit_count -= shift_bit;
115 };
116 return ESP_OK;
117 }
118
119 // Count a set bits.
esp_efuse_utility_count_once(unsigned int num_reg,esp_efuse_block_t efuse_block,int bit_start,int bit_count,void * out_cnt,int * bits_counter)120 esp_err_t esp_efuse_utility_count_once(unsigned int num_reg, esp_efuse_block_t efuse_block, int bit_start, int bit_count, void* out_cnt, int* bits_counter)
121 {
122 uint32_t reg = esp_efuse_utility_read_reg(efuse_block, num_reg);
123 *((size_t *)out_cnt) += __builtin_popcount(reg & get_mask(bit_count, bit_start)); // Returns the number of 1-bits in reg.
124 *bits_counter += bit_count;
125 return ESP_OK;
126 }
127
128 // Fill registers from array for writing.
esp_efuse_utility_write_blob(unsigned int num_reg,esp_efuse_block_t efuse_block,int bit_start,int bit_count,void * arr_in,int * bits_counter)129 esp_err_t esp_efuse_utility_write_blob(unsigned int num_reg, esp_efuse_block_t efuse_block, int bit_start, int bit_count, void* arr_in, int* bits_counter)
130 {
131 uint32_t reg_to_write = fill_reg(bit_start, bit_count, (uint8_t *)arr_in, bits_counter);
132 return esp_efuse_utility_write_reg(efuse_block, num_reg, reg_to_write);
133 }
134
135 // fill registers with the required number of bits for writing.
esp_efuse_utility_write_cnt(unsigned int num_reg,esp_efuse_block_t efuse_block,int bit_start,int bit_count,void * cnt,int * bits_counter)136 esp_err_t esp_efuse_utility_write_cnt(unsigned int num_reg, esp_efuse_block_t efuse_block, int bit_start, int bit_count, void* cnt, int* bits_counter)
137 {
138 esp_err_t err = ESP_OK;
139 uint32_t reg = esp_efuse_utility_read_reg(efuse_block, num_reg);
140 size_t* set_bits = (size_t*)cnt;
141 uint32_t mask = get_mask(bit_count, bit_start);
142 uint32_t reg_masked_bits = reg & mask;
143 if ((reg_masked_bits ^ mask) != 0) {// register has free bits to set them to 1?
144 uint32_t reg_to_write = set_cnt_in_reg(bit_start, bit_count, reg_masked_bits, set_bits);
145 write_reg(efuse_block, num_reg, reg_to_write);
146 }
147 *bits_counter += bit_count;
148 if ((*set_bits) == 0) {
149 err = ESP_OK_EFUSE_CNT;
150 }
151 return err;
152 }
153
154 // Reset efuse write registers
esp_efuse_utility_reset(void)155 void esp_efuse_utility_reset(void)
156 {
157 ++s_burn_counter;
158 esp_efuse_utility_clear_program_registers();
159 ++s_burn_counter;
160 for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
161 for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
162 REG_WRITE(addr_wr_block, 0);
163 }
164 }
165 }
166
167 // Burn values written to the efuse write registers
esp_efuse_utility_burn_efuses(void)168 void esp_efuse_utility_burn_efuses(void)
169 {
170 ++s_burn_counter;
171 esp_efuse_utility_burn_chip();
172 ++s_burn_counter;
173 }
174
175 // Erase the virt_blocks array.
esp_efuse_utility_erase_virt_blocks(void)176 void esp_efuse_utility_erase_virt_blocks(void)
177 {
178 #ifdef CONFIG_EFUSE_VIRTUAL
179 memset(virt_blocks, 0, sizeof(virt_blocks));
180 #ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
181 esp_efuse_utility_write_efuses_to_flash();
182 #endif
183 #endif // CONFIG_EFUSE_VIRTUAL
184 }
185
186 // Fills the virt_blocks array by values from efuse_Rdata.
esp_efuse_utility_update_virt_blocks(void)187 void esp_efuse_utility_update_virt_blocks(void)
188 {
189 #ifdef CONFIG_EFUSE_VIRTUAL
190 #ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
191 if (!esp_efuse_utility_load_efuses_from_flash()) {
192 #else
193 if (1) {
194 #endif
195 ESP_EARLY_LOGW(TAG, "Loading virtual efuse blocks from real efuses");
196 for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
197 int subblock = 0;
198 for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4) {
199 virt_blocks[num_block][subblock++] = REG_READ(addr_rd_block);
200 }
201 ESP_EARLY_LOGD(TAG, "virt_blocks[%d] is filled by EFUSE_BLOCK%d", num_block, num_block);
202 }
203 #ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
204 esp_efuse_utility_write_efuses_to_flash();
205 #endif
206 }
207 #else
208 ESP_EARLY_LOGI(TAG, "Emulate efuse is disabled");
209 #endif
210 }
211
212 // Prints efuse values for all registers.
213 void esp_efuse_utility_debug_dump_blocks(void)
214 {
215 esp_rom_printf("EFUSE_BLKx:\n");
216 #ifdef CONFIG_EFUSE_VIRTUAL
217 for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
218 int num_reg = 0;
219 esp_rom_printf("%d) ", num_block);
220 for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4, num_reg++) {
221 esp_rom_printf("0x%08x ", virt_blocks[num_block][num_reg]);
222 }
223 esp_rom_printf("\n");
224 }
225 #else
226 for (int num_block = EFUSE_BLK0; num_block < EFUSE_BLK_MAX; num_block++) {
227 esp_rom_printf("%d) ", num_block);
228 for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4) {
229 esp_rom_printf("0x%08x ", REG_READ(addr_rd_block));
230 }
231 esp_rom_printf("\n");
232 }
233 #endif
234 esp_rom_printf("\n");
235 }
236
237 // returns the number of array elements for placing these bits in an array with the length of each element equal to size_of_base.
238 int esp_efuse_utility_get_number_of_items(int bits, int size_of_base)
239 {
240 return bits / size_of_base + (bits % size_of_base > 0 ? 1 : 0);
241 }
242
243 // Writing efuse register with checking of repeated programming of programmed bits.
244 esp_err_t esp_efuse_utility_write_reg(esp_efuse_block_t efuse_block, unsigned int num_reg, uint32_t reg_to_write)
245 {
246 esp_err_t err = ESP_OK;
247 uint32_t reg = esp_efuse_utility_read_reg(efuse_block, num_reg);
248 if (reg & reg_to_write) {
249 ESP_EARLY_LOGE(TAG, "Repeated programming of programmed bits is strictly forbidden 0x%08x", reg & reg_to_write);
250 err = ESP_ERR_EFUSE_REPEATED_PROG;
251 } else {
252 write_reg(efuse_block, num_reg, reg_to_write);
253 }
254 return err;
255 }
256
257 // Reading efuse register.
258 uint32_t esp_efuse_utility_read_reg(esp_efuse_block_t blk, unsigned int num_reg)
259 {
260 assert(blk >= 0 && blk < EFUSE_BLK_MAX);
261 assert(num_reg <= (range_read_addr_blocks[blk].end - range_read_addr_blocks[blk].start) / sizeof(uint32_t));
262 uint32_t value;
263 #ifdef CONFIG_EFUSE_VIRTUAL
264 value = virt_blocks[blk][num_reg];
265 #else
266 value = REG_READ(range_read_addr_blocks[blk].start + num_reg * 4);
267 #endif
268 return value;
269 }
270
271 // Private functions
272
273 // writing efuse register.
274 static void write_reg(esp_efuse_block_t blk, unsigned int num_reg, uint32_t value)
275 {
276 assert(blk >= 0 && blk < EFUSE_BLK_MAX);
277 assert(num_reg <= (range_read_addr_blocks[blk].end - range_read_addr_blocks[blk].start) / sizeof(uint32_t));
278
279 uint32_t addr_wr_reg = range_write_addr_blocks[blk].start + num_reg * 4;
280 uint32_t reg_to_write = REG_READ(addr_wr_reg) | value;
281 // The register can be written in parts so we combine the new value with the one already available.
282 REG_WRITE(addr_wr_reg, reg_to_write);
283 }
284
285 // return mask with required the number of ones with shift.
286 static uint32_t get_mask(unsigned int bit_count, unsigned int shift)
287 {
288 uint32_t mask;
289 if (bit_count != 32) {
290 mask = (1 << bit_count) - 1;
291 } else {
292 mask = 0xFFFFFFFF;
293 }
294 return mask << shift;
295 }
296
297 // return the register number in the array. return -1 if all registers for field was selected.
298 static int get_reg_num(int bit_start, int bit_count, int i_reg)
299 {
300 int num_reg = i_reg + bit_start / 32;
301
302 if (num_reg > (bit_start + bit_count - 1) / 32) {
303 return -1;
304 }
305
306 return num_reg;
307 }
308
309 // returns the starting bit number in the register.
310 static int get_starting_bit_num_in_reg(int bit_start, int i_reg)
311 {
312 return (i_reg == 0) ? bit_start % 32 : 0;
313 }
314
315 // Returns the number of bits in the register.
316 static int get_count_bits_in_reg(int bit_start, int bit_count, int i_reg)
317 {
318 int ret_count = 0;
319 int num_reg = 0;
320 int last_used_bit = (bit_start + bit_count - 1);
321 for (int num_bit = bit_start; num_bit <= last_used_bit; ++num_bit) {
322 ++ret_count;
323 if ((((num_bit + 1) % 32) == 0) || (num_bit == last_used_bit)) {
324 if (i_reg == num_reg++) {
325 return ret_count;
326 }
327 ret_count = 0;
328 }
329 }
330 return 0;
331 }
332
333 // fill efuse register from array.
334 static uint32_t fill_reg(int bit_start_in_reg, int bit_count_in_reg, uint8_t* blob, int* filled_bits_blob)
335 {
336 uint32_t reg_to_write = 0;
337 uint32_t temp_blob_32;
338 int shift_bit = (*filled_bits_blob) % 8;
339 if (shift_bit != 0) {
340 temp_blob_32 = blob[(*filled_bits_blob) / 8] >> shift_bit;
341 shift_bit = ((8 - shift_bit) < bit_count_in_reg) ? (8 - shift_bit) : bit_count_in_reg;
342 reg_to_write = temp_blob_32 & get_mask(shift_bit, 0);
343 (*filled_bits_blob) += shift_bit;
344 bit_count_in_reg -= shift_bit;
345 }
346
347 int shift_reg = shift_bit;
348 while (bit_count_in_reg > 0) {
349 temp_blob_32 = blob[(*filled_bits_blob) / 8];
350 shift_bit = (bit_count_in_reg > 8) ? 8 : bit_count_in_reg;
351 reg_to_write |= (temp_blob_32 & get_mask(shift_bit, 0)) << shift_reg;
352 (*filled_bits_blob) += shift_bit;
353 bit_count_in_reg -= shift_bit;
354 shift_reg += 8;
355 };
356 return reg_to_write << bit_start_in_reg;
357 }
358
359 // sets a required count of bits as "1".
360 static uint32_t set_cnt_in_reg(int bit_start_in_reg, int bit_count_used_in_reg, uint32_t reg_masked, size_t* cnt)
361 {
362 assert((bit_start_in_reg + bit_count_used_in_reg) <= 32);
363 uint32_t reg_to_write = 0;
364 for (int i = bit_start_in_reg; i < bit_start_in_reg + bit_count_used_in_reg; ++i) {
365 if ((reg_masked & (1 << i)) == 0) {
366 reg_to_write |= (1 << i);
367 if (--(*cnt) == 0) {
368 break;
369 }
370 }
371 }
372 return reg_to_write;
373 }
374
375 // check range of bits for any coding scheme.
376 static bool check_range_of_bits(esp_efuse_block_t blk, int offset_in_bits, int size_bits)
377 {
378 int max_num_bit = offset_in_bits + size_bits;
379 if (max_num_bit > 256) {
380 return false;
381 } else {
382 ESP_EFUSE_FIELD_CORRESPONDS_CODING_SCHEME(blk, max_num_bit);
383 }
384 return true;
385 }
386
387 uint32_t esp_efuse_utility_get_read_register_address(esp_efuse_block_t block)
388 {
389 assert(block < EFUSE_BLK_MAX);
390 #ifdef CONFIG_EFUSE_VIRTUAL
391 return (uint32_t)&virt_blocks[block][0];
392 #else
393 return range_read_addr_blocks[block].start;
394 #endif
395
396 }
397
398 #if defined(BOOTLOADER_BUILD) && defined(CONFIG_EFUSE_VIRTUAL) && !defined(CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH)
399 void esp_efuse_init_virtual_mode_in_ram(void)
400 {
401 esp_efuse_utility_update_virt_blocks();
402 }
403 #endif
404
405 #ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
406
407 #include "../include_bootloader/bootloader_flash_priv.h"
408
409 static uint32_t esp_efuse_flash_offset = 0;
410 static uint32_t esp_efuse_flash_size = 0;
411
412 void esp_efuse_init_virtual_mode_in_flash(uint32_t offset, uint32_t size)
413 {
414 esp_efuse_flash_offset = offset;
415 esp_efuse_flash_size = size;
416 esp_efuse_utility_update_virt_blocks();
417 esp_efuse_utility_debug_dump_blocks();
418 }
419
420 void esp_efuse_utility_erase_efuses_in_flash(void)
421 {
422 if (esp_efuse_flash_offset == 0) {
423 ESP_EARLY_LOGE(TAG, "no efuse partition in partition_table? (Flash is not updated)");
424 abort();
425 }
426 esp_err_t err = bootloader_flash_erase_range(esp_efuse_flash_offset, esp_efuse_flash_size);
427 if (err != ESP_OK) {
428 ESP_EARLY_LOGE(TAG, "Failed to erase flash. err = 0x%x", err);
429 abort();
430 }
431 }
432
433 bool esp_efuse_utility_load_efuses_from_flash(void)
434 {
435 if (esp_efuse_flash_offset == 0) {
436 ESP_EARLY_LOGE(TAG, "no efuse partition in partition_table? (Flash is not updated)");
437 abort();
438 }
439 uint32_t efuses_in_flash[sizeof(virt_blocks)];
440
441 esp_err_t err = bootloader_flash_read(esp_efuse_flash_offset, &efuses_in_flash, sizeof(efuses_in_flash), true);
442 if (err != ESP_OK) {
443 ESP_EARLY_LOGE(TAG, "Can not read eFuse partition from flash (err=0x%x)", err);
444 abort();
445 }
446
447 for (unsigned i = 0; i < sizeof(virt_blocks); ++i) {
448 if (efuses_in_flash[i] != 0xFFFFFFFF) {
449 ESP_EARLY_LOGW(TAG, "Loading virtual efuse blocks from flash");
450 memcpy(virt_blocks, efuses_in_flash, sizeof(virt_blocks));
451 return true;
452 }
453 }
454 return false;
455 }
456
457 void esp_efuse_utility_write_efuses_to_flash(void)
458 {
459 if (esp_efuse_flash_offset == 0) {
460 ESP_EARLY_LOGE(TAG, "no efuse partition in partition_table? (Flash is not updated)");
461 abort();
462 }
463
464 esp_err_t err = bootloader_flash_erase_range(esp_efuse_flash_offset, esp_efuse_flash_size);
465 if (err != ESP_OK) {
466 ESP_EARLY_LOGE(TAG, "Failed to erase flash. err = 0x%x", err);
467 abort();
468 }
469
470 err = bootloader_flash_write(esp_efuse_flash_offset, &virt_blocks, sizeof(virt_blocks), false);
471 if (err != ESP_OK) {
472 ESP_EARLY_LOGE(TAG, "secure_version can not be written to flash. err = 0x%x", err);
473 abort();
474 }
475 }
476 #endif // CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
477