From f5d6a7b10010455d7bacf2d6ffb60bece61e2ba0 Mon Sep 17 00:00:00 2001 From: "W. J. van der Laan" Date: Sun, 4 Apr 2021 07:24:07 +0000 Subject: [PATCH] lib: Linux riscv64-mes-gcc support. * lib/linux/riscv64-mes-gcc/_exit.c, lib/linux/riscv64-mes-gcc/_write.c, lib/linux/riscv64-mes-gcc/crt1.c, lib/linux/riscv64-mes-gcc/syscall-internal.c, lib/linux/riscv64-mes-gcc/syscall.c: New files to make it possible to compile mes for riscv64-mes-gcc. --- lib/linux/riscv64-mes-gcc/_exit.c | 39 +++++ lib/linux/riscv64-mes-gcc/_write.c | 40 +++++ lib/linux/riscv64-mes-gcc/crt1.c | 90 ++++++++++ lib/linux/riscv64-mes-gcc/syscall-internal.c | 62 +++++++ lib/linux/riscv64-mes-gcc/syscall.c | 166 +++++++++++++++++++ 5 files changed, 397 insertions(+) create mode 100644 lib/linux/riscv64-mes-gcc/_exit.c create mode 100644 lib/linux/riscv64-mes-gcc/_write.c create mode 100644 lib/linux/riscv64-mes-gcc/crt1.c create mode 100644 lib/linux/riscv64-mes-gcc/syscall-internal.c create mode 100644 lib/linux/riscv64-mes-gcc/syscall.c diff --git a/lib/linux/riscv64-mes-gcc/_exit.c b/lib/linux/riscv64-mes-gcc/_exit.c new file mode 100644 index 00000000..4b4b0a06 --- /dev/null +++ b/lib/linux/riscv64-mes-gcc/_exit.c @@ -0,0 +1,39 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2019,2020 Jan (janneke) Nieuwenhuizen + * Copyright © 2021 W. J. van der Laan + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include "mes/lib-mini.h" + +#define SYS_exit 93 + +// *INDENT-OFF* +void +_exit (int code) +{ + register long __a7 asm ("a7") = SYS_exit; + register long __a0 asm ("a0") = code; + asm volatile ( + "ecall\n\t" + : // no outputs + : "r" (__a0), "r" (__a7) + ); + // not reached + _exit (0); +} diff --git a/lib/linux/riscv64-mes-gcc/_write.c b/lib/linux/riscv64-mes-gcc/_write.c new file mode 100644 index 00000000..fd154e5f --- /dev/null +++ b/lib/linux/riscv64-mes-gcc/_write.c @@ -0,0 +1,40 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2019,2020 Jan (janneke) Nieuwenhuizen + * Copyright © 2021 W. J. van der Laan + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include "mes/lib-mini.h" + +#define SYS_write 64 + +// *INDENT-OFF* +ssize_t +_write (int filedes, void const *buffer, size_t size) +{ + register long __a7 asm ("a7") = (long) SYS_write; + register long __a0 asm ("a0") = (long) filedes; + register long __a1 asm ("a1") = (long) buffer; + register long __a2 asm ("a2") = (long) size; + asm volatile ( + "ecall\n\t" + : "+r" (__a0) + : "r" (__a7), "r" (__a1), "r" (__a2) + ); + return (ssize_t)__a0; +} diff --git a/lib/linux/riscv64-mes-gcc/crt1.c b/lib/linux/riscv64-mes-gcc/crt1.c new file mode 100644 index 00000000..e0a2e22e --- /dev/null +++ b/lib/linux/riscv64-mes-gcc/crt1.c @@ -0,0 +1,90 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2017,2018,2019,2020 Jan (janneke) Nieuwenhuizen + * Copyright © 2019,2020 Danny Milosavljevic + * Copyright © 2021 W. J. van der Laan + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include +//int main (int argc, char *argv[], char *envp[]); + +/* gcc will generate the following preamble: + + addi sp,sp,-16 + sd s0,8(sp) + addi s0,sp,16 +*/ + +// *INDENT-OFF* +void +_start () +{ + asm ( + ".option push\n\t" + ".option norelax\n\t" + "lla gp, __global_pointer$\n\t" + ".option pop\n\t" + "andi sp, sp, ~15\n\t" // make sure sp conforms to ABI alignment + ); + + asm ( + "li t0, 0\n\t" + "mv %0, t0\n" + : "=r" (__stdin) + : //no inputs "" + ); + + asm ( + "li t0, 1\n\t" + "mv %0, t0\n" + : "=r" (__stdout) + : //no inputs "" + ); + + asm ( + "li t0, 2\n\t" + "mv %0, t0\n" + : "=r" (__stderr) + : //no inputs "" + ); + + // environ is &argv[argc + 1] + asm ( + "lw t0, 0(s0)\n\t" + "addi t1, s0, 8\n\t" + "addi t0, t0, 1\n\t" + "slli t0, t0, 3\n\t" + "add %0, t1, t0\n\t" + : "=r" (environ) + : //no inputs "" + ); + + asm ( + "lw a0, 0(s0)\n\t" // a0 argc + "addi a1, s0, 8\n\t" // a1 argv + "mv a2, %0\n\t" // a2 envp + "jal main\n\t" + + "li a7, 93\n\t" // SYS_exit + "ecall\n\t" // exit(return value from main) + + "ebreak\n\t" + : //no outputs "" + : "r" (environ) + ); +} diff --git a/lib/linux/riscv64-mes-gcc/syscall-internal.c b/lib/linux/riscv64-mes-gcc/syscall-internal.c new file mode 100644 index 00000000..08302903 --- /dev/null +++ b/lib/linux/riscv64-mes-gcc/syscall-internal.c @@ -0,0 +1,62 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen + * Copyright © 2021 W. J. van der Laan + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include + +// *INDENT-OFF* +static long +__sys_call_internal (long sys_call) +{ + register long __a7 asm ("a7") = sys_call; + register long __a0 asm ("a0"); + asm volatile ( + "ecall\n\t" + : "=r" (__a0) + : "r" (__a7) + ); + return __a0; +} + +static long +__sys_call2_internal (long sys_call, long one, long two) +{ + register long __a7 asm ("a7") = sys_call; + register long __a0 asm ("a0") = one; + register long __a1 asm ("a1") = two; + asm volatile ( + "ecall\n\t" + : "+r" (__a0) + : "r" (__a7), "r" (__a1) + ); + return __a0; +} +// *INDENT-ON* + +/* Returns < 0 on error (errno-like value from kernel), or 0 on success */ +int +__raise (int signum) +{ + long pid = __sys_call_internal (SYS_getpid); + if (pid < 0) + return pid; + else + return __sys_call2_internal (SYS_kill, pid, signum); +} diff --git a/lib/linux/riscv64-mes-gcc/syscall.c b/lib/linux/riscv64-mes-gcc/syscall.c new file mode 100644 index 00000000..b9006a49 --- /dev/null +++ b/lib/linux/riscv64-mes-gcc/syscall.c @@ -0,0 +1,166 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen + * Copyright © 2021 W. J. van der Laan + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include +#include + +// *INDENT-OFF* +long +__sys_call (long sys_call) +{ + register long __a7 asm ("a7") = sys_call; + register long __a0 asm ("a0"); + asm volatile ( + "ecall\n\t" + : "=r" (__a0) + : "r" (__a7) + ); + return __a0; +} + +long +__sys_call1 (long sys_call, long one) +{ + register long __a7 asm ("a7") = sys_call; + register long __a0 asm ("a0") = one; + asm volatile ( + "ecall\n\t" + : "+r" (__a0) + : "r" (__a7) + ); + return __a0; +} + +long +__sys_call2 (long sys_call, long one, long two) +{ + register long __a7 asm ("a7") = sys_call; + register long __a0 asm ("a0") = one; + register long __a1 asm ("a1") = two; + asm volatile ( + "ecall\n\t" + : "+r" (__a0) + : "r" (__a7), "r" (__a1) + ); + return __a0; +} + +long +__sys_call3 (long sys_call, long one, long two, long three) +{ + register long __a7 asm ("a7") = sys_call; + register long __a0 asm ("a0") = one; + register long __a1 asm ("a1") = two; + register long __a2 asm ("a2") = three; + asm volatile ( + "ecall\n\t" + : "+r" (__a0) + : "r" (__a7), "r" (__a1), "r" (__a2) + ); + return __a0; +} + +long +__sys_call4 (long sys_call, long one, long two, long three, long four) +{ + register long __a7 asm ("a7") = sys_call; + register long __a0 asm ("a0") = one; + register long __a1 asm ("a1") = two; + register long __a2 asm ("a2") = three; + register long __a3 asm ("a3") = four; + asm volatile ( + "ecall\n\t" + : "+r" (__a0) + : "r" (__a7), "r" (__a1), "r" (__a2), "r" (__a3) + ); + return __a0; +} +// *INDENT-ON* + +long +_sys_call (long sys_call) +{ + long r = __sys_call (sys_call); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +long +_sys_call1 (long sys_call, long one) +{ + long r = __sys_call1 (sys_call, one); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +long +_sys_call2 (long sys_call, long one, long two) +{ + long r = __sys_call2 (sys_call, one, two); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +long +_sys_call3 (long sys_call, long one, long two, long three) +{ + long r = __sys_call3 (sys_call, one, two, three); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +} + +long +_sys_call4 (long sys_call, long one, long two, long three, long four) +{ + long r = __sys_call4 (sys_call, one, two, three, four); + if (r < 0) + { + errno = -r; + r = -1; + } + else + errno = 0; + return r; +}