+// See LICENSE for license details.
+
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <limits.h>
-#include <machine/syscall.h>
#include "util.h"
+#define SYS_write 64
+#define SYS_exit 93
#define SYS_stats 1234
// initialized in crt.S
magic_mem[2] = arg1;
magic_mem[3] = arg2;
__sync_synchronize();
- write_csr(tohost, (long)magic_mem);
- while (swap_csr(fromhost, 0) == 0);
+ write_csr(mtohost, (long)magic_mem);
+ while (swap_csr(mfromhost, 0) == 0);
return magic_mem[0];
}
return 0;
}
-static void tohost_exit(int code)
+void tohost_exit(long code)
{
- write_csr(tohost, (code << 1) | 1);
+ write_csr(mtohost, (code << 1) | 1);
while (1);
}
if (cause == CAUSE_ILLEGAL_INSTRUCTION &&
(*(int*)epc & *csr_insn) == *csr_insn)
;
- else if (cause != CAUSE_SYSCALL)
+ else if (cause != CAUSE_USER_ECALL)
tohost_exit(1337);
else if (regs[17] == SYS_exit)
tohost_exit(regs[10]);
return -1;
}
+static void init_tls()
+{
+ register void* thread_pointer asm("tp");
+ extern char _tls_data;
+ extern __thread char _tdata_begin, _tdata_end, _tbss_end;
+ size_t tdata_size = &_tdata_end - &_tdata_begin;
+ memcpy(thread_pointer, &_tls_data, tdata_size);
+ size_t tbss_size = &_tbss_end - &_tdata_end;
+ memset(thread_pointer + tdata_size, 0, tbss_size);
+}
+
void _init(int cid, int nc)
{
+ init_tls();
thread_entry(cid, nc);
// only single-threaded programs should ever get here.