aboutsummaryrefslogtreecommitdiffstats
path: root/dhrystone/syscalls.c
blob: b23f605fa2be925ea33544ad0d6931c64f376209 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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();
}