From 29b8f3b7193c9003d278e65110985583cafa8450 Mon Sep 17 00:00:00 2001 From: Anton Maklakov Date: Tue, 18 May 2021 11:54:38 +0700 Subject: [PATCH] newlib: Add ESP_ROM_HAS_RETARGETABLE_LOCKING capability for C3 and S3 chips --- components/esp_rom/CMakeLists.txt | 2 +- components/esp_rom/component.mk | 2 +- components/esp_rom/esp32c3/esp_rom_caps.h | 9 ++-- components/esp_rom/esp32s3/esp_rom_caps.h | 11 ++-- .../esp_rom/include/esp32c3/rom/libc_stubs.h | 15 +----- .../esp_rom/include/esp32s3/rom/libc_stubs.h | 51 ++++++++++--------- components/newlib/locks.c | 16 ++---- components/newlib/newlib_init.c | 3 +- components/newlib/test/test_newlib.c | 2 +- 9 files changed, 49 insertions(+), 62 deletions(-) diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 38e502a204..667ab7f557 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -9,7 +9,7 @@ if(CONFIG_IDF_TARGET_ARCH_XTENSA) endif() idf_component_register(SRCS ${sources} - INCLUDE_DIRS include "${target}" + INCLUDE_DIRS include "${target}" "include/${target}" PRIV_REQUIRES soc hal) # Append a target linker script at the target-specific path, diff --git a/components/esp_rom/component.mk b/components/esp_rom/component.mk index 529abafdd2..4f53003366 100644 --- a/components/esp_rom/component.mk +++ b/components/esp_rom/component.mk @@ -1,4 +1,4 @@ -COMPONENT_ADD_INCLUDEDIRS := include esp32 +COMPONENT_ADD_INCLUDEDIRS := include esp32 include/esp32 COMPONENT_SRCDIRS := patches . #Linker scripts used to link the final application. diff --git a/components/esp_rom/esp32c3/esp_rom_caps.h b/components/esp_rom/esp32c3/esp_rom_caps.h index bae770da81..7c4226abe7 100644 --- a/components/esp_rom/esp32c3/esp_rom_caps.h +++ b/components/esp_rom/esp32c3/esp_rom_caps.h @@ -14,7 +14,8 @@ #pragma once -#define ESP_ROM_HAS_CRC_LE (1) // ROM CRC library supports Little Endian -#define ESP_ROM_HAS_CRC_BE (1) // ROM CRC library supports Big Endian -#define ESP_ROM_HAS_JPEG_DECODE (1) // ROM has JPEG decode library -#define ESP_ROM_UART_CLK_IS_XTAL (1) // UART clock source is selected to XTAL in ROM +#define ESP_ROM_HAS_CRC_LE (1) // ROM CRC library supports Little Endian +#define ESP_ROM_HAS_CRC_BE (1) // ROM CRC library supports Big Endian +#define ESP_ROM_HAS_JPEG_DECODE (1) // ROM has JPEG decode library +#define ESP_ROM_UART_CLK_IS_XTAL (1) // UART clock source is selected to XTAL in ROM +#define ESP_ROM_HAS_RETARGETABLE_LOCKING (1) // ROM was built with retargetable locking diff --git a/components/esp_rom/esp32s3/esp_rom_caps.h b/components/esp_rom/esp32s3/esp_rom_caps.h index aee488a025..7a235e4e98 100644 --- a/components/esp_rom/esp32s3/esp_rom_caps.h +++ b/components/esp_rom/esp32s3/esp_rom_caps.h @@ -14,8 +14,9 @@ #pragma once -#define ESP_ROM_HAS_CRC_LE (1) // ROM CRC library supports Little Endian -#define ESP_ROM_HAS_CRC_BE (1) // ROM CRC library supports Big Endian -#define ESP_ROM_HAS_JPEG_DECODE (1) // ROM has JPEG decode library -#define ESP_ROM_SUPPORT_MULTIPLE_UART (1) // ROM has multiple UARTs available for logging -#define ESP_ROM_UART_CLK_IS_XTAL (1) // UART clock source is selected to XTAL in ROM +#define ESP_ROM_HAS_CRC_LE (1) // ROM CRC library supports Little Endian +#define ESP_ROM_HAS_CRC_BE (1) // ROM CRC library supports Big Endian +#define ESP_ROM_HAS_JPEG_DECODE (1) // ROM has JPEG decode library +#define ESP_ROM_SUPPORT_MULTIPLE_UART (1) // ROM has multiple UARTs available for logging +#define ESP_ROM_UART_CLK_IS_XTAL (1) // UART clock source is selected to XTAL in ROM +#define ESP_ROM_HAS_RETARGETABLE_LOCKING (1) // ROM was built with retargetable locking diff --git a/components/esp_rom/include/esp32c3/rom/libc_stubs.h b/components/esp_rom/include/esp32c3/rom/libc_stubs.h index df78851c1b..233355e9c2 100644 --- a/components/esp_rom/include/esp32c3/rom/libc_stubs.h +++ b/components/esp_rom/include/esp32c3/rom/libc_stubs.h @@ -27,7 +27,7 @@ extern "C" { #endif /* -ESP32 ROM code contains implementations of some of C library functions. +ESP32-C3 ROM code contains implementations of some of C library functions. Whenever a function in ROM needs to use a syscall, it calls a pointer to the corresponding syscall implementation defined in the following struct. @@ -65,7 +65,6 @@ struct syscall_stub_table int (*_write_r)(struct _reent *r, int, const void *, int); int (*_lseek_r)(struct _reent *r, int, int, int); int (*_read_r)(struct _reent *r, int, void *, int); -#ifdef _RETARGETABLE_LOCKING void (*_retarget_lock_init)(_LOCK_T *lock); void (*_retarget_lock_init_recursive)(_LOCK_T *lock); void (*_retarget_lock_close)(_LOCK_T lock); @@ -76,18 +75,6 @@ struct syscall_stub_table int (*_retarget_lock_try_acquire_recursive)(_LOCK_T lock); void (*_retarget_lock_release)(_LOCK_T lock); void (*_retarget_lock_release_recursive)(_LOCK_T lock); -#else - void (*_lock_init)(_lock_t *lock); - void (*_lock_init_recursive)(_lock_t *lock); - void (*_lock_close)(_lock_t *lock); - void (*_lock_close_recursive)(_lock_t *lock); - void (*_lock_acquire)(_lock_t *lock); - void (*_lock_acquire_recursive)(_lock_t *lock); - int (*_lock_try_acquire)(_lock_t *lock); - int (*_lock_try_acquire_recursive)(_lock_t *lock); - void (*_lock_release)(_lock_t *lock); - void (*_lock_release_recursive)(_lock_t *lock); -#endif int (*_printf_float)(struct _reent *data, void *pdata, FILE * fp, int (*pfunc) (struct _reent *, FILE *, const char *, size_t len), va_list * ap); int (*_scanf_float) (struct _reent *rptr, void *pdata, FILE *fp, va_list *ap); void (*__assert_func) (const char *file, int line, const char * func, const char *failedexpr) __attribute__((noreturn)); diff --git a/components/esp_rom/include/esp32s3/rom/libc_stubs.h b/components/esp_rom/include/esp32s3/rom/libc_stubs.h index 9c9b0a21cd..1298eeda55 100644 --- a/components/esp_rom/include/esp32s3/rom/libc_stubs.h +++ b/components/esp_rom/include/esp32s3/rom/libc_stubs.h @@ -14,6 +14,7 @@ #pragma once +#include #include #include #include @@ -39,23 +40,24 @@ extern "C" { * to actual implementations of corresponding syscalls. * */ -struct syscall_stub_table { - struct _reent *(*__getreent)(void); - void *(*_malloc_r)(struct _reent *r, size_t); - void (*_free_r)(struct _reent *r, void *); - void *(*_realloc_r)(struct _reent *r, void *, size_t); - void *(*_calloc_r)(struct _reent *r, size_t, size_t); +struct syscall_stub_table +{ + struct _reent* (*__getreent)(void); + void* (*_malloc_r)(struct _reent *r, size_t); + void (*_free_r)(struct _reent *r, void*); + void* (*_realloc_r)(struct _reent *r, void*, size_t); + void* (*_calloc_r)(struct _reent *r, size_t, size_t); void (*_abort)(void); - int (*_system_r)(struct _reent *r, const char *); - int (*_rename_r)(struct _reent *r, const char *, const char *); + int (*_system_r)(struct _reent *r, const char*); + int (*_rename_r)(struct _reent *r, const char*, const char*); clock_t (*_times_r)(struct _reent *r, struct tms *); int (*_gettimeofday_r) (struct _reent *r, struct timeval *, void *); void (*_raise_r)(struct _reent *r); - int (*_unlink_r)(struct _reent *r, const char *); - int (*_link_r)(struct _reent *r, const char *, const char *); - int (*_stat_r)(struct _reent *r, const char *, struct stat *); + int (*_unlink_r)(struct _reent *r, const char*); + int (*_link_r)(struct _reent *r, const char*, const char*); + int (*_stat_r)(struct _reent *r, const char*, struct stat *); int (*_fstat_r)(struct _reent *r, int, struct stat *); - void *(*_sbrk_r)(struct _reent *r, ptrdiff_t); + void* (*_sbrk_r)(struct _reent *r, ptrdiff_t); int (*_getpid_r)(struct _reent *r); int (*_kill_r)(struct _reent *r, int, int); void (*_exit_r)(struct _reent *r, int); @@ -64,18 +66,21 @@ struct syscall_stub_table { int (*_write_r)(struct _reent *r, int, const void *, int); int (*_lseek_r)(struct _reent *r, int, int, int); int (*_read_r)(struct _reent *r, int, void *, int); - void (*_lock_init)(_lock_t *lock); - void (*_lock_init_recursive)(_lock_t *lock); - void (*_lock_close)(_lock_t *lock); - void (*_lock_close_recursive)(_lock_t *lock); - void (*_lock_acquire)(_lock_t *lock); - void (*_lock_acquire_recursive)(_lock_t *lock); - int (*_lock_try_acquire)(_lock_t *lock); - int (*_lock_try_acquire_recursive)(_lock_t *lock); - void (*_lock_release)(_lock_t *lock); - void (*_lock_release_recursive)(_lock_t *lock); - int (*_printf_float)(struct _reent *data, void *pdata, FILE *fp, int (*pfunc) (struct _reent *, FILE *, const char *, size_t len), va_list *ap); + void (*_retarget_lock_init)(_LOCK_T *lock); + void (*_retarget_lock_init_recursive)(_LOCK_T *lock); + void (*_retarget_lock_close)(_LOCK_T lock); + void (*_retarget_lock_close_recursive)(_LOCK_T lock); + void (*_retarget_lock_acquire)(_LOCK_T lock); + void (*_retarget_lock_acquire_recursive)(_LOCK_T lock); + int (*_retarget_lock_try_acquire)(_LOCK_T lock); + int (*_retarget_lock_try_acquire_recursive)(_LOCK_T lock); + void (*_retarget_lock_release)(_LOCK_T lock); + void (*_retarget_lock_release_recursive)(_LOCK_T lock); + int (*_printf_float)(struct _reent *data, void *pdata, FILE * fp, int (*pfunc) (struct _reent *, FILE *, const char *, size_t len), va_list * ap); int (*_scanf_float) (struct _reent *rptr, void *pdata, FILE *fp, va_list *ap); + void (*__assert_func) (const char *file, int line, const char * func, const char *failedexpr) __attribute__((noreturn)); + void (*__sinit) (struct _reent *r); + void (*_cleanup_r) (struct _reent* r); }; extern struct syscall_stub_table *syscall_table_ptr; diff --git a/components/newlib/locks.c b/components/newlib/locks.c index 86c8433767..882ea8dd0c 100644 --- a/components/newlib/locks.c +++ b/components/newlib/locks.c @@ -21,6 +21,7 @@ #include "freertos/semphr.h" #include "freertos/task.h" #include "freertos/portable.h" +#include "esp_rom_caps.h" /* Notes on our newlib lock implementation: * @@ -210,7 +211,6 @@ void IRAM_ATTR _lock_release_recursive(_lock_t *lock) { lock_release_generic(lock, queueQUEUE_TYPE_RECURSIVE_MUTEX); } -#ifdef _RETARGETABLE_LOCKING /* To ease the transition to newlib 3.3.0, this part is kept under an ifdef. * After the toolchain with newlib 3.3.0 is released and merged, the ifdefs * can be removed. @@ -252,8 +252,8 @@ static StaticSemaphore_t s_common_mutex; static StaticSemaphore_t s_common_recursive_mutex; -#ifdef CONFIG_IDF_TARGET_ESP32C3 -/* C3 ROM is built without Newlib static lock symbols exported, and +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) +/* C3 and S3 ROMs are built without Newlib static lock symbols exported, and * with an extra level of _LOCK_T indirection in mind. * The following is a workaround for this: * - on startup, we call esp_rom_newlib_init_common_mutexes to set @@ -267,7 +267,7 @@ static StaticSemaphore_t s_common_recursive_mutex; */ #define ROM_NEEDS_MUTEX_OVERRIDE -#endif // CONFIG_IDF_TARGET_ESP32C3 +#endif // defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) #ifdef ROM_NEEDS_MUTEX_OVERRIDE #define ROM_MUTEX_MAGIC 0xbb10c433 @@ -407,11 +407,3 @@ void esp_newlib_locks_init(void) #error Unsupported target #endif } - -#else // _RETARGETABLE_LOCKING - -void esp_newlib_locks_init(void) -{ -} - -#endif // _RETARGETABLE_LOCKING diff --git a/components/newlib/newlib_init.c b/components/newlib/newlib_init.c index 24ef68e737..7f95b49885 100644 --- a/components/newlib/newlib_init.c +++ b/components/newlib/newlib_init.c @@ -26,6 +26,7 @@ #include "esp_attr.h" #include "sdkconfig.h" #include "soc/soc_caps.h" +#include "esp_rom_caps.h" #if CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/libc_stubs.h" @@ -81,7 +82,7 @@ static struct syscall_stub_table s_stub_table = { ._write_r = (int (*)(struct _reent *r, int, const void *, int)) &_write_r, ._lseek_r = (int (*)(struct _reent *r, int, int, int)) &_lseek_r, ._read_r = (int (*)(struct _reent *r, int, void *, int)) &_read_r, -#if _RETARGETABLE_LOCKING /* TODO: only if RETARGETABLE LOCKING IS IN ROM */ +#if ESP_ROM_HAS_RETARGETABLE_LOCKING ._retarget_lock_init = &__retarget_lock_init, ._retarget_lock_init_recursive = &__retarget_lock_init_recursive, ._retarget_lock_close = &__retarget_lock_close, diff --git a/components/newlib/test/test_newlib.c b/components/newlib/test/test_newlib.c index 552c0939ef..6851ce1eb5 100644 --- a/components/newlib/test/test_newlib.c +++ b/components/newlib/test/test_newlib.c @@ -141,7 +141,7 @@ TEST_CASE("check if ROM or Flash is used for functions", "[newlib]") #if defined(CONFIG_IDF_TARGET_ESP32) && !defined(CONFIG_SPIRAM) TEST_ASSERT(fn_in_rom(atoi)); TEST_ASSERT(fn_in_rom(strtol)); -#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C3) +#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) /* S3 and C3 always use these from ROM */ TEST_ASSERT(fn_in_rom(atoi)); TEST_ASSERT(fn_in_rom(strtol));