aboutsummaryrefslogtreecommitdiffstats
path: root/dhrystone/syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'dhrystone/syscalls.c')
-rw-r--r--dhrystone/syscalls.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/dhrystone/syscalls.c b/dhrystone/syscalls.c
new file mode 100644
index 0000000..cdf872f
--- /dev/null
+++ b/dhrystone/syscalls.c
@@ -0,0 +1,95 @@
+// An extremely minimalist syscalls.c for newlib
+// Based on riscv newlib libgloss/riscv/machine/syscall.h
+// Written by Clifford Wolf.
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define UNIMPL_FUNC(_f) ".globl " #_f "\n.type " #_f ", @function\n" #_f ":\n"
+
+asm (
+ ".text\n"
+ ".align 2\n"
+ UNIMPL_FUNC(open)
+ UNIMPL_FUNC(openat)
+ UNIMPL_FUNC(lseek)
+ UNIMPL_FUNC(stat)
+ UNIMPL_FUNC(lstat)
+ UNIMPL_FUNC(fstatat)
+ UNIMPL_FUNC(isatty)
+ UNIMPL_FUNC(access)
+ UNIMPL_FUNC(faccessat)
+ UNIMPL_FUNC(link)
+ UNIMPL_FUNC(unlink)
+ UNIMPL_FUNC(execve)
+ UNIMPL_FUNC(getpid)
+ UNIMPL_FUNC(fork)
+ UNIMPL_FUNC(kill)
+ UNIMPL_FUNC(wait)
+ UNIMPL_FUNC(times)
+ UNIMPL_FUNC(gettimeofday)
+ UNIMPL_FUNC(ftime)
+ UNIMPL_FUNC(utime)
+ UNIMPL_FUNC(chown)
+ UNIMPL_FUNC(chmod)
+ UNIMPL_FUNC(chdir)
+ UNIMPL_FUNC(getcwd)
+ UNIMPL_FUNC(sysconf)
+ "j unimplemented_syscall\n"
+);
+
+void unimplemented_syscall()
+{
+ const char *p = "Unimplemented system call called!\n";
+ while (*p)
+ *(volatile int*)0x10000000 = *(p++);
+ asm volatile ("ebreak");
+ __builtin_unreachable();
+}
+
+ssize_t read(int file, void *ptr, size_t len)
+{
+ // always EOF
+ return 0;
+}
+
+ssize_t write(int file, const void *ptr, size_t len)
+{
+ const void *eptr = ptr + len;
+ while (ptr != eptr)
+ *(volatile int*)0x10000000 = *(char*)(ptr++);
+ return len;
+}
+
+int close(int file)
+{
+ // close is called before _exit()
+ return 0;
+}
+
+int fstat(int file, struct stat *st)
+{
+ // fstat is called during libc startup
+ errno = ENOENT;
+ return -1;
+}
+
+void *sbrk(ptrdiff_t incr)
+{
+ extern unsigned char _end[]; // Defined by linker
+ static unsigned long heap_end;
+
+ if (heap_end == 0)
+ heap_end = (long)_end;
+
+ heap_end += incr;
+ return (void *)(heap_end - incr);
+}
+
+void _exit(int exit_status)
+{
+ asm volatile ("ebreak");
+ __builtin_unreachable();
+}
+