diff options
Diffstat (limited to 'libc/sysdeps/linux/riscv64')
-rw-r--r-- | libc/sysdeps/linux/riscv64/Makefile.arch | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/__syscall_error.c | 4 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/bits/atomic.h | 170 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/bits/fcntl.h | 7 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/bits/shm.h | 18 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h | 9 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/bits/uClibc_page.h | 34 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/bits/wordsize.h | 3 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/cache.c | 55 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/clone.S | 8 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/crt1.S | 3 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/jmpbuf-unwind.h | 7 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/setjmp.S | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/sys/asm.h | 6 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/sys/ucontext.h | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/riscv64/sysdep.h | 1 |
16 files changed, 302 insertions, 29 deletions
diff --git a/libc/sysdeps/linux/riscv64/Makefile.arch b/libc/sysdeps/linux/riscv64/Makefile.arch index 74c074852..21ecaa65b 100644 --- a/libc/sysdeps/linux/riscv64/Makefile.arch +++ b/libc/sysdeps/linux/riscv64/Makefile.arch @@ -1,2 +1,2 @@ -CSRC-y := __syscall_error.c +CSRC-y := __syscall_error.c cache.c SSRC-y := __longjmp.S setjmp.S vfork.S clone.S diff --git a/libc/sysdeps/linux/riscv64/__syscall_error.c b/libc/sysdeps/linux/riscv64/__syscall_error.c index 2b642e816..c682aae49 100644 --- a/libc/sysdeps/linux/riscv64/__syscall_error.c +++ b/libc/sysdeps/linux/riscv64/__syscall_error.c @@ -10,8 +10,8 @@ /* This routine is jumped to by all the syscall handlers, to stash * an error number into errno. */ -int __syscall_error(int err_no) attribute_hidden; -int __syscall_error(int err_no) +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) { __set_errno(-err_no); return -1; diff --git a/libc/sysdeps/linux/riscv64/bits/atomic.h b/libc/sysdeps/linux/riscv64/bits/atomic.h new file mode 100644 index 000000000..8bf6abfac --- /dev/null +++ b/libc/sysdeps/linux/riscv64/bits/atomic.h @@ -0,0 +1,170 @@ +/* Copyright (C) 2003-2017 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _RISCV64_ATOMIC_MACHINE_H +#define _RISCV64_ATOMIC_MACHINE_H 1 + +#define typeof __typeof__ + +#include <stdint.h> +#include <sysdep.h> + +typedef int8_t atomic8_t; +typedef int16_t atomic16_t; +typedef int32_t atomic32_t; +typedef int64_t atomic64_t; + +typedef uint8_t uatomic8_t; +typedef uint16_t uatomic16_t; +typedef uint32_t uatomic32_t; +typedef uint64_t uatomic64_t; + +typedef intptr_t atomicptr_t; +typedef uintptr_t uatomicptr_t; +typedef intmax_t atomic_max_t; +typedef uintmax_t uatomic_max_t; + +#define __HAVE_64B_ATOMICS 1 +#define USE_ATOMIC_COMPILER_BUILTINS 1 + +/* Compare and exchange. + For all "bool" routines, we return FALSE if exchange succesful. */ + +# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + }) + +# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + +# define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \ + ({ \ + typeof (*mem) __oldval = (oldval); \ + __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \ + model, __ATOMIC_RELAXED); \ + __oldval; \ + }) + + +/* Compare and exchange with "acquire" semantics, ie barrier after. */ + +# define atomic_compare_and_exchange_bool_acq(mem, new, old) \ + __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \ + mem, new, old, __ATOMIC_ACQUIRE) + +# define atomic_compare_and_exchange_val_acq(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ + mem, new, old, __ATOMIC_ACQUIRE) + +/* Compare and exchange with "release" semantics, ie barrier before. */ + +# define atomic_compare_and_exchange_val_rel(mem, new, old) \ + __atomic_val_bysize (__arch_compare_and_exchange_val, int, \ + mem, new, old, __ATOMIC_RELEASE) + + +/* Atomic exchange (without compare). */ + +# define __arch_exchange_8_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define __arch_exchange_16_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define __arch_exchange_32_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define __arch_exchange_64_int(mem, newval, model) \ + __atomic_exchange_n (mem, newval, model) + +# define atomic_exchange_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE) + +# define atomic_exchange_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE) + + +/* Atomically add value and return the previous (unincremented) value. */ + +# define __arch_exchange_and_add_8_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define __arch_exchange_and_add_16_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define __arch_exchange_and_add_32_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define __arch_exchange_and_add_64_int(mem, value, model) \ + __atomic_fetch_add (mem, value, model) + +# define atomic_exchange_and_add_acq(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + __ATOMIC_ACQUIRE) + +# define atomic_exchange_and_add_rel(mem, value) \ + __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \ + __ATOMIC_RELEASE) + +/* Barrier macro. */ +#define atomic_full_barrier() __sync_synchronize() + +#endif diff --git a/libc/sysdeps/linux/riscv64/bits/fcntl.h b/libc/sysdeps/linux/riscv64/bits/fcntl.h index a08bbf5b5..a9d7c84e0 100644 --- a/libc/sysdeps/linux/riscv64/bits/fcntl.h +++ b/libc/sysdeps/linux/riscv64/bits/fcntl.h @@ -40,6 +40,7 @@ # define O_DIRECT 00040000 /* Direct disk access. */ # define O_NOATIME 01000000 /* Do not set atime. */ # define O_PATH 010000000 /* Resolve pathname but do not open file. */ +# define O_TMPFILE 020200000 /* Atomically create nameless file. */ #endif #ifdef __USE_LARGEFILE64 @@ -88,11 +89,13 @@ # define F_SETLEASE 1024 /* Set a lease. */ # define F_GETLEASE 1025 /* Enquire what lease is active. */ # define F_NOTIFY 1026 /* Request notfications on a directory. */ -# define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with - close-on-exit set on new fd. */ # define F_SETPIPE_SZ 1031 /* Set pipe page size array. */ # define F_GETPIPE_SZ 1032 /* Get pipe page size array. */ #endif +#if defined __USE_XOPEN2K8 || defined __USE_GNU +# define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with + close-on-exit set on new fd. */ +#endif /* For F_[GET|SET]FL. */ #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ diff --git a/libc/sysdeps/linux/riscv64/bits/shm.h b/libc/sysdeps/linux/riscv64/bits/shm.h index dbe4851f9..8a11c7050 100644 --- a/libc/sysdeps/linux/riscv64/bits/shm.h +++ b/libc/sysdeps/linux/riscv64/bits/shm.h @@ -38,16 +38,16 @@ struct shmid_ds struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ __time_t shm_atime; /* time of last shmat() */ - unsigned long int __unused1; + unsigned long int __uclibc_unused1; __time_t shm_dtime; /* time of last shmdt() */ - unsigned long int __unused2; + unsigned long int __uclibc_unused2; __time_t shm_ctime; /* time of last change by shmctl() */ - unsigned long int __unused3; + unsigned long int __uclibc_unused3; __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ - unsigned long int __unused4; - unsigned long int __unused5; + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; }; #ifdef __USE_MISC @@ -69,10 +69,10 @@ struct shminfo unsigned long int shmmni; unsigned long int shmseg; unsigned long int shmall; - unsigned long int __unused1; - unsigned long int __unused2; - unsigned long int __unused3; - unsigned long int __unused4; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + unsigned long int __uclibc_unused3; + unsigned long int __uclibc_unused4; }; struct shm_info diff --git a/libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h b/libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h index b754f3227..63b17770d 100644 --- a/libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h +++ b/libc/sysdeps/linux/riscv64/bits/uClibc_arch_features.h @@ -5,12 +5,15 @@ #ifndef _BITS_UCLIBC_ARCH_FEATURES_H #define _BITS_UCLIBC_ARCH_FEATURES_H -#undef __UCLIBC_ABORT_INSTRUCTION__ +#define __UCLIBC_ABORT_INSTRUCTION__ "unimp" /* can your target use syscall6() for mmap ? */ -#undef __UCLIBC_MMAP_HAS_6_ARGS__ +#define __UCLIBC_MMAP_HAS_6_ARGS__ -#define __UCLIBC_SYSCALL_ALIGN_64BIT__ +/* does your target use statx */ +#undef __UCLIBC_HAVE_STATX__ + +#undef __UCLIBC_SYSCALL_ALIGN_64BIT__ /* does your target have a broken create_module() ? */ #define __UCLIBC_BROKEN_CREATE_MODULE__ diff --git a/libc/sysdeps/linux/riscv64/bits/uClibc_page.h b/libc/sysdeps/linux/riscv64/bits/uClibc_page.h new file mode 100644 index 000000000..7282638ba --- /dev/null +++ b/libc/sysdeps/linux/riscv64/bits/uClibc_page.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2004 Erik Andersen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The GNU C Library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the GNU C Library; see the file COPYING.LIB. If + * not, see <http://www.gnu.org/licenses/>. + */ + +/* Supply an architecture specific value for PAGE_SIZE and friends. */ + +#ifndef _UCLIBC_PAGE_H +#define _UCLIBC_PAGE_H + +/* PAGE_SHIFT determines the page size -- in this case 4096 */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +/* Some architectures always use 12 as page shift for mmap2() eventhough the + * real PAGE_SHIFT != 12. Other architectures use the same value as + * PAGE_SHIFT... + */ +#define MMAP2_PAGE_SHIFT PAGE_SHIFT + +#endif /* _UCLIBC_PAGE_H */ diff --git a/libc/sysdeps/linux/riscv64/bits/wordsize.h b/libc/sysdeps/linux/riscv64/bits/wordsize.h index 67a16ba62..1fc649aad 100644 --- a/libc/sysdeps/linux/riscv64/bits/wordsize.h +++ b/libc/sysdeps/linux/riscv64/bits/wordsize.h @@ -25,5 +25,6 @@ #if __riscv_xlen == 64 # define __WORDSIZE_TIME64_COMPAT32 1 #else -# error "rv32i-based targets are not supported" +# define __WORDSIZE_TIME64_COMPAT32 1 +// # warning "rv32i-based targets are experimental" #endif diff --git a/libc/sysdeps/linux/riscv64/cache.c b/libc/sysdeps/linux/riscv64/cache.c new file mode 100644 index 000000000..aa99a2a0d --- /dev/null +++ b/libc/sysdeps/linux/riscv64/cache.c @@ -0,0 +1,55 @@ +/* RISC-V instruction cache flushing VDSO calls + Copyright (C) 2017-2020 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <stdlib.h> +#include <atomic.h> +#include <sys/syscall.h> + +#ifndef __NR_riscv_flush_icache +#define __NR_riscv_flush_icache 259 +#endif + +typedef int (*func_type) (void *, void *, unsigned long int); + +static int +__riscv_flush_icache_syscall (void *start, void *end, unsigned long int flags) +{ + return INLINE_SYSCALL (riscv_flush_icache, 3, start, end, flags); +} + +static func_type +__lookup_riscv_flush_icache (void) +{ + /* always call the system call directly.*/ + return &__riscv_flush_icache_syscall; +} + +int +__riscv_flush_icache (void *start, void *end, unsigned long int flags) +{ + static volatile func_type cached_func; + + func_type func = atomic_load_relaxed (&cached_func); + + if (!func) + { + func = __lookup_riscv_flush_icache (); + atomic_store_relaxed (&cached_func, func); + } + + return func (start, end, flags); +} diff --git a/libc/sysdeps/linux/riscv64/clone.S b/libc/sysdeps/linux/riscv64/clone.S index f7684c88d..315de2ac8 100644 --- a/libc/sysdeps/linux/riscv64/clone.S +++ b/libc/sysdeps/linux/riscv64/clone.S @@ -29,6 +29,9 @@ .text LEAF (clone) + /* Align stack to a 128-bit boundary as per RISC-V ABI. */ + andi a1,a1,ALMASK + /* Sanity check arguments. */ beqz a0,L (invalid) /* No NULL function pointers. */ beqz a1,L (invalid) /* No NULL stack pointers. */ @@ -57,7 +60,7 @@ L (invalid): li a0, -EINVAL /* Something bad happened -- no child created. */ L (error): - j __syscall_error + tail __syscall_error END (clone) /* Load up the arguments to the function. Put this block of code in @@ -66,6 +69,9 @@ L (error): ENTRY (__thread_start) L (thread_start): + .cfi_label .Ldummy + cfi_undefined (ra) + /* Restore the arg for user's function. */ REG_L a1,0(sp) /* Function pointer. */ REG_L a0,SZREG(sp) /* Argument pointer. */ diff --git a/libc/sysdeps/linux/riscv64/crt1.S b/libc/sysdeps/linux/riscv64/crt1.S index 1e8403d26..5e33046d4 100644 --- a/libc/sysdeps/linux/riscv64/crt1.S +++ b/libc/sysdeps/linux/riscv64/crt1.S @@ -52,9 +52,6 @@ _start: la a0, main REG_L a1, 0(sp) /* argc. */ addi a2, sp, SZREG /* argv. */ - /* - * No support fo app_init/app_fini as we don't support shared libraries. - */ mv a3, zero mv a4, zero andi sp, sp, ALMASK /* Align stack. */ diff --git a/libc/sysdeps/linux/riscv64/jmpbuf-unwind.h b/libc/sysdeps/linux/riscv64/jmpbuf-unwind.h index 2e5f37f10..fb5d65ddd 100644 --- a/libc/sysdeps/linux/riscv64/jmpbuf-unwind.h +++ b/libc/sysdeps/linux/riscv64/jmpbuf-unwind.h @@ -23,8 +23,8 @@ /* Test if longjmp to JMPBUF would unwind the frame containing a local variable at ADDRESS. */ -#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \ - ((void *) (address) < (void *) demangle ((jmpbuf)[0].__sp)) +#define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) ((jmpbuf)[0].__sp)) #define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) @@ -33,9 +33,6 @@ static inline uintptr_t __attribute__ ((unused)) _jmpbuf_sp (__jmp_buf regs) { uintptr_t sp = regs[0].__sp; -#ifdef PTR_DEMANGLE - PTR_DEMANGLE (sp); -#endif return sp; } diff --git a/libc/sysdeps/linux/riscv64/setjmp.S b/libc/sysdeps/linux/riscv64/setjmp.S index 4cdb8e9c3..100a0bd78 100644 --- a/libc/sysdeps/linux/riscv64/setjmp.S +++ b/libc/sysdeps/linux/riscv64/setjmp.S @@ -20,7 +20,7 @@ ENTRY (_setjmp) li a1, 0 - j __sigsetjmp + j HIDDEN_JUMPTARGET (__sigsetjmp) END (_setjmp) ENTRY (setjmp) li a1, 1 diff --git a/libc/sysdeps/linux/riscv64/sys/asm.h b/libc/sysdeps/linux/riscv64/sys/asm.h index ddb84b683..3c94c9a70 100644 --- a/libc/sysdeps/linux/riscv64/sys/asm.h +++ b/libc/sysdeps/linux/riscv64/sys/asm.h @@ -26,7 +26,11 @@ # define REG_S sd # define REG_L ld #elif __riscv_xlen == 32 -# error "rv32i-based targets are not supported" +# define PTRLOG 2 +# define SZREG 4 +# define REG_S sw +# define REG_L lw +// # warning "rv32i-based targets are experimental" #else # error __riscv_xlen must equal 32 or 64 #endif diff --git a/libc/sysdeps/linux/riscv64/sys/ucontext.h b/libc/sysdeps/linux/riscv64/sys/ucontext.h index 2a80a853c..2893ff359 100644 --- a/libc/sysdeps/linux/riscv64/sys/ucontext.h +++ b/libc/sysdeps/linux/riscv64/sys/ucontext.h @@ -21,6 +21,8 @@ #define _SYS_UCONTEXT_H 1 #include <features.h> +#include <signal.h> +#include <bits/sigcontext.h> typedef unsigned long int __riscv_mc_gp_state[32]; diff --git a/libc/sysdeps/linux/riscv64/sysdep.h b/libc/sysdeps/linux/riscv64/sysdep.h index b12329332..3fa04bb57 100644 --- a/libc/sysdeps/linux/riscv64/sysdep.h +++ b/libc/sysdeps/linux/riscv64/sysdep.h @@ -20,6 +20,7 @@ #define _LINUX_RISCV_SYSDEP_H 1 #include <common/sysdep.h> +#include <sys/syscall.h> #ifdef __ASSEMBLER__ |