| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 | #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((const char *)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();}
 |