boardinfo.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. union board_info_block {
  10. struct board_info i;
  11. uint8_t b[BOARDINFO_SIZE];
  12. };
  13. static const union board_info_block *board_info_flash;
  14. struct board_info DRAM_ATTR board_info;
  15. static spi_flash_mmap_handle_t board_info_handle;
  16. static const union board_info_block *board_info_map(void)
  17. {
  18. if (!board_info_flash) {
  19. const void *bifp;
  20. if (spi_flash_mmap(BOARDINFO_ADDR, BOARDINFO_SIZE, SPI_FLASH_MMAP_DATA,
  21. &bifp, &board_info_handle)
  22. == ESP_OK)
  23. board_info_flash = bifp;
  24. }
  25. return board_info_flash;
  26. }
  27. static void board_info_unmap(void)
  28. {
  29. if (board_info_flash) {
  30. spi_flash_munmap(board_info_handle);
  31. board_info_flash = NULL;
  32. board_info_handle = 0;
  33. }
  34. }
  35. /* Returns 1 if the flash was modified, 0 if unmodified, -1 on error */
  36. int board_info_init(void)
  37. {
  38. int err = -1;
  39. uint32_t crc;
  40. const union board_info_block *bif;
  41. bif = board_info_map();
  42. if (!bif)
  43. goto unmapped;
  44. if (bif->i.magic[0] != BOARDINFO_MAGIC_1 ||
  45. bif->i.magic[1] != BOARDINFO_MAGIC_2 ||
  46. bif->i.len < 16 || bif->i.len > BOARDINFO_SIZE ||
  47. board_info.version_str[sizeof board_info.version_str - 1])
  48. goto bad;
  49. memcpy(&board_info, bif, sizeof board_info);
  50. board_info.crc = 0;
  51. crc = crc32_le(0, (const uint8_t *)&board_info, 16);
  52. crc = crc32_le(crc, &bif->b[16], bif->i.len - 16);
  53. board_info.crc = bif->i.crc;
  54. if (crc != bif->i.crc)
  55. goto bad;
  56. printf("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("NOTE: 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_1;
  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. board_info_update_flash();
  133. }