Support for building and running external apps (#112)
This commit is contained in:
committed by
GitHub
parent
42e843b463
commit
415442e410
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/errno.h>
|
||||
#include "esp_idf_version.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp32s2/rom/cache.h"
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
#include "esp32s2/spiram.h"
|
||||
#endif
|
||||
#include "soc/mmu.h"
|
||||
#include "private/elf_platform.h"
|
||||
|
||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
|
||||
#define PSRAM_VADDR_START 0x3f800000
|
||||
#else
|
||||
#define PSRAM_VADDR_START (DRAM0_CACHE_ADDRESS_HIGH - esp_spiram_get_size())
|
||||
#endif
|
||||
|
||||
#define MMU_INVALID BIT(14)
|
||||
#define MMU_UNIT_SIZE 0x10000
|
||||
#define MMU_REG ((volatile uint32_t *)DR_REG_MMU_TABLE)
|
||||
|
||||
#define ESP_MMU_IBUS_BASE IRAM0_ADDRESS_LOW
|
||||
#define ESP_MMU_IBUS_MAX ((IRAM0_ADDRESS_HIGH - IRAM0_ADDRESS_LOW) / \
|
||||
MMU_UNIT_SIZE)
|
||||
#define ESP_MMU_IBUS_OFF (8)
|
||||
|
||||
#define DADDR_2_SECS(v) ((v) / MMU_UNIT_SIZE)
|
||||
#define IADDR_2_SECS(v) ((v) / MMU_UNIT_SIZE)
|
||||
|
||||
#define PSRAM_OFF(v) ((v) - PSRAM_VADDR_START)
|
||||
#define PSRAM_SECS(v) DADDR_2_SECS(PSRAM_OFF((uintptr_t)(v)))
|
||||
#define PSRAM_ALIGN(v) ((uintptr_t)(v) & (~(MMU_UNIT_SIZE - 1)))
|
||||
|
||||
#define ICACHE_ADDR(s) (ESP_MMU_IBUS_BASE + (s) * MMU_UNIT_SIZE)
|
||||
|
||||
extern void spi_flash_disable_interrupts_caches_and_other_cpu(void);
|
||||
extern void spi_flash_enable_interrupts_caches_and_other_cpu(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize MMU hardware remapping function.
|
||||
*
|
||||
* @param elf - ELF object pointer
|
||||
*
|
||||
* @return 0 if success or a negative value if failed.
|
||||
*/
|
||||
int IRAM_ATTR esp_elf_arch_init_mmu(esp_elf_t *elf)
|
||||
{
|
||||
int ret;
|
||||
int off;
|
||||
uint32_t ibus_secs;
|
||||
volatile uint32_t dbus_secs;
|
||||
esp_elf_sec_t *sec = &elf->sec[ELF_SEC_TEXT];
|
||||
volatile uint32_t *p = MMU_REG;
|
||||
|
||||
if (sec->size % MMU_UNIT_SIZE) {
|
||||
ibus_secs = IADDR_2_SECS(sec->size) + 1;
|
||||
} else {
|
||||
ibus_secs = IADDR_2_SECS(sec->size);
|
||||
}
|
||||
|
||||
dbus_secs = PSRAM_SECS(elf->ptext);
|
||||
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
|
||||
for (off = ESP_MMU_IBUS_OFF; off < ESP_MMU_IBUS_MAX; off++) {
|
||||
if (p[off] == MMU_INVALID) {
|
||||
int j;
|
||||
|
||||
for (j = 1; j < ibus_secs; j++) {
|
||||
if (p[off + j] != MMU_INVALID) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j >= ibus_secs) {
|
||||
for (int k = 0; k < ibus_secs; k++) {
|
||||
p [off + k] = MMU_ACCESS_SPIRAM | (dbus_secs + k);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
|
||||
if (off >= ESP_MMU_IBUS_MAX) {
|
||||
ret = -EIO;
|
||||
} else {
|
||||
elf->mmu_off = off;
|
||||
elf->mmu_num = ibus_secs;
|
||||
elf->text_off = ICACHE_ADDR(off) - PSRAM_ALIGN(elf->ptext);
|
||||
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-initialize MMU hardware remapping function.
|
||||
*
|
||||
* @param elf - ELF object pointer
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void IRAM_ATTR esp_elf_arch_deinit_mmu(esp_elf_t *elf)
|
||||
{
|
||||
volatile int num = elf->mmu_num;
|
||||
volatile int off = elf->mmu_off;
|
||||
volatile uint32_t *p = MMU_REG;
|
||||
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
p [off + i] = MMU_INVALID;
|
||||
}
|
||||
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
}
|
||||
Reference in New Issue
Block a user