/**************************************************************************** * 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 #include "rom/esp32_libc_stubs.h" /**************************************************************************** * Private Types ****************************************************************************/ static mutex_t g_nxlock_common = NXMUTEX_INITIALIZER; static mutex_t g_nxlock_recursive = NXMUTEX_INITIALIZER; /* Forward declaration */ struct _reent; /**************************************************************************** * Public Functions ****************************************************************************/ int _close_r(struct _reent *r, int fd) { return nx_close(fd); } int _fstat_r(struct _reent *r, int fd, struct stat *statbuf) { return nx_fstat(fd, statbuf); } int _getpid_r(struct _reent *r) { return nxsched_getpid(); } int _kill_r(struct _reent *r, int pid, int sig) { return nxsig_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 nx_seek(fd, offset, whence); } int _open_r(struct _reent *r, const char *pathname, int flags, int mode) { return nx_open(pathname, flags, mode); } int read_r(struct _reent *r, int fd, void *buf, int count) { return nx_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 nx_stat(pathname, statbuf, 1); } clock_t _times_r(struct _reent *r, struct tms *buf) { return times(buf); } int _unlink_r(struct _reent *r, const char *pathname) { return nx_unlink(pathname); } int write_r(struct _reent *r, int fd, const void *buf, int count) { return nx_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 lib_malloc(size); } void *_realloc_r(struct _reent *r, void *ptr, size_t size) { return lib_realloc(ptr, size); } void *_calloc_r(struct _reent *r, size_t nmemb, size_t size) { return lib_calloc(nmemb, size); } void _free_r(struct _reent *r, void *ptr) { lib_free(ptr); } void _abort(void) { abort(); } void _raise_r(struct _reent *r) { /* FIXME */ } void _lock_init(_lock_t *lock) { *lock = 0; mutex_t *mutex = (mutex_t *)kmm_malloc(sizeof(mutex_t)); nxmutex_init(mutex); *lock = (_lock_t)mutex; } void _lock_init_recursive(_lock_t *lock) { *lock = 0; rmutex_t *rmutex = (rmutex_t *)kmm_malloc(sizeof(rmutex_t)); nxrmutex_init(rmutex); *lock = (_lock_t)rmutex; } void _lock_close(_lock_t *lock) { mutex_t *mutex = (mutex_t *)(*lock); nxmutex_destroy(mutex); kmm_free((void *)(*lock)); *lock = 0; } void _lock_close_recursive(_lock_t *lock) { rmutex_t *rmutex = (rmutex_t *)(*lock); nxrmutex_destroy(rmutex); kmm_free((void *)(*lock)); *lock = 0; } void _lock_acquire(_lock_t *lock) { if ((*lock) == 0) { mutex_t *mutex = (mutex_t *)kmm_malloc(sizeof(mutex_t)); nxmutex_init(mutex); *lock = (_lock_t)mutex; } nxmutex_lock((mutex_t *)(*lock)); } void _lock_acquire_recursive(_lock_t *lock) { if ((*lock) == 0) { rmutex_t *rmutex = (rmutex_t *)kmm_malloc(sizeof(rmutex_t)); nxrmutex_init(rmutex); *lock = (_lock_t)rmutex; } nxrmutex_lock((rmutex_t *)(*lock)); } int _lock_try_acquire(_lock_t *lock) { if ((*lock) == 0) { mutex_t *mutex = (mutex_t *)kmm_malloc(sizeof(mutex_t)); nxmutex_init(mutex); *lock = (_lock_t)mutex; } return nxmutex_trylock((mutex_t *)(*lock)); } int _lock_try_acquire_recursive(_lock_t *lock) { if ((*lock) == 0) { rmutex_t *rmutex = (rmutex_t *)kmm_malloc(sizeof(rmutex_t)); nxrmutex_init(rmutex); *lock = (_lock_t)rmutex; } return nxrmutex_trylock((rmutex_t *)(*lock)); } void _lock_release(_lock_t *lock) { mutex_t *mutex = (mutex_t *)(*lock); nxmutex_unlock(mutex); } void _lock_release_recursive(_lock_t *lock) { rmutex_t *rmutex = (rmutex_t *)(*lock); nxrmutex_unlock(rmutex); } 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; }