X-Git-Url: https://git.libre-soc.org/?p=riscv-tests.git;a=blobdiff_plain;f=benchmarks%2Fcommon%2Fsyscalls.c;h=0a7d6b728f633304d9b3aa9e01ecb2b8ddf6f57c;hp=a168ebf6ae5c86c91eb0e7028089af6bb3008c7a;hb=HEAD;hpb=629d7edf826573a9bf297486999e23a7b745c44d diff --git a/benchmarks/common/syscalls.c b/benchmarks/common/syscalls.c index a168ebf..0a7d6b7 100644 --- a/benchmarks/common/syscalls.c +++ b/benchmarks/common/syscalls.c @@ -1,14 +1,21 @@ +// See LICENSE for license details. + #include #include #include #include #include -#include +#include #include "util.h" -#define SYS_stats 1234 +#define SYS_write 64 + +#undef strcmp -static long handle_frontend_syscall(long which, long arg0, long arg1, long arg2) +extern volatile uint64_t tohost; +extern volatile uint64_t fromhost; + +static uintptr_t syscall(uintptr_t which, uint64_t arg0, uint64_t arg1, uint64_t arg2) { volatile uint64_t magic_mem[8] __attribute__((aligned(64))); magic_mem[0] = which; @@ -16,103 +23,60 @@ static long handle_frontend_syscall(long which, long arg0, long arg1, long arg2) magic_mem[2] = arg1; magic_mem[3] = arg2; __sync_synchronize(); - write_csr(tohost, (long)magic_mem); - while (swap_csr(fromhost, 0) == 0); + + tohost = (uintptr_t)magic_mem; + while (fromhost == 0) + ; + fromhost = 0; + + __sync_synchronize(); return magic_mem[0]; } -// In setStats, we might trap reading uarch-specific counters. -// The trap handler will skip over the instruction and write 0, -// but only if v0 is the destination register. -#define read_csr_safe(reg) ({ register long __tmp asm("v0"); \ - asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ - __tmp; }) - -#define NUM_COUNTERS 18 -static long counters[NUM_COUNTERS]; +#define NUM_COUNTERS 2 +static uintptr_t counters[NUM_COUNTERS]; static char* counter_names[NUM_COUNTERS]; -static int handle_stats(int enable) + +void setStats(int enable) { - //use csrs to set stats register - if(enable) { - asm volatile (R"( - addi v0, x0, 1 - csrrs v0, stats, v0 - )" : : : "v0"); - } int i = 0; #define READ_CTR(name) do { \ while (i >= NUM_COUNTERS) ; \ - long csr = read_csr_safe(name); \ + uintptr_t csr = read_csr(name); \ if (!enable) { csr -= counters[i]; counter_names[i] = #name; } \ counters[i++] = csr; \ } while (0) - READ_CTR(cycle); READ_CTR(instret); - READ_CTR(uarch0); READ_CTR(uarch1); READ_CTR(uarch2); READ_CTR(uarch3); - READ_CTR(uarch4); READ_CTR(uarch5); READ_CTR(uarch6); READ_CTR(uarch7); - READ_CTR(uarch8); READ_CTR(uarch9); READ_CTR(uarch10); READ_CTR(uarch11); - READ_CTR(uarch12); READ_CTR(uarch13); READ_CTR(uarch14); READ_CTR(uarch15); + + READ_CTR(mcycle); + READ_CTR(minstret); + #undef READ_CTR - if(!enable) { - asm volatile (R"( - addi v0, x0, 1 - csrrc v0, stats, v0 - )" : : : "v0"); - } - return 0; } -static void tohost_exit(int code) +void __attribute__((noreturn)) tohost_exit(uintptr_t code) { - write_csr(tohost, (code << 1) | 1); + tohost = (code << 1) | 1; while (1); } -long handle_trap(long cause, long epc, long regs[32]) +uintptr_t __attribute__((weak)) handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32]) { - int csr_insn; - asm volatile ("lw %0, 1f; j 2f; 1: csrr v0, stats; 2:" : "=r"(csr_insn)); - long sys_ret = 0; - - if (cause == CAUSE_ILLEGAL_INSTRUCTION && - (*(int*)epc & csr_insn) == csr_insn) - ; - else if (cause != CAUSE_SYSCALL) - tohost_exit(1337); - else if (regs[16] == SYS_exit) - tohost_exit(regs[18]); - else if (regs[16] == SYS_stats) - sys_ret = handle_stats(regs[18]); - else - sys_ret = handle_frontend_syscall(regs[16], regs[18], regs[19], regs[20]); - - regs[16] = sys_ret; - return epc+4; -} - -static long syscall(long num, long arg0, long arg1, long arg2) -{ - register long v0 asm("v0") = num; - register long a0 asm("a0") = arg0; - register long a1 asm("a1") = arg1; - register long a2 asm("a2") = arg2; - asm volatile ("scall" : "+r"(v0) : "r"(a0), "r"(a1), "r"(a2) : "s0"); - return v0; + tohost_exit(1337); } void exit(int code) { - syscall(SYS_exit, code, 0, 0); + tohost_exit(code); } -void setStats(int enable) +void abort() { - syscall(SYS_stats, enable, 0, 0); + exit(128 + SIGABRT); } void printstr(const char* s) { - syscall(SYS_write, 1, (long)s, strlen(s)); + syscall(SYS_write, 1, (uintptr_t)s, strlen(s)); } void __attribute__((weak)) thread_entry(int cid, int nc) @@ -129,8 +93,20 @@ int __attribute__((weak)) main(int argc, char** argv) 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. @@ -150,14 +126,14 @@ void _init(int cid, int nc) #undef putchar int putchar(int ch) { - static char buf[64] __attribute__((aligned(64))); - static int buflen = 0; + static __thread char buf[64] __attribute__((aligned(64))); + static __thread int buflen = 0; buf[buflen++] = ch; if (ch == '\n' || buflen == sizeof(buf)) { - syscall(SYS_write, 1, (long)buf, buflen); + syscall(SYS_write, 1, (uintptr_t)buf, buflen); buflen = 0; } @@ -400,3 +376,95 @@ int sprintf(char* str, const char* fmt, ...) va_end(ap); return str - str0; } + +void* memcpy(void* dest, const void* src, size_t len) +{ + if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) { + const uintptr_t* s = src; + uintptr_t *d = dest; + while (d < (uintptr_t*)(dest + len)) + *d++ = *s++; + } else { + const char* s = src; + char *d = dest; + while (d < (char*)(dest + len)) + *d++ = *s++; + } + return dest; +} + +void* memset(void* dest, int byte, size_t len) +{ + if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) { + uintptr_t word = byte & 0xFF; + word |= word << 8; + word |= word << 16; + word |= word << 16 << 16; + + uintptr_t *d = dest; + while (d < (uintptr_t*)(dest + len)) + *d++ = word; + } else { + char *d = dest; + while (d < (char*)(dest + len)) + *d++ = byte; + } + return dest; +} + +size_t strlen(const char *s) +{ + const char *p = s; + while (*p) + p++; + return p - s; +} + +size_t strnlen(const char *s, size_t n) +{ + const char *p = s; + while (n-- && *p) + p++; + return p - s; +} + +int strcmp(const char* s1, const char* s2) +{ + unsigned char c1, c2; + + do { + c1 = *s1++; + c2 = *s2++; + } while (c1 != 0 && c1 == c2); + + return c1 - c2; +} + +char* strcpy(char* dest, const char* src) +{ + char* d = dest; + while ((*d++ = *src++)) + ; + return dest; +} + +long atol(const char* str) +{ + long res = 0; + int sign = 0; + + while (*str == ' ') + str++; + + if (*str == '-' || *str == '+') { + sign = *str == '-'; + str++; + } + + while (*str) { + res *= 10; + res += *str++ - '0'; + } + + return sign ? -res : res; +}