Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heap init code improvements and updates #8458

Merged
merged 5 commits into from
Feb 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions cores/esp8266/core_esp8266_app_entry_noextra4k.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,19 @@ extern "C" void app_entry_redefinable(void)
{
g_pcont = &g_cont;

#ifdef UMM_INIT_USE_IRAM
/*
* Legacy option: the umm_init() call path must reside in IRAM.
*/
umm_init();
#else
/*
* Instruction cache is enabled/disabled around running umm_init().
* Allows the use of IROM (flash) to store umm_init().
*/
mmu_wrap_irom_fn(umm_init);
#endif

/* Call the entry point of the SDK code. */
call_user_start();
}
Expand Down
5 changes: 5 additions & 0 deletions cores/esp8266/core_esp8266_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,12 @@ extern "C" void app_entry_redefinable(void)

/* Doing umm_init just once before starting the SDK, allowed us to remove
test and init calls at each malloc API entry point, saving IRAM. */
#ifdef UMM_INIT_USE_IRAM
umm_init();
#else
// umm_init() is in IROM
mmu_wrap_irom_fn(umm_init);
#endif
/* Call the entry point of the SDK code. */
call_user_start();
}
Expand Down
62 changes: 30 additions & 32 deletions cores/esp8266/hwdt_app_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@
#include <esp8266_peri.h>
#include <uart.h>
#include <pgmspace.h>
#include "mmu_iram.h"

