SDAA362 June 2026 TDA4VE-Q1
The runtime overlay framework loads executable payloads from eMMC FATFS into a shared SRAM overlay slot. The loading process is implemented by the BootApp_emmcOverlayLoadAndRun() function.
The loader first reads and validates the overlay package header. The shared SRAM overlay slot is then cleared and the executable payload image is copied from the package file into the overlay execution region.
After the payload image has been loaded into SRAM, execution is performed by the BootApp_emmcOverlayExecute() function. Once execution is complete, the payload returns control to the resident boot_app runtime. The same SRAM overlay slot can then be reused for another payload package.
Below is a code snippet related to payload loading and execution.
int32_t BootApp_emmcOverlayLoadAndRun(const char *payloadFile,
BootApp_EmmcOverlayCtx *ctx)
{
BootApp_EmmcOverlayPkgHeader hdr;
int32_t status;
void *slotBase = (void *)((uintptr_t)BOOTAPP_EMMC_OVERLAY_SLOT_BASE);
if ((payloadFile == NULL) || (ctx == NULL))
{
return CSL_EBADARGS;
}
memset(&hdr, 0, sizeof(hdr));
status = BootApp_emmcOverlayReadFile(payloadFile, 0U, &hdr, sizeof(hdr));
if (status != CSL_PASS)
{
return status;
}
status = BootApp_emmcOverlayValidateHeader(payloadFile, &hdr);
if (status != CSL_PASS)
{
return status;
}
memset(slotBase, 0, BOOTAPP_EMMC_OVERLAY_SLOT_SIZE);
CacheP_wbInv(slotBase, BOOTAPP_EMMC_OVERLAY_SLOT_SIZE);
status = BootApp_emmcOverlayReadFile(payloadFile,
(uint32_t)sizeof(hdr),
slotBase,
hdr.codeSize);
if (status != CSL_PASS)
{
return status;
}
UART_printf("emmc_overlay: loaded %s code=%u entryOffset=%u slot=0x%x\r\n",
payloadFile,
hdr.codeSize,
hdr.entryOffset,
(uint32_t)((uintptr_t)slotBase));
status = BootApp_emmcOverlayExecute(slotBase, hdr.codeSize, hdr.entryOffset, ctx);
return status;
}
static void BootApp_emmcOverlaySyncForExec(void *addr, uint32_t size)
{
CacheP_wbInv(addr, size);
CSL_armR5CacheInvalidateAllIcache();
CSL_armR5Dsb();
CSL_armR5Isb();
}
int32_t BootApp_emmcOverlayExecute(void *slotBase,
uint32_t codeSize,
uint32_t entryOffset,
BootApp_EmmcOverlayCtx *ctx)
{
uintptr_t entryAddr;
BootApp_EmmcOverlayEntry entry;
if ((slotBase == NULL) || (ctx == NULL) || (codeSize == 0U) || (entryOffset >= codeSize))
{
return CSL_EBADARGS;
}
BootApp_emmcOverlaySyncForExec(slotBase, codeSize);
entryAddr = ((uintptr_t)slotBase) + ((uintptr_t)entryOffset);
/* R5F executes Thumb code. Force bit[0] for function pointer call. */
entryAddr |= (uintptr_t)0x1U;
entry = (BootApp_EmmcOverlayEntry)entryAddr;
UART_printf("emmc_overlay: execute entry=0x%x codeSize=%u entryOffset=%u\r\n",
(uint32_t)entryAddr,
codeSize,
entryOffset);
entry(ctx);
CSL_armR5Dsb();
CSL_armR5Isb();
return CSL_PASS;
}