OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [lib/] [source/] [syscalls.c] - Blame information for rev 74

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 72 zero_gravi
/* An extremely minimalist syscalls.c for newlib
2
 * Based on riscv newlib libgloss/riscv/sys_*.c
3
 *
4
 * Copyright 2019 Clifford Wolf
5
 * Copyright 2019 ETH Zürich and University of Bologna
6
 *
7
 * Permission to use, copy, modify, and/or distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
 * PERFORMANCE OF THIS SOFTWARE.
18
 */
19
 
20
/**********************************************************************//**
21
 * @file syscalls.c
22
 * @brief Newlib system calls
23
 *
24
 * @warning UART0 (if available) is used to read/write console data (STDIN, STDOUT, STDERR, ...).
25
 *
26
 * @note Original source file: https://github.com/openhwgroup/cv32e40p/blob/master/example_tb/core/custom/syscalls.c
27
 * @note Original license: SOLDERPAD HARDWARE LICENSE version 0.51
28
 * @note More information was derived from: https://interrupt.memfault.com/blog/boostrapping-libc-with-newlib#implementing-newlib
29
 **************************************************************************/
30
 
31
#include <sys/stat.h>
32
#include <sys/timeb.h>
33
#include <sys/times.h>
34
#include <utime.h>
35
#include <newlib.h>
36
#include <unistd.h>
37
#include <errno.h>
38
#include <neorv32.h>
39
 
40
#undef errno
41
extern int errno;
42
 
43
// defined in sw/common/crt0.S
44
extern const volatile unsigned int __crt0_main_exit;
45
 
46
/* It turns out that older newlib versions use different symbol names which goes
47
 * against newlib recommendations. Anyway this is fixed in later version.
48
 */
49
#if __NEWLIB__ <= 2 && __NEWLIB_MINOR__ <= 5
50
#    define _sbrk sbrk
51
#    define _write write
52
#    define _close close
53
#    define _lseek lseek
54
#    define _read read
55
#    define _fstat fstat
56
#    define _isatty isatty
57
#endif
58
 
59
void unimplemented_syscall()
60
{
61
  if (neorv32_uart0_available()) {
62
    neorv32_uart0_print("<syscalls.c> Unimplemented system call called!\n");
63
  }
64
}
65
 
66
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
67
{
68
    errno = ENOSYS;
69
    return -1;
70
}
71
 
72
int _access(const char *file, int mode)
73
{
74
    errno = ENOSYS;
75
    return -1;
76
}
77
 
78
int _chdir(const char *path)
79
{
80
    errno = ENOSYS;
81
    return -1;
82
}
83
 
84
int _chmod(const char *path, mode_t mode)
85
{
86
    errno = ENOSYS;
87
    return -1;
88
}
89
 
90
int _chown(const char *path, uid_t owner, gid_t group)
91
{
92
    errno = ENOSYS;
93
    return -1;
94
}
95
 
96
int _close(int file)
97
{
98
    return -1;
99
}
100
 
101
int _execve(const char *name, char *const argv[], char *const env[])
102
{
103
    errno = ENOMEM;
104
    return -1;
105
}
106
 
107
void _exit(int exit_status)
108
{
109
    // jump to crt0's shutdown code
110
    asm volatile ("la t0, __crt0_main_exit \n"
111
                  "jr t0                   \n");
112
 
113
    while(1); // will never be reached
114
}
115
 
116
int _faccessat(int dirfd, const char *file, int mode, int flags)
117
{
118
    errno = ENOSYS;
119
    return -1;
120
}
121
 
122
int _fork(void)
123
{
124
    errno = EAGAIN;
125
    return -1;
126
}
127
 
128
int _fstat(int file, struct stat *st)
129
{
130
    st->st_mode = S_IFCHR; // all files are "character special files"
131
    return 0;
132
}
133
 
