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

Subversion Repositories neorv32

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

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

powered by: WebSVN 2.1.0

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