boardinfo.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "common.h"
  2. #include "boardinfo_esp.h"
  3. #include <esp_attr.h>
  4. #include <esp_flash.h>
  5. #include <esp_spi_flash.h>
  6. #include <esp_flash_internal.h> /* For esp_flash_app_disable_protect() */
  7. #include <rom/crc.h>
  8. #define BOARDINFO_ADDR 0 /* Flash address on ESP */
  9. static const union board_info_block *board_info_flash;
  10. struct board_info DRAM_ATTR board_info;
  11. static spi_flash_mmap_handle_t board_info_handle;
  12. static const union board_info_block *board_info_map(void)
  13. {
  14. if (!board_info_flash) {
  15. const void *bifp;
  16. if (spi_flash_mmap(BOARDINFO_ADDR, BOARDINFO_SIZE, SPI_FLASH_MMAP_DATA,
  17. &bifp, &board_info_handle)
  18. == ESP_OK)
  19. board_info_flash = bifp;
  20. }
  21. return board_info_flash;
  22. }
  23. static void board_info_unmap(void)
  24. {
  25. if (board_info_flash) {
  26. spi_flash_munmap(board_info_handle);
  27. board_info_flash = NULL;
  28. board_info_handle = 0;
  29. }
  30. }
  31. /* Returns 1 if the flash was modified, 0 if unmodified, -1 on error */
  32. int board_info_init(void)
  33. {
  34. int err = -1;
  35. uint32_t crc, bif_crc;
  36. const union board_info_block *bif;
  37. bif = board_info_map();
  38. if (!bif)
  39. goto unmapped;
  40. if (bif->i.magic[0] != BOARDINFO_MAGIC_1 ||
  41. bif->i.magic[1] != BOARDINFO_MAGIC_2 ||
  42. bif->i.len < 16 || bif->i.len > BOARDINFO_SIZE ||
  43. board_info.version_str[sizeof board_info.version_str - 1])
  44. goto bad;
  45. memcpy(&board_info, bif, sizeof board_info);
  46. bif_crc = board_info.crc;
  47. board_info.crc = 0;
  48. crc = crc32_le(0, (const uint8_t *)&board_info, 16);
  49. crc = crc32_le(crc, &bif->b[16], bif->i.len - 16);
  50. board_info.crc = bif_crc;
  51. if (crc != bif_crc) {
  52. printf("[PCB] Bad board_info crc %08x calculated %08x\n",
  53. bif_crc, crc);
  54. goto bad;
  55. }
  56. printf("[PCB] Board ID/version: %s\n", board_info.version_str);
  57. err = 0;
  58. goto done;
  59. bad:
  60. if (!memcmp(board_info_flash->b, "MAX80 ", 6) &&
  61. strnlen(board_info_flash->b, sizeof board_info.version_str)
  62. < sizeof board_info.version_str) {
  63. /*
  64. * Contains board version string but nothing else; this
  65. * is allowed to simplify the initial programming.
  66. * Convert it to a proper structure and write it back.
  67. */
  68. printf("[PCB] updating board information block in flash\n");
  69. return board_info_set((const char *)board_info_flash->b);
  70. }
  71. unmapped:
  72. printf("WARNING: no board ID/version string set in flash\n");
  73. board_info.len = 0;
  74. done:
  75. if (board_info.len < sizeof board_info)
  76. memset((char *)&board_info + board_info.len, 0,
  77. sizeof board_info - board_info.len);
  78. board_info_unmap();
  79. return err;
  80. }
  81. static int board_info_generate(const char *board_id_string)
  82. {
  83. memset(&board_info, 0, sizeof board_info);
  84. board_info.magic[0] = BOARDINFO_MAGIC_1;
  85. board_info.magic[1] = BOARDINFO_MAGIC_2;
  86. board_info.len = sizeof board_info;
  87. strncpy(board_info.version_str, board_id_string,
  88. sizeof board_info.version_str - 1);
  89. memcpy(board_info.mac[0], efuse_default_mac, 6);
  90. board_info.crc = crc32_le(0, (const uint8_t *)&board_info,
  91. sizeof board_info);
  92. return 0; /* For tailcalling convenience */
  93. }
  94. /* Must be in IRAM to allow flash operations */
  95. static int __noinline IRAM_ATTR board_info_update_flash(void)
  96. {
  97. esp_err_t err;
  98. int rv = -1;
  99. /* The board_info table is in protected memory */
  100. err = esp_flash_app_disable_protect(true);
  101. if (err) {
  102. printf("board_info_set: failed to unprotect flash (err 0x%x)\n", err);
  103. goto err1;
  104. }
  105. err = esp_flash_erase_region(NULL, BOARDINFO_ADDR, BOARDINFO_SIZE);
  106. if (err) {
  107. printf("board_info_set: failed to erase board info flash region (err 0x%x)\n", err);
  108. goto err2;
  109. }
  110. err = esp_flash_write(NULL, &board_info, BOARDINFO_ADDR, sizeof board_info);
  111. if (err) {
  112. printf("board_info_set: failed to write board info flash region (err 0x%x)\n", err);
  113. goto err2;
  114. }
  115. rv = 0;
  116. err2:
  117. esp_flash_app_disable_protect(false);
  118. err1:
  119. return rv;
  120. }
  121. int board_info_set(const char *board_id_string)
  122. {
  123. const union board_info_block *bif;
  124. board_info_generate(board_id_string);
  125. bif = board_info_map();
  126. if (!bif)
  127. return -1; /* Could not map board info */
  128. bool unchanged = !memcmp(bif, &board_info, sizeof board_info);
  129. board_info_unmap();
  130. if (unchanged)
  131. return 0; /* Not modified, so don't reflash */
  132. return board_info_update_flash();
  133. }