123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #include "common.h"
- #include "boardinfo_esp.h"
- #include <esp_attr.h>
- #include <esp_flash.h>
- #include <esp_spi_flash.h>
- #include <esp_flash_internal.h> /* For esp_flash_app_disable_protect() */
- #include <rom/crc.h>
- #define BOARDINFO_ADDR 0 /* Flash address on ESP */
- static const union board_info_block *board_info_flash;
- struct board_info DRAM_ATTR board_info;
- static spi_flash_mmap_handle_t board_info_handle;
- static const union board_info_block *board_info_map(void)
- {
- if (!board_info_flash) {
- const void *bifp;
- if (spi_flash_mmap(BOARDINFO_ADDR, BOARDINFO_SIZE, SPI_FLASH_MMAP_DATA,
- &bifp, &board_info_handle)
- == ESP_OK)
- board_info_flash = bifp;
- }
- return board_info_flash;
- }
- static void board_info_unmap(void)
- {
- if (board_info_flash) {
- spi_flash_munmap(board_info_handle);
- board_info_flash = NULL;
- board_info_handle = 0;
- }
- }
- /* Returns 1 if the flash was modified, 0 if unmodified, -1 on error */
- int board_info_init(void)
- {
- int err = -1;
- uint32_t crc, bif_crc;
- const union board_info_block *bif;
- bif = board_info_map();
- if (!bif)
- goto unmapped;
- if (bif->i.magic[0] != BOARDINFO_MAGIC_1 ||
- bif->i.magic[1] != BOARDINFO_MAGIC_2 ||
- bif->i.len < 16 || bif->i.len > BOARDINFO_SIZE ||
- board_info.version_str[sizeof board_info.version_str - 1])
- goto bad;
- memcpy(&board_info, bif, sizeof board_info);
- bif_crc = board_info.crc;
- board_info.crc = 0;
- crc = crc32_le(0, (const uint8_t *)&board_info, 16);
- crc = crc32_le(crc, &bif->b[16], bif->i.len - 16);
- board_info.crc = bif_crc;
- if (crc != bif_crc) {
- printf("[PCB] Bad board_info crc %08x calculated %08x\n",
- bif_crc, crc);
- goto bad;
- }
- printf("[PCB] Board ID/version: %s\n", board_info.version_str);
- err = 0;
- goto done;
- bad:
- if (!memcmp(board_info_flash->b, "MAX80 ", 6) &&
- strnlen(board_info_flash->b, sizeof board_info.version_str)
- < sizeof board_info.version_str) {
- /*
- * Contains board version string but nothing else; this
- * is allowed to simplify the initial programming.
- * Convert it to a proper structure and write it back.
- */
- printf("[PCB] updating board information block in flash\n");
- return board_info_set((const char *)board_info_flash->b);
- }
- unmapped:
- printf("WARNING: no board ID/version string set in flash\n");
- board_info.len = 0;
-
- done:
- if (board_info.len < sizeof board_info)
- memset((char *)&board_info + board_info.len, 0,
- sizeof board_info - board_info.len);
- board_info_unmap();
- return err;
- }
- static int board_info_generate(const char *board_id_string)
- {
- memset(&board_info, 0, sizeof board_info);
- board_info.magic[0] = BOARDINFO_MAGIC_1;
- board_info.magic[1] = BOARDINFO_MAGIC_2;
- board_info.len = sizeof board_info;
- strncpy(board_info.version_str, board_id_string,
- sizeof board_info.version_str - 1);
- memcpy(board_info.mac[0], efuse_default_mac, 6);
- board_info.crc = crc32_le(0, (const uint8_t *)&board_info,
- sizeof board_info);
- return 0; /* For tailcalling convenience */
- }
- /* Must be in IRAM to allow flash operations */
- static int __noinline IRAM_ATTR board_info_update_flash(void)
- {
- esp_err_t err;
- int rv = -1;
- /* The board_info table is in protected memory */
- err = esp_flash_app_disable_protect(true);
- if (err) {
- printf("board_info_set: failed to unprotect flash (err 0x%x)\n", err);
- goto err1;
- }
-
- err = esp_flash_erase_region(NULL, BOARDINFO_ADDR, BOARDINFO_SIZE);
- if (err) {
- printf("board_info_set: failed to erase board info flash region (err 0x%x)\n", err);
- goto err2;
- }
- err = esp_flash_write(NULL, &board_info, BOARDINFO_ADDR, sizeof board_info);
- if (err) {
- printf("board_info_set: failed to write board info flash region (err 0x%x)\n", err);
- goto err2;
- }
- rv = 0;
-
- err2:
- esp_flash_app_disable_protect(false);
- err1:
- return rv;
- }
- int board_info_set(const char *board_id_string)
- {
- const union board_info_block *bif;
- board_info_generate(board_id_string);
- bif = board_info_map();
- if (!bif)
- return -1; /* Could not map board info */
-
- bool unchanged = !memcmp(bif, &board_info, sizeof board_info);
- board_info_unmap();
- if (unchanged)
- return 0; /* Not modified, so don't reflash */
- return board_info_update_flash();
- }
|