diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index 27f55b52e29..9ddcab35d1b 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -34,7 +34,7 @@ endif CHIP_CSRCS = esp32_allocateheap.c esp32_clockconfig.c esp32_gpio.c CHIP_CSRCS += esp32_systemreset.c esp32_resetcause.c CHIP_CSRCS += esp32_irq.c esp32_region.c esp32_rtc_gpio.c -CHIP_CSRCS += esp32_user.c +CHIP_CSRCS += esp32_user.c esp32_libc_stubs.c CHIP_CSRCS += esp32_dma.c ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y) diff --git a/arch/xtensa/src/esp32/esp32_libc_stubs.c b/arch/xtensa/src/esp32/esp32_libc_stubs.c new file mode 100644 index 00000000000..f65a8653189 --- /dev/null +++ b/arch/xtensa/src/esp32/esp32_libc_stubs.c @@ -0,0 +1,337 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/esp32_libc_stubs.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "rom/esp32_libc_stubs.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define _lock_t int + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +static mutex_t g_nxlock_common; +static mutex_t g_nxlock_recursive; + +/* Forward declaration */ + +struct _reent; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int _close_r(struct _reent *r, int fd) +{ + return close(fd); +} + +int _fstat_r(struct _reent *r, int fd, struct stat *statbuf) +{ + return fstat(fd, statbuf); +} + +int _getpid_r(struct _reent *r) +{ + return getpid(); +} + +int _kill_r(struct _reent *r, int pid, int sig) +{ + return kill(pid, sig); +} + +int _link_r(struct _reent *r, const char *oldpath, const char *newpath) +{ + /* TODO */ + + return 0; +} + +int lseek_r(struct _reent *r, int fd, int offset, int whence) +{ + return lseek(fd, offset, whence); +} + +int _open_r(struct _reent *r, const char *pathname, int flags, int mode) +{ + return open(pathname, flags, mode); +} + +int read_r(struct _reent *r, int fd, void *buf, int count) +{ + return read(fd, buf, count); +} + +int _rename_r(struct _reent *r, const char *oldpath, const char *newpath) +{ + return rename(oldpath, newpath); +} + +void *_sbrk_r(struct _reent *r, ptrdiff_t increment) +{ + /* TODO: sbrk is only supported on Kernel mode */ + + errno = -ENOMEM; + return (void *) -1; +} + +int _stat_r(struct _reent *r, const char *pathname, struct stat *statbuf) +{ + return stat(pathname, statbuf); +} + +clock_t _times_r(struct _reent *r, struct tms *buf) +{ + return times(buf); +} + +int _unlink_r(struct _reent *r, const char *pathname) +{ + return unlink(pathname); +} + +int write_r(struct _reent *r, int fd, const void *buf, int count) +{ + return write(fd, buf, count); +} + +int _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz) +{ + return gettimeofday(tv, tz); +} + +void *_malloc_r(struct _reent *r, size_t size) +{ + return malloc(size); +} + +void *_realloc_r(struct _reent *r, void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +void *_calloc_r(struct _reent *r, size_t nmemb, size_t size) +{ + return calloc(nmemb, size); +} + +void _free_r(struct _reent *r, void *ptr) +{ + free(ptr); +} + +void _abort(void) +{ + abort(); +} + +void _raise_r(struct _reent *r) +{ + /* FIXME */ +} + +void _lock_init(_lock_t *lock) +{ + nxmutex_init(&g_nxlock_common); + nxsem_get_value(&g_nxlock_common.sem, lock); +} + +void _lock_init_recursive(_lock_t *lock) +{ + nxmutex_init(&g_nxlock_recursive); + nxsem_get_value(&g_nxlock_recursive.sem, lock); +} + +void _lock_close(_lock_t *lock) +{ + nxmutex_destroy(&g_nxlock_common); + *lock = 0; +} + +void _lock_close_recursive(_lock_t *lock) +{ + nxmutex_destroy(&g_nxlock_recursive); + *lock = 0; +} + +void _lock_acquire(_lock_t *lock) +{ + nxmutex_lock(&g_nxlock_common); + nxsem_get_value(&g_nxlock_common.sem, lock); +} + +void _lock_acquire_recursive(_lock_t *lock) +{ + nxmutex_lock(&g_nxlock_recursive); + nxsem_get_value(&g_nxlock_recursive.sem, lock); +} + +int _lock_try_acquire(_lock_t *lock) +{ + nxmutex_trylock(&g_nxlock_common); + nxsem_get_value(&g_nxlock_common.sem, lock); + return 0; +} + +int _lock_try_acquire_recursive(_lock_t *lock) +{ + nxmutex_trylock(&g_nxlock_recursive); + nxsem_get_value(&g_nxlock_recursive.sem, lock); + return 0; +} + +void _lock_release(_lock_t *lock) +{ + nxmutex_unlock(&g_nxlock_common); + nxsem_get_value(&g_nxlock_common.sem, lock); +} + +void _lock_release_recursive(_lock_t *lock) +{ + nxmutex_unlock(&g_nxlock_recursive); + nxsem_get_value(&g_nxlock_recursive.sem, lock); +} + +struct _reent *__getreent(void) +{ + /* TODO */ + + return (struct _reent *) NULL; +} + +int _system_r(struct _reent *r, const char *command) +{ + /* TODO: Implement system() */ + + return 0; +} + +void noreturn_function __assert_func(const char *file, int line, + const char *func, const char *expr) +{ + __assert(file, line, expr); +} + +void _cleanup_r(struct _reent *r) +{ +} + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct syscall_stub_table g_stub_table = +{ + .__getreent = &__getreent, + ._malloc_r = &_malloc_r, + ._free_r = &_free_r, + ._realloc_r = &_realloc_r, + ._calloc_r = &_calloc_r, + ._abort = &_abort, + ._system_r = &_system_r, + ._rename_r = &_rename_r, + ._times_r = &_times_r, + ._gettimeofday_r = &_gettimeofday_r, + ._raise_r = &_raise_r, + ._unlink_r = &_unlink_r, + ._link_r = &_link_r, + ._stat_r = &_stat_r, + ._fstat_r = &_fstat_r, + ._sbrk_r = &_sbrk_r, + ._getpid_r = &_getpid_r, + ._kill_r = &_kill_r, + ._exit_r = NULL, + ._close_r = &_close_r, + ._open_r = &_open_r, + ._write_r = &write_r, + ._lseek_r = &lseek_r, + ._read_r = &read_r, + ._lock_init = &_lock_init, + ._lock_init_recursive = &_lock_init_recursive, + ._lock_close = &_lock_close, + ._lock_close_recursive = &_lock_close_recursive, + ._lock_acquire = &_lock_acquire, + ._lock_acquire_recursive = &_lock_acquire_recursive, + ._lock_try_acquire = &_lock_try_acquire, + ._lock_try_acquire_recursive = &_lock_try_acquire_recursive, + ._lock_release = &_lock_release, + ._lock_release_recursive = &_lock_release_recursive, + ._printf_float = NULL, + ._scanf_float = NULL +}; + +/**************************************************************************** + * Name: esp_setup_syscall_table + * + * Description: + * Configure the syscall table used by the ROM code for calling C library + * functions. + * ROM code from Espressif's chips 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 syscall_stub_table struct. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_setup_syscall_table(void) +{ + syscall_table_ptr_pro = (struct syscall_stub_table *)&g_stub_table; + syscall_table_ptr_app = (struct syscall_stub_table *)&g_stub_table; + + /* Newlib 2.2.0 is used in ROM, the following lock symbols are defined: */ + + extern _lock_t __sfp_lock; + __sfp_lock = (_lock_t) &g_nxlock_recursive; + + extern _lock_t __sinit_lock; + __sinit_lock = (_lock_t) &g_nxlock_recursive; + + extern _lock_t __env_lock_object; + __env_lock_object = (_lock_t) &g_nxlock_recursive; + + extern _lock_t __tz_lock_object; + __tz_lock_object = (_lock_t) &g_nxlock_common; +} diff --git a/arch/xtensa/src/esp32/esp32_start.c b/arch/xtensa/src/esp32/esp32_start.c index 8aeab7f2714..bde7ef8624d 100644 --- a/arch/xtensa/src/esp32/esp32_start.c +++ b/arch/xtensa/src/esp32/esp32_start.c @@ -44,6 +44,7 @@ #endif #include "hardware/esp32_dport.h" #include "hardware/esp32_rtccntl.h" +#include "rom/esp32_libc_stubs.h" /**************************************************************************** * Pre-processor Definitions @@ -243,6 +244,10 @@ static noreturn_function void __esp32_start(void) #endif + /* Setup the syscall table needed by the ROM code */ + + esp_setup_syscall_table(); + /* Initialize onboard resources */ esp32_board_initialize(); diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.c b/arch/xtensa/src/esp32/esp32_wifi_adapter.c index 21dad51c16f..1a1a1dad657 100644 --- a/arch/xtensa/src/esp32/esp32_wifi_adapter.c +++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.c @@ -4504,31 +4504,6 @@ int32_t esp_timer_delete(esp_timer_handle_t timer) return 0; } -/**************************************************************************** - * Name: __assert_func - * - * Description: - * Delete timer and free resource - * - * Input Parameters: - * file - assert file - * line - assert line - * func - assert function - * expr - assert condition - * - * Returned Value: - * None - * - ****************************************************************************/ - -void __assert_func(const char *file, int line, - const char *func, const char *expr) -{ - wlerr("Assert failed in %s, %s:%d (%s)", - func, file, line, expr); - abort(); -} - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/arch/xtensa/src/esp32/rom/esp32_libc_stubs.h b/arch/xtensa/src/esp32/rom/esp32_libc_stubs.h new file mode 100644 index 00000000000..e63e1004cf1 --- /dev/null +++ b/arch/xtensa/src/esp32/rom/esp32_libc_stubs.h @@ -0,0 +1,133 @@ +/**************************************************************************** + * arch/xtensa/src/esp32/rom/esp32_libc_stubs.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32_ROM_ESP32_LIBC_STUBS_H +#define __ARCH_XTENSA_SRC_ESP32_ROM_ESP32_LIBC_STUBS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define _lock_t int + +/* Forward declaration */ + +struct _reent; + +/** + * @brief ESP32 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. + * + * The table itself, by default, is not allocated in RAM. There are + * two pointers, `syscall_table_ptr_pro` and `syscall_table_ptr_app`, + * which can be set to point to the locations of syscall tables of + * CPU 0 (aka PRO CPU) and CPU 1 (aka APP CPU). Location of these + * pointers in .bss segment of ROM code is defined in linker script. + * + * So, before using any of the C library functions (except for pure + * functions and memcpy/memset functions), application must allocate + * syscall table structure for each CPU being used, and populate it + * with pointers 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); + void (* _abort)(void); + 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 (* _fstat_r)(struct _reent *r, int, struct stat *); + 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); + int (* _close_r)(struct _reent *r, int); + int (* _open_r)(struct _reent *r, const char *, int, int); + 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); + int (*_scanf_float)(struct _reent *rptr, void *pdata, FILE *fp, + va_list *ap); +}; + +extern struct syscall_stub_table *syscall_table_ptr_pro; +extern struct syscall_stub_table *syscall_table_ptr_app; + +/**************************************************************************** + * Name: esp_setup_syscall_table + * + * Description: + * Configure the syscall table used by the ROM code for calling C library + * functions. + * ROM code from Espressif's chips 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 syscall_stub_table struct. + * + * Input Parameters: + * None. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_setup_syscall_table(void); + +#endif /* __ARCH_XTENSA_SRC_ESP32_ROM_ESP32_LIBC_STUBS_H */ diff --git a/boards/xtensa/esp32/common/scripts/esp32_rom.ld b/boards/xtensa/esp32/common/scripts/esp32_rom.ld index ff0bd51e11e..efc1275f6ee 100644 --- a/boards/xtensa/esp32/common/scripts/esp32_rom.ld +++ b/boards/xtensa/esp32/common/scripts/esp32_rom.ld @@ -234,6 +234,7 @@ PROVIDE ( ecc_Jacobian_InfinityPoint256 = 0x3ff972e8 ); PROVIDE ( em_buf_env = 0x3ffb8d74 ); PROVIDE ( environ = 0x3ffae0b4 ); PROVIDE ( __env_lock = 0x40001fd4 ); +PROVIDE ( __env_lock_object = 0x3ffae0b8 ); PROVIDE ( __env_unlock = 0x40001fe0 ); PROVIDE ( esp_crc8 = 0x4005d144 ); PROVIDE ( _etext = 0x4000d66c ); @@ -1708,6 +1709,7 @@ PROVIDE ( __sf_fake_stdout = 0x3ff96478 ); PROVIDE ( __sflush_r = 0x400591e0 ); PROVIDE ( __sfmoreglue = 0x40001dc8 ); PROVIDE ( __sfp = 0x40001e90 ); +PROVIDE ( __sfp_lock = 0x3ffae0ac ); PROVIDE ( __sfp_lock_acquire = 0x40001e08 ); PROVIDE ( __sfp_lock_release = 0x40001e14 ); PROVIDE ( __sfputs_r = 0x40057790 ); @@ -1721,6 +1723,7 @@ PROVIDE ( sha_blk_bits_bytes = 0x3ff99288 ); PROVIDE ( sha_blk_hash_bytes = 0x3ff9928c ); PROVIDE ( sig_matrix = 0x3ffae293 ); PROVIDE ( __sinit = 0x40001e38 ); +PROVIDE ( __sinit_lock = 0x3ffae0a8 ); PROVIDE ( __sinit_lock_acquire = 0x40001e20 ); PROVIDE ( __sinit_lock_release = 0x40001e2c ); PROVIDE ( sip_after_tx_complete = 0x4000b358 ); @@ -1892,6 +1895,7 @@ PROVIDE ( __tz_lock = 0x40001a04 ); PROVIDE ( _tzname = 0x3ffae030 ); PROVIDE ( tzset = 0x40001a1c ); PROVIDE ( _tzset_r = 0x40001a28 ); +PROVIDE ( __tz_lock_object = 0x3ffae080 ); PROVIDE ( __tz_unlock = 0x40001a10 ); PROVIDE ( uartAttach = 0x40008fd0 ); PROVIDE ( uart_baudrate_detect = 0x40009034 );