Skip to content

Commit

Permalink
soc: espressif: esp32s3: AMP flash support
Browse files Browse the repository at this point in the history
Rework memory layout and add a flash support to multicore SoCs.

Signed-off-by: Marek Matej <[email protected]>
  • Loading branch information
Marek Matej committed Jan 31, 2025
1 parent ae7976a commit b41f514
Show file tree
Hide file tree
Showing 13 changed files with 1,121 additions and 380 deletions.
12 changes: 12 additions & 0 deletions soc/espressif/common/Kconfig.amp
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,16 @@ config ESP_APPCPU_DRAM_SIZE
help
Defines APPCPU DRAM area size in bytes.

config ESP_APPCPU_IROM_SIZE
hex "ESP32* APPCPU IROM size"
default 0x100000
help
Defines APPCPU IROM area size in bytes.

config ESP_APPCPU_DROM_SIZE
hex "ESP32* APPCPU DRAM size"
default 0x10000
help
Defines APPCPU DROM area size in bytes.

endmenu # AMP config
11 changes: 11 additions & 0 deletions soc/espressif/common/include/hw_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@
#ifndef _SOC_ESPRESSIF_COMMON_HW_INIT_H_
#define _SOC_ESPRESSIF_COMMON_HW_INIT_H_

struct rom_segments {
unsigned irom_map_addr; /* Mapped address (VMA) for IROM region */

Check warning on line 11 in soc/espressif/common/include/hw_init.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

soc/espressif/common/include/hw_init.h:11 please, no spaces at the start of a line

Check warning on line 11 in soc/espressif/common/include/hw_init.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

UNSPECIFIED_INT

soc/espressif/common/include/hw_init.h:11 Prefer 'unsigned int' to bare use of 'unsigned'
unsigned irom_flash_offset; /* Flash offset (LMA) for IROM region */

Check warning on line 12 in soc/espressif/common/include/hw_init.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

soc/espressif/common/include/hw_init.h:12 please, no spaces at the start of a line

Check warning on line 12 in soc/espressif/common/include/hw_init.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

UNSPECIFIED_INT

soc/espressif/common/include/hw_init.h:12 Prefer 'unsigned int' to bare use of 'unsigned'
unsigned irom_size; /* Size of IROM region */

Check warning on line 13 in soc/espressif/common/include/hw_init.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

soc/espressif/common/include/hw_init.h:13 please, no spaces at the start of a line

Check warning on line 13 in soc/espressif/common/include/hw_init.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

UNSPECIFIED_INT

soc/espressif/common/include/hw_init.h:13 Prefer 'unsigned int' to bare use of 'unsigned'
unsigned drom_map_addr; /* Mapped address (VMA) for DROM region */

Check warning on line 14 in soc/espressif/common/include/hw_init.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

soc/espressif/common/include/hw_init.h:14 please, no spaces at the start of a line

Check warning on line 14 in soc/espressif/common/include/hw_init.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

UNSPECIFIED_INT

soc/espressif/common/include/hw_init.h:14 Prefer 'unsigned int' to bare use of 'unsigned'
unsigned drom_flash_offset; /* Flash offset (LMA) for DROM region */

Check warning on line 15 in soc/espressif/common/include/hw_init.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LEADING_SPACE

soc/espressif/common/include/hw_init.h:15 please, no spaces at the start of a line
unsigned drom_size; /* Size of DROM region */
};

void map_rom_segments(int core, struct rom_segments *map);

int hardware_init(void);

#endif /* _SOC_ESPRESSIF_COMMON_HW_INIT_H_ */
111 changes: 61 additions & 50 deletions soc/espressif/common/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,28 +68,32 @@

#define HDR_ATTR __attribute__((section(".entry_addr"))) __attribute__((used))

#if !defined(CONFIG_SOC_ESP32_APPCPU) && !defined(CONFIG_SOC_ESP32S3_APPCPU)
#define PART_OFFSET FIXED_PARTITION_OFFSET(slot0_partition)
#else
#define PART_OFFSET FIXED_PARTITION_OFFSET(slot0_appcpu_partition)
#endif

void __start(void);
static HDR_ATTR void (*_entry_point)(void) = &__start;

esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr;
extern uint32_t _image_irom_start, _image_irom_size, _image_irom_vaddr;
extern uint32_t _image_drom_start, _image_drom_size, _image_drom_vaddr;
extern uint32_t _libc_heap_size;