extern "C" {
#include <user_interface.h>
Expand Down Expand Up @@ -1007,6 +1008,18 @@ STATIC void IRAM_MAYBE handle_hwdt(void) {
#endif
}

#if defined(DEBUG_ESP_HWDT_DEV_DEBUG) && !defined(USE_IRAM)
static void printSanityCheck() {
ETS_PRINTF("\n\nsys_stack_first: %p\n", sys_stack_first);
ETS_PRINTF( "CONT_STACK: %p\n", CONT_STACK);
ETS_PRINTF( "g_pcont: %p\n", g_pcont);
ETS_PRINTF( "ROM_STACK: %p\n", ROM_STACK);
ETS_PRINTF( "get_noextra4k_g_pcont(): %p\n", get_noextra4k_g_pcont());
ETS_PRINTF( "g_rom_stack: %p\n", g_rom_stack);
ETS_PRINTF( "g_rom_stack_A16_sz: 0x%08X\n\n", g_rom_stack_A16_sz);
}
#endif //DEBUG_ESP_HWDT_DEV_DEBUG

/*
* Using Cache_Read_Enable/Cache_Read_Disable to reduce IRAM usage. Moved
* strings and most functions to flash. At this phase of the startup, "C++" has
Expand All @@ -1019,34 +1032,11 @@ STATIC void IRAM_MAYBE handle_hwdt(void) {
* https://richard.burtons.org/2015/06/12/esp8266-cache_read_enable/.
* Additional insight can be gleemed from reviewing the ESP8266_RTOS_SDK.
* (eg. ../components/bootloader_support/src/bootloader_utility.c)
*
* The logic to use Cache_Read_Enable and Cache_Read_Disable has been
* generalized into a wrapper function, mmu_wrap_irom_fn, and moved to
* mmu_iram.cpp.
*/
#define ICACHE_SIZE_32 1
#define ICACHE_SIZE_16 0

extern "C" void Cache_Read_Disable(void);
extern "C" void Cache_Read_Enable(uint8_t map, uint8_t p, uint8_t v);

#ifndef USE_IRAM
static void IRAM_ATTR __attribute__((noinline)) handle_hwdt_icache() __attribute__((used));
void handle_hwdt_icache() {
Cache_Read_Enable(0, 0, ICACHE_SIZE_16);
handle_hwdt();
Cache_Read_Disable();
}
#endif // USE_IRAM


#if defined(DEBUG_ESP_HWDT_DEV_DEBUG) && !defined(USE_IRAM)
static void printSanityCheck() {
ETS_PRINTF("\n\nsys_stack_first: %p\n", sys_stack_first);
ETS_PRINTF( "CONT_STACK: %p\n", CONT_STACK);
ETS_PRINTF( "g_pcont: %p\n", g_pcont);
ETS_PRINTF( "ROM_STACK: %p\n", ROM_STACK);
ETS_PRINTF( "get_noextra4k_g_pcont(): %p\n", get_noextra4k_g_pcont());
ETS_PRINTF( "g_rom_stack: %p\n", g_rom_stack);
ETS_PRINTF( "g_rom_stack_A16_sz: 0x%08X\n\n", g_rom_stack_A16_sz);
}
#endif //DEBUG_ESP_HWDT_DEV_DEBUG

/*
hwdt_pre_sdk_init() is the result of a hook for development diagnotics which
Expand All @@ -1071,9 +1061,8 @@ void hwdt_pre_sdk_init(void) {
#endif
}

static void IRAM_ATTR __attribute__((noinline)) hwdt_pre_sdk_init_icache(void) __attribute__((used));
static void __attribute__((noinline)) hwdt_pre_sdk_init_icache(void) __attribute__((used));
void hwdt_pre_sdk_init_icache(void) {
Cache_Read_Enable(0, 0, ICACHE_SIZE_16);
#ifdef DEBUG_ESP_HWDT_UART_SPEED
const uint32_t uart_divisor = set_uart_speed(0, DEBUG_ESP_HWDT_UART_SPEED);
#endif
Expand All @@ -1085,7 +1074,6 @@ void hwdt_pre_sdk_init_icache(void) {
adjust_uart_speed(uart_divisor);
}
#endif
Cache_Read_Disable();
}

/*
Expand All @@ -1106,6 +1094,7 @@ asm (
".literal .umm_init, umm_init\n\t"
".literal .call_user_start, call_user_start\n\t"
".literal .get_noextra4k_g_pcont, get_noextra4k_g_pcont\n\t"
".literal .mmu_wrap_irom_fn, mmu_wrap_irom_fn\n\t"
".align 4\n\t"
".global app_entry_redefinable\n\t"
".type app_entry_redefinable, @function\n\t"
Expand All @@ -1129,7 +1118,9 @@ asm (
#ifdef USE_IRAM
"call0 handle_hwdt\n\t"
#else
"call0 handle_hwdt_icache\n\t"
"l32r a0, .mmu_wrap_irom_fn\n\t"
"movi a2, handle_hwdt\n\t"
"callx0 a0\n\t"
#endif
/*
* Use new calculated SYS stack from top.
Expand Down Expand Up @@ -1160,7 +1151,9 @@ asm (
/*
* Allow for running additional diagnotics supplied at link time.
*/
"call0 hwdt_pre_sdk_init_icache\n\t"
"l32r a0, .mmu_wrap_irom_fn\n\t"
"movi a2, hwdt_pre_sdk_init_icache\n\t"
"callx0 a0\n\t"

// In case somebody cares, leave things as we found them
// - Restore ROM BSS zeros.
Expand All @@ -1174,7 +1167,12 @@ asm (
* improvements could possibly use hwdt_pre_sdk_init() to run other early
* diagnostic tools.
*/
#ifdef UMM_INIT_USE_IRAM
"l32r a0, .umm_init\n\t"
#else
"l32r a0, .mmu_wrap_irom_fn\n\t"
"l32r a2, .umm_init\n\t"
#endif
"callx0 a0\n\t"

"l32r a3, .call_user_start\n\t"
Expand Down
20 changes: 18 additions & 2 deletions cores/esp8266/mmu_iram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@
#include "mmu_iram.h"
#include <user_interface.h>

#define ICACHE_SIZE_32 1
#define ICACHE_SIZE_16 0

extern "C" {

#if (MMU_ICACHE_SIZE == 0x4000)
#define SOC_CACHE_SIZE 0 // 16KB
#define SOC_CACHE_SIZE ICACHE_SIZE_16
#pragma message("ICACHE size 16K")
#else
#define SOC_CACHE_SIZE 1 // 32KB
#define SOC_CACHE_SIZE ICACHE_SIZE_32
#endif

#if (MMU_ICACHE_SIZE == 0x4000)
Expand Down Expand Up @@ -185,8 +188,21 @@ extern "C" void pinMode( uint8_t pin, uint8_t mode ) {

__pinMode( pin, mode );
}
#else // #ifdef DEV_DEBUG_PRINT
extern void Cache_Read_Disable(void);
#endif // #ifdef DEV_DEBUG_PRINT

#else // #if (MMU_ICACHE_SIZE == 0x4000)
extern void Cache_Read_Enable(uint8_t map, uint8_t p, uint8_t v);
#endif // #if (MMU_ICACHE_SIZE == 0x4000)

/*
* This wrapper is for running code from IROM (flash) before the SDK starts.
*/
void IRAM_ATTR mmu_wrap_irom_fn(void (*fn)(void)) {
Cache_Read_Enable(0, 0, ICACHE_SIZE_16);
fn();
Cache_Read_Disable();
}

};
18 changes: 18 additions & 0 deletions cores/esp8266/mmu_iram.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,24 @@ DBG_MMU_FLUSH(0)
#define DBG_MMU_PRINTF(...) do {} while(false)
#endif // defined(DEV_DEBUG_PRINT) || defined(DEBUG_ESP_MMU)

/*
* This wrapper is for running code from IROM (flash) before the SDK starts.
*
* Wraps a `void fn(void)` call with calls to enable and disable iCACHE.
* Allows a function that resides in IROM to run before the SDK starts.
*
* Do not use once the SDK has started.
*
* Because the SDK initialization code has not run, nearly all the SDK functions
* are not safe to call.
*
* Note printing at this early stage is complicated. To gain more insight,
* review DEV_DEBUG_PRINT build path in mmu_iram.cpp. To handle strings stored
* in IROM, review printing method and comments in hwdt_app_entry.cpp.
*
*/
void IRAM_ATTR mmu_wrap_irom_fn(void (*fn)(void));

static inline __attribute__((always_inline))
bool mmu_is_iram(const void *addr) {
const uintptr_t iram_start = (uintptr_t)XCHAL_INSTRAM1_VADDR;
Expand Down
2 changes: 1 addition & 1 deletion cores/esp8266/umm_malloc/umm_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
void *umm_info(void *ptr, bool force) {
UMM_CRITICAL_DECL(id_info);

UMM_INIT_HEAP;
UMM_CHECK_INITIALIZED();

uint16_t blockNo = 0;

Expand Down
2 changes: 1 addition & 1 deletion cores/esp8266/umm_malloc/umm_integrity.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ bool umm_integrity_check(void) {
uint16_t prev;
uint16_t cur;

UMM_INIT_HEAP;
UMM_CHECK_INITIALIZED();

/* Iterate through all free blocks */
prev = 0;
Expand Down
2 changes: 1 addition & 1 deletion cores/esp8266/umm_malloc/umm_local.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ size_t umm_block_size(void) {
#if defined(UMM_STATS) || defined(UMM_STATS_FULL)
// Keep complete call path in IRAM
size_t umm_free_heap_size_lw(void) {
UMM_INIT_HEAP;
UMM_CHECK_INITIALIZED();

umm_heap_context_t *_context = umm_get_current_heap();
return (size_t)_context->UMM_FREE_BLOCKS * sizeof(umm_block);
Expand Down
Loading