Merge branch 'feature/mmu_page_size_from_app_bin' into 'master'
feat(bootloader): add support to use MMU page size from app binary Closes IDF-8209 See merge request espressif/esp-idf!33989
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "esp_rom_spiflash.h"
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/efuse_periph.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
@@ -66,7 +67,7 @@ static void set_cache_and_start_app(uint32_t drom_addr,
|
||||
uint32_t irom_addr,
|
||||
uint32_t irom_load_addr,
|
||||
uint32_t irom_size,
|
||||
uint32_t entry_addr);
|
||||
const esp_image_metadata_t *data);
|
||||
|
||||
esp_err_t bootloader_common_read_otadata(const esp_partition_pos_t *ota_info, esp_ota_select_entry_t *two_otadata)
|
||||
{
|
||||
@@ -789,7 +790,7 @@ static void unpack_load_app(const esp_image_metadata_t *data)
|
||||
rom_addr[1],
|
||||
rom_load_addr[1],
|
||||
rom_size[1],
|
||||
data->image.entry_addr);
|
||||
data);
|
||||
}
|
||||
|
||||
#else //!SOC_MMU_DI_VADDR_SHARED
|
||||
@@ -834,7 +835,7 @@ static void unpack_load_app(const esp_image_metadata_t *data)
|
||||
irom_addr,
|
||||
irom_load_addr,
|
||||
irom_size,
|
||||
data->image.entry_addr);
|
||||
data);
|
||||
}
|
||||
#endif //#if SOC_MMU_DI_VADDR_SHARED
|
||||
|
||||
@@ -859,9 +860,11 @@ static void set_cache_and_start_app(
|
||||
uint32_t irom_addr,
|
||||
uint32_t irom_load_addr,
|
||||
uint32_t irom_size,
|
||||
uint32_t entry_addr)
|
||||
const esp_image_metadata_t *data)
|
||||
{
|
||||
int rc __attribute__((unused));
|
||||
const uint32_t entry_addr = data->image.entry_addr;
|
||||
const uint32_t mmu_page_size = data->mmu_page_size;
|
||||
|
||||
ESP_EARLY_LOGD(TAG, "configure drom and irom and start");
|
||||
//-----------------------Disable Cache to do the mapping---------
|
||||
@@ -871,12 +874,18 @@ static void set_cache_and_start_app(
|
||||
#else
|
||||
cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL);
|
||||
#endif
|
||||
|
||||
#if SOC_MMU_PAGE_SIZE_CONFIGURABLE
|
||||
// re-configure MMU page size
|
||||
mmu_ll_set_page_size(0, mmu_page_size);
|
||||
#endif //SOC_MMU_PAGE_SIZE_CONFIGURABLE
|
||||
|
||||
//reset MMU table first
|
||||
mmu_hal_unmap_all();
|
||||
|
||||
//-----------------------MAP DROM--------------------------
|
||||
uint32_t drom_load_addr_aligned = drom_load_addr & MMU_FLASH_MASK;
|
||||
uint32_t drom_addr_aligned = drom_addr & MMU_FLASH_MASK;
|
||||
uint32_t drom_load_addr_aligned = drom_load_addr & MMU_FLASH_MASK_FROM_VAL(mmu_page_size);
|
||||
uint32_t drom_addr_aligned = drom_addr & MMU_FLASH_MASK_FROM_VAL(mmu_page_size);
|
||||
ESP_EARLY_LOGV(TAG, "rodata starts from paddr=0x%08" PRIx32 ", vaddr=0x%08" PRIx32 ", size=0x%" PRIx32, drom_addr, drom_load_addr, drom_size);
|
||||
//The addr is aligned, so we add the mask off length to the size, to make sure the corresponding buses are enabled.
|
||||
drom_size = (drom_load_addr - drom_load_addr_aligned) + drom_size;
|
||||
@@ -894,13 +903,13 @@ static void set_cache_and_start_app(
|
||||
ESP_EARLY_LOGV(TAG, "after mapping rodata, starting from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", drom_addr_aligned, drom_load_addr_aligned, actual_mapped_len);
|
||||
}
|
||||
//we use the MMU_LL_END_DROM_ENTRY_ID mmu entry as a map page for app to find the boot partition
|
||||
mmu_hal_map_region(0, MMU_TARGET_FLASH0, MMU_LL_END_DROM_ENTRY_VADDR, drom_addr_aligned, CONFIG_MMU_PAGE_SIZE, &actual_mapped_len);
|
||||
mmu_hal_map_region(0, MMU_TARGET_FLASH0, MMU_DROM_END_ENTRY_VADDR_FROM_VAL(mmu_page_size), drom_addr_aligned, mmu_page_size, &actual_mapped_len);
|
||||
ESP_EARLY_LOGV(TAG, "mapped one page of the rodata, from paddr=0x%08" PRIx32 " and vaddr=0x%08" PRIx32 ", 0x%" PRIx32 " bytes are mapped", drom_addr_aligned, MMU_LL_END_DROM_ENTRY_VADDR, actual_mapped_len);
|
||||
#endif
|
||||
|
||||
//-----------------------MAP IROM--------------------------
|
||||
uint32_t irom_load_addr_aligned = irom_load_addr & MMU_FLASH_MASK;
|
||||
uint32_t irom_addr_aligned = irom_addr & MMU_FLASH_MASK;
|
||||
uint32_t irom_load_addr_aligned = irom_load_addr & MMU_FLASH_MASK_FROM_VAL(mmu_page_size);
|
||||
uint32_t irom_addr_aligned = irom_addr & MMU_FLASH_MASK_FROM_VAL(mmu_page_size);
|
||||
ESP_EARLY_LOGV(TAG, "text starts from paddr=0x%08" PRIx32 ", vaddr=0x%08" PRIx32 ", size=0x%" PRIx32, irom_addr, irom_load_addr, irom_size);
|
||||
//The addr is aligned, so we add the mask off length to the size, to make sure the corresponding buses are enabled.
|
||||
irom_size = (irom_load_addr - irom_load_addr_aligned) + irom_size;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "bootloader_memory_utils.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
|
||||
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
@@ -77,7 +78,7 @@ static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t
|
||||
static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent);
|
||||
|
||||
/* Verify a segment header */
|
||||
static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, bool silent);
|
||||
static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, esp_image_metadata_t *metadata, bool silent);
|
||||
|
||||
/* Log-and-fail macro for use in esp_image_load */
|
||||
#define FAIL_LOAD(...) do { \
|
||||
@@ -578,7 +579,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
|
||||
|
||||
ESP_LOGV(TAG, "segment data length 0x%"PRIx32" data starts 0x%"PRIx32, data_len, data_addr);
|
||||
|
||||
CHECK_ERR(verify_segment_header(index, header, data_addr, silent));
|
||||
CHECK_ERR(verify_segment_header(index, header, data_addr, metadata, silent));
|
||||
|
||||
if (data_len % 4 != 0) {
|
||||
FAIL_LOAD("unaligned segment length 0x%"PRIx32, data_len);
|
||||
@@ -767,7 +768,7 @@ static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, bool silent)
|
||||
static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, esp_image_metadata_t *metadata, bool silent)
|
||||
{
|
||||
if ((segment->data_len & 3) != 0
|
||||
|| segment->data_len >= SIXTEEN_MB) {
|
||||
@@ -780,13 +781,42 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header
|
||||
uint32_t load_addr = segment->load_addr;
|
||||
bool map_segment = should_map(load_addr);
|
||||
|
||||
#if SOC_MMU_PAGE_SIZE_CONFIGURABLE
|
||||
/* ESP APP descriptor is present in the DROM segment #0 */
|
||||
if (index == 0 && !is_bootloader(metadata->start_addr)) {
|
||||
uint32_t data_len = segment->data_len;
|
||||
const uint32_t *data = (const uint32_t *)bootloader_mmap(segment_data_offs, data_len);
|
||||
if (!data) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%"PRIx32", 0x%"PRIx32") failed",
|
||||
segment_data_offs, data_len);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_app_desc_t *app_desc = (esp_app_desc_t *)data;
|
||||
// Convert from log base 2 number to actual size while handling legacy image case (value 0)
|
||||
metadata->mmu_page_size = (app_desc->mmu_page_size > 0) ? (1UL << app_desc->mmu_page_size) : SPI_FLASH_MMU_PAGE_SIZE;
|
||||
if (metadata->mmu_page_size != SPI_FLASH_MMU_PAGE_SIZE) {
|
||||
ESP_LOGI(TAG, "MMU page size mismatch, configured: 0x%x, found: 0x%"PRIx32, SPI_FLASH_MMU_PAGE_SIZE, metadata->mmu_page_size);
|
||||
}
|
||||
bootloader_munmap(data);
|
||||
} else if (index == 0 && is_bootloader(metadata->start_addr)) {
|
||||
// Bootloader always uses the default MMU page size
|
||||
metadata->mmu_page_size = SPI_FLASH_MMU_PAGE_SIZE;
|
||||
}
|
||||
#else // SOC_MMU_PAGE_SIZE_CONFIGURABLE
|
||||
metadata->mmu_page_size = SPI_FLASH_MMU_PAGE_SIZE;
|
||||
#endif // !SOC_MMU_PAGE_SIZE_CONFIGURABLE
|
||||
|
||||
const int mmu_page_size = metadata->mmu_page_size;
|
||||
ESP_LOGV(TAG, "MMU page size 0x%x", mmu_page_size);
|
||||
|
||||
/* Check that flash cache mapped segment aligns correctly from flash to its mapped address,
|
||||
relative to the 64KB page mapping size.
|
||||
relative to the MMU page mapping size.
|
||||
*/
|
||||
ESP_LOGV(TAG, "segment %d map_segment %d segment_data_offs 0x%"PRIx32" load_addr 0x%"PRIx32,
|
||||
index, map_segment, segment_data_offs, load_addr);
|
||||
if (map_segment
|
||||
&& ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) {
|
||||
&& ((segment_data_offs % mmu_page_size) != (load_addr % mmu_page_size))) {
|
||||
if (!silent) {
|
||||
ESP_LOGE(TAG, "Segment %d load address 0x%08"PRIx32", doesn't match data 0x%08"PRIx32,
|
||||
index, load_addr, segment_data_offs);
|
||||
|
||||
Reference in New Issue
Block a user