esp_efuse_utility.c 17 KB

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