#ifndef CONFIG_MCUBOOT
static uint32_t _app_irom_start =
(FIXED_PARTITION_OFFSET(slot0_partition) + (uint32_t)&_image_irom_start);
static uint32_t _app_irom_size = (uint32_t)&_image_irom_size;

static uint32_t _app_drom_start =
(FIXED_PARTITION_OFFSET(slot0_partition) + (uint32_t)&_image_drom_start);
static uint32_t _app_drom_size = (uint32_t)&_image_drom_size;

extern uint32_t _libc_heap_size;
static uint32_t libc_heap_size = (uint32_t)&_libc_heap_size;
#endif

static uint32_t _app_irom_vaddr = ((uint32_t)&_image_irom_vaddr);
static uint32_t _app_drom_vaddr = ((uint32_t)&_image_drom_vaddr);
static struct rom_segments _segments = {
.irom_map_addr = (uint32_t)&_image_irom_vaddr,
.irom_flash_offset = PART_OFFSET + (uint32_t)&_image_irom_start,
.irom_size = (uint32_t)&_image_irom_size,
.drom_map_addr = ((uint32_t)&_image_drom_vaddr),
.drom_flash_offset = PART_OFFSET + (uint32_t)&_image_drom_start,
.drom_size = (uint32_t)&_image_drom_size,
};

#ifndef CONFIG_BOOTLOADER_MCUBOOT
static int spi_flash_read(uint32_t address, void *buffer, size_t length)
Expand All @@ -98,15 +102,15 @@ static int spi_flash_read(uint32_t address, void *buffer, size_t length)
}
#endif /* CONFIG_BOOTLOADER_MCUBOOT */

