summaryrefslogtreecommitdiff
path: root/software/shared/syscall.c
blob: 2e4199f58e0ec6072acc89b2bdacd1df1df63b01 (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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// See LICENSE for license details.

/* This is an incomplete version of a syscall library, 
 * which really only supports simple reads and writes over UART.
 */

#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <stdio.h>
#include <string.h>

#include "encoding.h"

#include "shared.h"

volatile uint64_t tohost __attribute__((aligned(64)));
volatile uint64_t fromhost __attribute__((aligned(64)));

void write_hex(int fd, uint32_t hex){
  uint8_t ii;
  uint8_t jj;
  char towrite;
  write( fd , "0x", 2 );
  for (ii = 8 ; ii > 0; ii--){
    jj = ii-1;
    uint8_t digit = ((hex & (0xF << (jj*4))) >> (jj*4));
    towrite = digit < 0xA ? ('0' + digit) : ('A' +  (digit - 0xA));
    write( fd, &towrite, 1);
  }

}

               
void _exit(int code)
{
  volatile uint32_t* leds = (uint32_t*) (GPIO_BASE_ADDR + GPIO_OUT_OFFSET);
  const char * message = "\nProgam has exited with code:";
  
  *leds = (~(code));

  write(STDERR_FILENO, message, strlen(message));
  write_hex(STDERR_FILENO, code);

  while (1);
    
}

void *sbrk(ptrdiff_t incr)
{
  //  extern char _end[];
  //  extern char _heap_end[];
  //  static char *curbrk = _end;

  //  if ((curbrk + incr < _end) || (curbrk + incr > _heap_end))
    return NULL - 1;

    //  curbrk += incr;
    //return curbrk - incr;
}

static int stub(int err)
{
  errno = err;
  return -1;
}

int open(const char* name, int flags, int mode)
{
  return stub(ENOENT);
}

int openat(int dirfd, const char* name, int flags, int mode)
{
  return stub(ENOENT);
}

int close(int fd)
{
  return stub(EBADF);
}

int execve(const char* name, char* const argv[], char* const env[])
{
  return stub(ENOMEM);
}

int fork()
{
  return stub(EAGAIN);
}

int fstat(int fd, struct stat *st)
{
  if (isatty(fd)) {
    st->st_mode = S_IFCHR;
    return 0;
  }

  return stub(EBADF);
}

int getpid()
{
  return 1;
}

int isatty(int fd)
{
  if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
    return 1;

  errno = EBADF;
  return 0;
}

int kill(int pid, int sig)
{
  return stub(EINVAL);
}

int link(const char *old_name, const char *new_name)
{
  return stub(EMLINK);
}

off_t lseek(int fd, off_t ptr, int dir)
{
  if (isatty(fd))
    return 0;

  return stub(EBADF);
}

ssize_t read(int fd, void* ptr, size_t len)
{
  int i;
  uint8_t * current = (uint8_t*) ptr;
  volatile uint8_t  * uart_rx = (uint8_t*) (UART_BASE_ADDR + UART_RX_OFFSET);
  volatile uint32_t * uart_rx_cnt = (uint32_t*) (UART_BASE_ADDR + UART_RX_COUNT_OFFSET);

  ssize_t result = 0;
  
  if (isatty(fd)) {
    
    for (current = (uint8_t*) ptr;
	 (current < ((uint8_t*) ptr) + len) && (*uart_rx_cnt > 0);
	 current ++){
      *current = *uart_rx;
      result ++;
    }
    return result;

  }
 
  return stub(EBADF);
}

int stat(const char* file, struct stat* st)
{
  return stub(EACCES);
}

clock_t times(struct tms* buf)
{
  return stub(EACCES);
}

int unlink(const char* name)
{
  return stub(ENOENT);
}

int wait(int* status)
{
  return stub(ECHILD);
}

ssize_t write(int fd, const void* ptr, size_t len)
{

  const uint8_t * current = (const char*) ptr;
  volatile uint32_t * uart_tx_count = (uint32_t*) (UART_BASE_ADDR + UART_TX_COUNT_OFFSET);
  volatile uint8_t *  uart_tx = (uint8_t*) (UART_BASE_ADDR + UART_TX_OFFSET);

  size_t jj;
  if (isatty(fd)) {
    
    for (jj = 0; jj < len; jj++){

      while ((*uart_tx_count) < 1);
      *uart_tx = current[jj];

      if (current[jj] == '\n'){
	while ((*uart_tx_count) < 1);
	*uart_tx = '\r';
      }
    }
    return len;
  } 
  return stub(EBADF);
}