feat(esp_psram): add option to carve unencrypted PSRAM region

Adds CONFIG_SPIRAM_ENC_EXEMPT, available on chips that support per-page
PSRAM encryption configuration (esp32c5, esp32c61, esp32p4). When
enabled, esp_psram carves CONFIG_SPIRAM_ENC_EXEMPT_SIZE off the top of
PSRAM and maps it via the new mmu_hal_map_region_no_enc() helper, which
writes MMU entries without the SENSITIVE bit. The region is registered
as a separate heap pool reachable only through the new
MALLOC_CAP_SPIRAM_NO_ENC capability bit, so default SPIRAM allocations
cannot accidentally land there.

PSRAM encryption imposes alignment constraints that some DMA engines
(e.g. 2D-DMA) cannot satisfy. This option lets such workloads place
their buffers in unencrypted PSRAM while keeping the rest of PSRAM
(and flash) encrypted. Default disabled; security implications are
documented in the Kconfig help text.
This commit is contained in:
Mahavir Jain
2026-05-14 19:21:18 +05:30
parent cc532288e8
commit 23aba459f5
8 changed files with 204 additions and 7 deletions
+25 -1
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -113,6 +113,30 @@ void mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vaddr,
}
}
#if SOC_PSRAM_ENCRYPTION_PAGE_CONFIGURABLE
void mmu_hal_map_region_no_enc(uint32_t vaddr, uint32_t paddr, uint32_t len)
{
uint32_t mmu_id = MMU_LL_PSRAM_MMU_ID;
uint32_t page_size_in_bytes = mmu_hal_pages_to_bytes(mmu_id, 1);
HAL_ASSERT(vaddr % page_size_in_bytes == 0);
HAL_ASSERT(paddr % page_size_in_bytes == 0);
HAL_ASSERT(mmu_ll_check_valid_paddr_region(mmu_id, paddr, len));
// Restrict to data vaddr space — unencrypted PSRAM must never back code/rodata.
HAL_ASSERT(mmu_hal_check_valid_ext_vaddr_region(mmu_id, vaddr, len, MMU_VADDR_DATA));
uint32_t page_num = (len + page_size_in_bytes - 1) / page_size_in_bytes;
uint32_t mmu_val = mmu_ll_format_paddr(mmu_id, paddr, MMU_TARGET_PSRAM0);
while (page_num) {
uint32_t entry_id = mmu_ll_get_entry_id(mmu_id, vaddr);
mmu_ll_write_entry_no_enc(mmu_id, entry_id, mmu_val);
vaddr += page_size_in_bytes;
mmu_val++;
page_num--;
}
}
#endif
void mmu_hal_unmap_region(uint32_t mmu_id, uint32_t vaddr, uint32_t len)
{
uint32_t page_size_in_bytes = mmu_hal_pages_to_bytes(mmu_id, 1);