134
int _fstatat(int dirfd, const char *file, struct stat *st, int flags)
135
{
136
    errno = ENOSYS;
137
    return -1;
138
}
139
 
140
int _ftime(struct timeb *tp)
141
{
142
    errno = ENOSYS;
143
    return -1;
144
}
145
 
146
char *_getcwd(char *buf, size_t size)
147
{
148
    errno = -ENOSYS;
149
    return NULL;
150
}
151
 
152
int _getpid()
153
{
154
    return 1;
155
}
156
 
157
int _gettimeofday(struct timeval *tp, void *tzp)
158
{
159
    errno = -ENOSYS;
160
    return -1;
161
}
162
 
163
int _isatty(int file)
164
{
165
    return (file == STDOUT_FILENO);
166
}
167
 
168
int _kill(int pid, int sig)
169
{
170
    errno = EINVAL;
171
    return -1;
172
}
173
 
174
int _link(const char *old_name, const char *new_name)
175
{
176
    errno = EMLINK;
177
    return -1;
178
}
179
 
180
off_t _lseek(int file, off_t ptr, int dir)
181
{
182
    return 0;
183
}
184
 
185
int _lstat(const char *file, struct stat *st)
186
{
187
    errno = ENOSYS;
188
    return -1;
189
}
190
 
191
int _open(const char *name, int flags, int mode)
192
{
193
    return -1;
194
}
195
 
196
int _openat(int dirfd, const char *name, int flags, int mode)
197
{
198
    errno = ENOSYS;
199
    return -1;
200
}
201
 
202
ssize_t _read(int file, void *ptr, size_t len)
203
{
204
    int read_cnt = 0;
205
 
206
    // read everything (STDIN, ...) from NEORV32.UART0 (if available)
207
    if (neorv32_uart0_available()) {
208
      char *char_ptr;
209
      char_ptr = (char *)ptr;
210
      while (len > 0) {
211
        *char_ptr++ = (char)neorv32_uart0_getc();
212
        read_cnt++;
213
        len--;
214
      }
215
    }
216
 
217
    return read_cnt;
218
}
219
 
220
int _stat(const char *file, struct stat *st)
221
{
222
    st->st_mode = S_IFCHR;
223
    return 0;
224
    // errno = ENOSYS;
225
    // return -1;
226
}
227
 
228
long _sysconf(int name)
229
{
230
 
231
    return -1;
232
}
233
 
234
clock_t _times(struct tms *buf)
235
{
236
    return -1;
237
}
238
 
239
int _unlink(const char *name)
240
{
241
    errno = ENOENT;
242
    return -1;
243
}
244
 
245
int _utime(const char *path, const struct utimbuf *times)
246
{
247
    errno = ENOSYS;
248
    return -1;
249
}
250
 
251
int _wait(int *status)
252
{
253
    errno = ECHILD;
254
    return -1;
255
}
256
 
257
ssize_t _write(int file, const void *ptr, size_t len)
258
{
259
    // write everything (STDOUT, STDERR, ...) to NEORV32.UART0 (if available)
260
    const void *eptr = ptr + len;
261
    if (neorv32_uart0_available()) {
262
      while (ptr != eptr) {
263
        neorv32_uart0_putc(*(char *)(ptr++));
264
      }
265
      return len;
266
    }
267
    else {
268
      return (size_t)0; // nothing sent
269
    }
270
}
271
 
272
extern char __heap_start[];
273
extern char __heap_end[];
274
static char *brk = __heap_start;
275
 
276
int _brk(void *addr)
277
{
278
    brk = addr;
279
    return 0;
280
}
281
 
282
void *_sbrk(ptrdiff_t incr)
283
{
284
    char *old_brk = brk;
285
 
286
    if (__heap_start == __heap_end) {
287
        return NULL;
288
    }
289
 
290
    if ((brk += incr) < __heap_end) {
291
        brk += incr;
292
    } else {
293
        brk = __heap_end;
294
    }
295
    return old_brk;
296
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.