void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t app_drom_size,
uint32_t app_irom_start, uint32_t app_irom_vaddr, uint32_t app_irom_size)
void map_rom_segments(int core, struct rom_segments *map)
{
uint32_t app_irom_start_aligned = app_irom_start & MMU_FLASH_MASK;
uint32_t app_irom_vaddr_aligned = app_irom_vaddr & MMU_FLASH_MASK;
uint32_t app_irom_vaddr_aligned = map->irom_map_addr & MMU_FLASH_MASK;
uint32_t app_irom_start_aligned = map->irom_flash_offset & MMU_FLASH_MASK;

uint32_t app_drom_start_aligned = app_drom_start & MMU_FLASH_MASK;
uint32_t app_drom_vaddr_aligned = app_drom_vaddr & MMU_FLASH_MASK;
uint32_t app_drom_vaddr_aligned = map->drom_map_addr & MMU_FLASH_MASK;
uint32_t app_drom_start_aligned = map->drom_flash_offset & MMU_FLASH_MASK;

/* Traverse segments to fix flash offset changes due to post-build processing */
#ifndef CONFIG_BOOTLOADER_MCUBOOT
esp_image_segment_header_t WORD_ALIGNED_ATTR segment_hdr;
size_t offset = FIXED_PARTITION_OFFSET(boot_partition);
Expand Down Expand Up @@ -141,13 +145,13 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t
/* Fix drom and irom produced be the linker, as it could
* be invalidated by the elf2image and flash load offset
*/
if (segment_hdr.load_addr == _app_drom_vaddr) {
app_drom_start = offset + sizeof(esp_image_segment_header_t);
app_drom_start_aligned = app_drom_start & MMU_FLASH_MASK;
if (segment_hdr.load_addr == map->drom_map_addr) {
map->drom_flash_offset = offset + sizeof(esp_image_segment_header_t);
app_drom_start_aligned = map->drom_flash_offset /*app_drom_start*/ & MMU_FLASH_MASK;
}
if (segment_hdr.load_addr == _app_irom_vaddr) {
app_irom_start = offset + sizeof(esp_image_segment_header_t);
app_irom_start_aligned = app_irom_start & MMU_FLASH_MASK;
if (segment_hdr.load_addr == map->irom_map_addr) {
map->irom_flash_offset = offset + sizeof(esp_image_segment_header_t);
app_irom_start_aligned = map->irom_flash_offset & MMU_FLASH_MASK;
}
if (IS_SRAM(segment_hdr.load_addr) || IS_RTC(segment_hdr.load_addr)) {
ram_segments++;
Expand All @@ -169,29 +173,31 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t
#endif /* !CONFIG_BOOTLOADER_MCUBOOT */

#if CONFIG_SOC_SERIES_ESP32
Cache_Read_Disable(0);
Cache_Flush(0);
Cache_Read_Disable(core);
Cache_Flush(core);
#else
cache_hal_disable(CACHE_TYPE_ALL);
#endif /* CONFIG_SOC_SERIES_ESP32 */

/* Clear the MMU entries that are already set up,
* so the new app only has the mappings it creates.
*/
mmu_hal_unmap_all();
if (core == 0) {
mmu_hal_unmap_all();
}

#if CONFIG_SOC_SERIES_ESP32
int rc = 0;
uint32_t drom_page_count =
(app_drom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE;
(map->drom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE;

rc |= cache_flash_mmu_set(0, 0, app_drom_vaddr_aligned, app_drom_start_aligned, 64,
drom_page_count);
rc |= cache_flash_mmu_set(1, 0, app_drom_vaddr_aligned, app_drom_start_aligned, 64,
drom_page_count);

uint32_t irom_page_count =
(app_irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE;
(map->irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE;

rc |= cache_flash_mmu_set(0, 0, app_irom_vaddr_aligned, app_irom_start_aligned, 64,
irom_page_count);
Expand All @@ -204,53 +210,56 @@ void map_rom_segments(uint32_t app_drom_start, uint32_t app_drom_vaddr, uint32_t
#else
uint32_t actual_mapped_len = 0;

mmu_hal_map_region(0, MMU_TARGET_FLASH0, app_drom_vaddr_aligned, app_drom_start_aligned,
app_drom_size, &actual_mapped_len);
mmu_hal_map_region(core, MMU_TARGET_FLASH0, app_drom_vaddr_aligned, app_drom_start_aligned,
map->drom_size, &actual_mapped_len);

mmu_hal_map_region(0, MMU_TARGET_FLASH0, app_irom_vaddr_aligned, app_irom_start_aligned,
app_irom_size, &actual_mapped_len);
mmu_hal_map_region(core, MMU_TARGET_FLASH0, app_irom_vaddr_aligned, app_irom_start_aligned,
map->irom_size, &actual_mapped_len);
#endif /* CONFIG_SOC_SERIES_ESP32 */

/* ----------------------Enable corresponding buses---------------- */
cache_bus_mask_t bus_mask = cache_ll_l1_get_bus(0, app_drom_vaddr_aligned, app_drom_size);
cache_bus_mask_t bus_mask = cache_ll_l1_get_bus(core, app_drom_vaddr_aligned, map->drom_size);
cache_ll_l1_enable_bus(core, bus_mask);
bus_mask = cache_ll_l1_get_bus(core, app_irom_vaddr_aligned, map->irom_size);
cache_ll_l1_enable_bus(core, bus_mask);

cache_ll_l1_enable_bus(0, bus_mask);
bus_mask = cache_ll_l1_get_bus(0, app_irom_vaddr_aligned, app_irom_size);
cache_ll_l1_enable_bus(0, bus_mask);
#if CONFIG_MP_MAX_NUM_CPUS > 1
bus_mask = cache_ll_l1_get_bus(1, app_drom_vaddr_aligned, app_drom_size);
#error "SMP case not settled"
bus_mask = cache_ll_l1_get_bus(1, app_drom_vaddr_aligned, map->drom_size);
cache_ll_l1_enable_bus(1, bus_mask);
bus_mask = cache_ll_l1_get_bus(1, app_irom_vaddr_aligned, app_irom_size);
bus_mask = cache_ll_l1_get_bus(1, app_irom_vaddr_aligned, map->irom_size);
cache_ll_l1_enable_bus(1, bus_mask);
#endif

/* ----------------------Enable Cache---------------- */
#if CONFIG_SOC_SERIES_ESP32
/* Application will need to do Cache_Flush(1) and Cache_Read_Enable(1) */
Cache_Read_Enable(0);
Cache_Read_Enable(core);
#else
cache_hal_enable(CACHE_TYPE_ALL);
#endif /* CONFIG_SOC_SERIES_ESP32 */

#if !defined(CONFIG_SOC_SERIES_ESP32) && !defined(CONFIG_SOC_SERIES_ESP32S2)
/* Configure the Cache MMU size for instruction and rodata in flash. */
uint32_t cache_mmu_irom_size =
((app_irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE) *
((map->irom_size + CONFIG_MMU_PAGE_SIZE - 1) / CONFIG_MMU_PAGE_SIZE) *
sizeof(uint32_t);

/* Split the cache usage by the segment sizes */
Cache_Set_IDROM_MMU_Size(cache_mmu_irom_size, CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
#endif
/* Show map segments continue using same log format as during MCUboot phase */
ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map", "DROM",
app_drom_start_aligned, app_drom_vaddr_aligned, app_drom_size,
app_drom_size);
app_drom_start_aligned, app_drom_vaddr_aligned, map->drom_size,
map->drom_size);
ESP_EARLY_LOGI(TAG, "%s segment: paddr=%08xh, vaddr=%08xh, size=%05Xh (%6d) map", "IROM",
app_irom_start_aligned, app_irom_vaddr_aligned, app_irom_size,
app_irom_size);
esp_rom_uart_tx_wait_idle(0);
app_irom_start_aligned, app_irom_vaddr_aligned, map->irom_size,
map->irom_size);
esp_rom_uart_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM);
}
#endif /* !CONFIG_MCUBOOT */

#include "debugpin.h"
void __start(void)
{
#ifdef CONFIG_RISCV_GP
Expand All @@ -272,10 +281,12 @@ void __start(void)
}
#endif

#if !defined(CONFIG_SOC_ESP32_APPCPU) && !defined(CONFIG_SOC_ESP32S3_APPCPU) && \
!defined(CONFIG_MCUBOOT)
map_rom_segments(_app_drom_start, _app_drom_vaddr, _app_drom_size, _app_irom_start,
_app_irom_vaddr, _app_irom_size);
#if defined(CONFIG_SOC_ESP32S3_APPCPU) || defined(CONFIG_SOC_ESP32_APPCPU)
#error
#endif

#if !defined(CONFIG_MCUBOOT)
map_rom_segments(0, &_segments);
#endif
#ifndef CONFIG_SOC_SERIES_ESP32C2
/* Disable RNG entropy source as it was already used */
Expand All @@ -286,7 +297,7 @@ void __start(void)
ESP_EARLY_LOGI(TAG, "Disabling glitch detection");
ana_clock_glitch_reset_config(false);
#endif
#if !defined(CONFIG_MCUBOOT)
#ifndef CONFIG_MCUBOOT
ESP_EARLY_LOGI(TAG, "libc heap size %d kB.", libc_heap_size / 1024);
#endif
__esp_platform_start();
Expand Down
18 changes: 15 additions & 3 deletions soc/espressif/esp32/default.ld
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ procpu_dram_len = SRAM2_DRAM_USER_SIZE - CONFIG_ESP32_BT_RESERVE_DRAM;
user_dram_2_seg_org = SRAM1_DRAM_USER_START;
user_dram_2_seg_len = SRAM1_USER_SIZE;

/* User available cache memory */
procpu_irom_org = ICACHE0_START;
procpu_irom_len = ICACHE0_SIZE - APPCPU_ROM_SIZE;

procpu_drom_org = DCACHE0_START;
procpu_drom_len = DCACHE0_SIZE - APPCPU_ROM_SIZE;

#if defined(CONFIG_ESP_SPIRAM)
procpu_extram_org = DCACHE1_START
procpu_extram_len = CONFIG_ESP_SPIRAM_SIZE
#endif

/* Aliases */
#define FLASH_CODE_REGION irom0_0_seg
#define RODATA_REGION drom0_0_seg
Expand Down Expand Up @@ -65,8 +77,8 @@ MEMORY
iram0_0_seg(RX): org = procpu_iram_org, len = procpu_iram_len
dram0_0_seg(RW): org = procpu_dram_org, len = procpu_dram_len

irom0_0_seg(RX): org = IROM_SEG_ORG, len = IROM_SEG_LEN
drom0_0_seg(R): org = DROM_SEG_ORG, len = DROM_SEG_LEN
irom0_0_seg(RX): org = procpu_irom_org, len = procpu_irom_len
drom0_0_seg(R): org = procpu_drom_org, len = procpu_drom_len

rtc_iram_seg(RWX): org = 0x400c0000, len = 0x2000
rtc_slow_seg(RW): org = 0x50000000, len = 0x2000 - CONFIG_RESERVE_RTC_MEM
Expand All @@ -84,7 +96,7 @@ MEMORY
#endif

#ifdef CONFIG_ESP_SPIRAM
ext_ram_seg(RW): org = 0x3f800000, len = CONFIG_ESP_SPIRAM_SIZE
ext_ram_seg(RW): org = procpu_extram_org, len = procpu_extram_len
#endif /* CONFIG_ESP_SPIRAM */

#ifdef CONFIG_GEN_ISR_TABLES
Expand Down
Loading

0 comments on commit b41f514

Please sign in to comment.