This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 173212ebc9 esp32s3: Define syscall table to enable using ROM functions
173212ebc9 is described below

commit 173212ebc94e80cf0a0d805851d4e8038a78e4da
Author: Tiago Medicci Serrano <tiago.medi...@espressif.com>
AuthorDate: Fri Feb 17 16:57:24 2023 -0300

    esp32s3: Define syscall table to enable using ROM functions
---
 arch/xtensa/src/esp32s3/Make.defs                |   2 +-
 arch/xtensa/src/esp32s3/esp32s3_libc_stubs.c     | 394 +++++++++++++++++++++++
 arch/xtensa/src/esp32s3/esp32s3_start.c          |   5 +
 arch/xtensa/src/esp32s3/rom/esp32s3_libc_stubs.h | 139 ++++++++
 4 files changed, 539 insertions(+), 1 deletion(-)

diff --git a/arch/xtensa/src/esp32s3/Make.defs 
b/arch/xtensa/src/esp32s3/Make.defs
index 32b8a48a7b..e0f8c11626 100644
--- a/arch/xtensa/src/esp32s3/Make.defs
+++ b/arch/xtensa/src/esp32s3/Make.defs
@@ -30,7 +30,7 @@ HEAD_CSRC  = esp32s3_start.c
 CHIP_CSRCS  = esp32s3_irq.c esp32s3_clockconfig.c esp32s3_region.c
 CHIP_CSRCS += esp32s3_systemreset.c esp32s3_user.c esp32s3_allocateheap.c
 CHIP_CSRCS += esp32s3_wdt.c esp32s3_gpio.c esp32s3_lowputc.c esp32s3_serial.c
-CHIP_CSRCS += esp32s3_rtc_gpio.c
+CHIP_CSRCS += esp32s3_rtc_gpio.c esp32s3_libc_stubs.c
 
 # Configuration-dependent ESP32-S3 files
 
diff --git a/arch/xtensa/src/esp32s3/esp32s3_libc_stubs.c 
b/arch/xtensa/src/esp32s3/esp32s3_libc_stubs.c
new file mode 100644
index 0000000000..c6c722f8a6
--- /dev/null
+++ b/arch/xtensa/src/esp32s3/esp32s3_libc_stubs.c
@@ -0,0 +1,394 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s3/esp32s3_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 <assert.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <nuttx/mutex.h>
+#include "rom/esp32s3_libc_stubs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define _lock_t int
+
+#define ROM_MUTEX_MAGIC   0xbb10c433
+
+/****************************************************************************
+ * 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);
+}
+
+void __retarget_lock_init(_lock_t *lock)
+{
+  _lock_init(lock);
+}
+
+void __retarget_lock_init_recursive(_lock_t *lock)
+{
+  _lock_init_recursive(lock);
+}
+
+void __retarget_lock_close(_lock_t lock)
+{
+  _lock_close(&lock);
+}
+
+void __retarget_lock_close_recursive(_lock_t lock)
+{
+  _lock_close_recursive(&lock);
+}
+
+void __retarget_lock_acquire(_lock_t lock)
+{
+  _lock_acquire(&lock);
+}
+
+void __retarget_lock_acquire_recursive(_lock_t lock)
+{
+  _lock_acquire_recursive(&lock);
+}
+
+int __retarget_lock_try_acquire(_lock_t lock)
+{
+  return _lock_try_acquire(&lock);
+}
+
+int __retarget_lock_try_acquire_recursive(_lock_t lock)
+{
+  return _lock_try_acquire_recursive(&lock);
+}
+
+void __retarget_lock_release(_lock_t lock)
+{
+  _lock_release(&lock);
+}
+
+void __retarget_lock_release_recursive(_lock_t lock)
+{
+  _lock_release_recursive(&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,
+  ._retarget_lock_init = &__retarget_lock_init,
+  ._retarget_lock_init_recursive = &__retarget_lock_init_recursive,
+  ._retarget_lock_close = &__retarget_lock_close,
+  ._retarget_lock_close_recursive = &__retarget_lock_close_recursive,
+  ._retarget_lock_acquire = &__retarget_lock_acquire,
+  ._retarget_lock_acquire_recursive = &__retarget_lock_acquire_recursive,
+  ._retarget_lock_try_acquire = &__retarget_lock_try_acquire,
+  ._retarget_lock_try_acquire_recursive =
+    &__retarget_lock_try_acquire_recursive,
+  ._retarget_lock_release = &__retarget_lock_release,
+  ._retarget_lock_release_recursive = &__retarget_lock_release_recursive,
+  ._printf_float = NULL,
+  ._scanf_float = NULL,
+  .__assert_func = &__assert_func,
+  .__sinit = (void *)abort,
+  ._cleanup_r = &_cleanup_r
+};
+
+/****************************************************************************
+ * 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 = (struct syscall_stub_table *)&g_stub_table;
+
+  /* Newlib 3.3.0 is used in ROM, built with _RETARGETABLE_LOCKING.
+   * No access to lock variables for the purpose of ECO forward
+   * compatibility, however we have an API to initialize lock variables used
+   * in the ROM.
+   */
+
+  extern void esp_rom_newlib_init_common_mutexes(_lock_t, _lock_t);
+
+  int magic_val = ROM_MUTEX_MAGIC;
+  _lock_t magic_mutex = (_lock_t) &magic_val;
+  esp_rom_newlib_init_common_mutexes(magic_mutex, magic_mutex);
+}
diff --git a/arch/xtensa/src/esp32s3/esp32s3_start.c 
b/arch/xtensa/src/esp32s3/esp32s3_start.c
index 22fbdb1a99..49cac473d5 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_start.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_start.c
@@ -45,6 +45,7 @@
 #include "hardware/esp32s3_cache_memory.h"
 #include "hardware/esp32s3_system.h"
 #include "hardware/esp32s3_extmem.h"
+#include "rom/esp32s3_libc_stubs.h"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -351,6 +352,10 @@ void noreturn_function IRAM_ATTR __esp32s3_start(void)
     }
 #endif
 
+  /* Setup the syscall table needed by the ROM code */
+
+  esp_setup_syscall_table();
+
   /* Initialize onboard resources */
 
   esp32s3_board_initialize();
diff --git a/arch/xtensa/src/esp32s3/rom/esp32s3_libc_stubs.h 
b/arch/xtensa/src/esp32s3/rom/esp32s3_libc_stubs.h
new file mode 100644
index 0000000000..6740807433
--- /dev/null
+++ b/arch/xtensa/src/esp32s3/rom/esp32s3_libc_stubs.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s3/rom/esp32s3_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_ESP32S3_ROM_ESP32S3_LIBC_STUBS_H
+#define __ARCH_XTENSA_SRC_ESP32S3_ROM_ESP32S3_LIBC_STUBS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdio.h>
+
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include <nuttx/mutex.h>
+
+#define _lock_t int
+
+/* Forward declaration */
+
+struct _reent;
+
+/**
+ * @brief ESP32-S3 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 (* _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 const struct syscall_stub_table *syscall_table_ptr;
+#define syscall_table_ptr_pro syscall_table_ptr
+#define syscall_table_ptr_app syscall_table_ptr
+
+/****************************************************************************
+ * 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_ESP32S3_ROM_ESP32S3_LIBC_STUBS_H */

Reply via email to