diff --git a/abis/linux/signal.h b/abis/linux/signal.h index e0924e551d..4b74fd5232 100644 --- a/abis/linux/signal.h +++ b/abis/linux/signal.h @@ -361,6 +361,13 @@ typedef struct __ucontext { mcontext_t uc_mcontext; } ucontext_t; +struct sigcontext { + unsigned long int gregs[32]; + unsigned long long int fpregs[66] __attribute__ ((__aligned__ (16))); +}; + +#warning amnogusd + #elif defined (__aarch64__) typedef struct sigcontext { diff --git a/sysdeps/managarm/generic/file.cpp b/sysdeps/managarm/generic/file.cpp index 4bcbcec09f..bd048961d9 100644 --- a/sysdeps/managarm/generic/file.cpp +++ b/sysdeps/managarm/generic/file.cpp @@ -2463,6 +2463,8 @@ int sys_uname(struct utsname *buf) { strcpy(buf->machine, "x86_64"); #elif defined (__aarch64__) strcpy(buf->machine, "aarch64"); +#elif defined (__riscv) && __riscv_xlen == 64 + strcpy(buf->machine, "riscv64"); #else # error Unknown architecture #endif diff --git a/sysdeps/managarm/meson.build b/sysdeps/managarm/meson.build index 888af89543..89a402561d 100644 --- a/sysdeps/managarm/meson.build +++ b/sysdeps/managarm/meson.build @@ -62,6 +62,12 @@ elif host_machine.cpu_family() == 'x86_64' 'x86_64/thread_entry.S', 'x86_64/thread.cpp' ) +elif host_machine.cpu_family() == 'riscv64' + libc_sources += files( + 'riscv64/signals.S', + 'riscv64/thread_entry.S', + 'riscv64/thread.cpp' + ) else error('Unknown architecture') endif diff --git a/sysdeps/managarm/riscv64/crt-src/crt0.S b/sysdeps/managarm/riscv64/crt-src/crt0.S new file mode 100644 index 0000000000..16c79d681f --- /dev/null +++ b/sysdeps/managarm/riscv64/crt-src/crt0.S @@ -0,0 +1,15 @@ +.section .text +.global _start +_start: + .weak __global_pointer$ + .hidden __global_pointer$ + .option push + .option norelax + lla gp, __global_pointer$ + .option pop + + mv a0, sp + la a1, main + call __mlibc_entry +.section .note.GNU-stack,"",%progbits + diff --git a/sysdeps/managarm/riscv64/signals.S b/sysdeps/managarm/riscv64/signals.S new file mode 100644 index 0000000000..af95724215 --- /dev/null +++ b/sysdeps/managarm/riscv64/signals.S @@ -0,0 +1,8 @@ +.section .text + nop // TODO: why is this needed? +.global __mlibc_signal_restore +.type __mlibc_signal_restore, @function +__mlibc_signal_restore: + unimp // TODO +.section .note.GNU-stack,"",%progbits + diff --git a/sysdeps/managarm/riscv64/thread.cpp b/sysdeps/managarm/riscv64/thread.cpp new file mode 100644 index 0000000000..d0d00babfa --- /dev/null +++ b/sysdeps/managarm/riscv64/thread.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include +#include + +extern "C" void __mlibc_enter_thread(void *entry, void *user_arg, Tcb *tcb) { + // Wait until our parent sets up the TID. + while(!__atomic_load_n(&tcb->tid, __ATOMIC_RELAXED)) + mlibc::sys_futex_wait(&tcb->tid, 0, nullptr); + + if(mlibc::sys_tcb_set(tcb)) + __ensure(!"sys_tcb_set() failed"); + + void *(*func)(void *) = reinterpret_cast(entry); + auto result = func(user_arg); + + auto self = reinterpret_cast(tcb); + + self->returnValue = result; + __atomic_store_n(&self->didExit, 1, __ATOMIC_RELEASE); + mlibc::sys_futex_wake(&self->didExit); + + mlibc::sys_thread_exit(); +} + +namespace mlibc { + +static constexpr size_t default_stacksize = 0x200000; + +int sys_prepare_stack(void **stack, void *entry, void *user_arg, void *tcb, size_t *stack_size, size_t *guard_size) { + if (!*stack_size) + *stack_size = default_stacksize; + *guard_size = 0; + + uintptr_t *sp; + if (*stack) { + sp = reinterpret_cast(*stack); + } else { + sp = reinterpret_cast(reinterpret_cast( + mmap(nullptr, *stack_size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) + ) + *stack_size); + } + + *--sp = reinterpret_cast(tcb); + *--sp = reinterpret_cast(user_arg); + *--sp = reinterpret_cast(entry); + *stack = reinterpret_cast(sp); + return 0; +} + +} //namespace mlibc diff --git a/sysdeps/managarm/riscv64/thread_entry.S b/sysdeps/managarm/riscv64/thread_entry.S new file mode 100644 index 0000000000..f43b8375d7 --- /dev/null +++ b/sysdeps/managarm/riscv64/thread_entry.S @@ -0,0 +1,17 @@ +.section .text +.global __mlibc_start_thread +.type __mlibc_start_thread, "function" +__mlibc_start_thread: + // if this works i am going to eat my dog + ld a0, 0(sp) + ld a1, 8(sp) + ld a2, 16(sp) + addi sp, sp, 24 + andi sp, sp, -16 + call __mlibc_enter_thread + unimp + +.parent: + ret +.section .note.GNU-stack,"",%progbits +