Cygwin: dirent.h: fix a comment
[newlib-cygwin.git] / libgloss / xtensa / syscalls.c
blob11e972c3fd49eb17db5a7a68deb0949153bd278c
1 /*
2 * Copyright (C) 2023 Espressif Systems (Shanghai) CO LTD
3 * SPDX-License-Identifier: BSD-2-Clause
4 */
6 #include <unistd.h>
7 #include <syscalls.h>
8 #include <sys/stat.h>
9 #include <soc/uart.h>
11 #if defined (OPENOCD_SEMIHOSTING) || (QEMU_SEMIHOSTING)
12 # define WITH_SEMIHOSTING
13 # define __WEAK_FUNCTION_ATTR__
14 #else
15 # define __WEAK_FUNCTION_ATTR__ __attribute__((__weak__))
16 #endif
19 /* __semihosting_call is a function in case semihosting usage, macro (-1) otherwise */
20 #ifdef WITH_SEMIHOSTING
22 static inline int
23 __attribute__ ((always_inline))
24 __semihosting_call(int id, int arg1, int arg2, int arg3, int arg4)
26 # ifdef OPENOCD_SEMIHOSTING
27 register long a2 asm("a2") = id;
28 long args[] = {arg1, arg2, arg3, arg4};
29 register long a3 asm("a3") = (long)&args;
31 /* OpenOCD has different semihosting api for sys_exit on 32-bit and 64-bit */
32 if (id == SYS_exit && sizeof(void *) != 8) {
33 a3 = ADP_STOPPED_APPLICATION_EXIT;
35 __asm__ __volatile__ (
36 "break 1, 14\n"
37 : "+r"(a2): "r"(a3)
38 : "memory");
40 // return code is placed in a2 register, so return it to the caller
41 return a2;
42 # else // OPENOCD_SEMIHOSTING
43 extern int __sim_call(int id, int arg1, int arg2, int arg3, int arg4);
44 return __sim_call(id, arg1, arg2, arg3, arg4);
45 # endif // OPENOCD_SEMIHOSTING
48 # ifdef OPENOCD_SEMIHOSTING
50 int
51 __semihosting_init (void)
53 struct {
54 int version;
55 } ver_info = { 2 };
56 __semihosting_call(ESP_SEMIHOSTING_SYS_DRV_INFO, (long) &ver_info, sizeof(ver_info), 0, 0);
59 # endif // OPENOCD_SEMIHOSTING
61 #else // !WITH_SEMIHOSTING
62 # define __semihosting_call(...) (-1)
63 #endif // WITH_SEMIHOSTING
66 void
67 __WEAK_FUNCTION_ATTR__
68 __attribute__ ((noreturn))
69 _exit (int status)
71 __semihosting_call(SYS_exit, status, 0, 0, 0);
73 for (;;) {
79 int
80 __WEAK_FUNCTION_ATTR__
81 _open (const char *file, int flags, int mode)
83 return __semihosting_call(SYS_open, (int) file, flags, mode, 0);
87 int
88 __WEAK_FUNCTION_ATTR__
89 _lseek (int fd, _off_t off, int whence)
91 return __semihosting_call(SYS_lseek, fd, off, whence, 0);
95 int
96 __WEAK_FUNCTION_ATTR__
97 _close (int fd)
99 return __semihosting_call(SYS_close, fd, 0, 0, 0);
103 _ssize_t
104 __WEAK_FUNCTION_ATTR__
105 _write (int fd, const char *buf, size_t cnt)
107 int ret = 0;
108 #ifdef WITH_SEMIHOSTING
109 ret = __semihosting_call(SYS_write, fd, (int) buf, cnt, 0);
110 # ifdef OPENOCD_SEMIHOSTING
111 /* ret - number of bytes that are NOT written. Calculate written */
112 ret = cnt - ret;
113 # endif // OPENOCD_SEMIHOSTING
114 #else // !WITH_SEMIHOSTING
115 if (fd != STDOUT_FILENO && fd != STDERR_FILENO) {
116 return -1;
119 for (uint32_t i = 0; i < cnt; i++) {
120 board_uart_write_char(buf[i]);
122 ret = cnt;
123 #endif // WITH_SEMIHOSTING
124 return ret;
128 /* Do not compile functions with common implementation
129 * if building semihosting library
131 #ifndef WITH_SEMIHOSTING
133 struct _reent*
134 __WEAK_FUNCTION_ATTR__
135 __getreent(void)
137 return _GLOBAL_REENT;
142 __WEAK_FUNCTION_ATTR__
143 _fstat (int fd, struct stat *pstat)
146 if (fd < STDERR_FILENO)
148 pstat->st_mode = S_IFCHR;
149 return 0;
151 return -1;
155 _ssize_t
156 __WEAK_FUNCTION_ATTR__
157 _read (int fd, char *buf, size_t cnt)
159 return -1;
164 __WEAK_FUNCTION_ATTR__
165 _getpid (void)
167 return -1;
172 __WEAK_FUNCTION_ATTR__
173 _kill (int sig)
175 return -1;
179 void *
180 __WEAK_FUNCTION_ATTR__
181 _sbrk (int incr)
183 extern char end; /* Set by linker. */
184 static char * heap_end;
185 char * prev_heap_end;
187 if (heap_end == 0) {
188 heap_end = & end;
191 prev_heap_end = heap_end;
192 heap_end += incr;
194 return (void *) prev_heap_end;
199 __WEAK_FUNCTION_ATTR__
200 pthread_setcancelstate (int state, int *oldstate)
202 return 0;
205 #endif // WITH_SEMIHOSTING