From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/13349 Path: news.gmane.org!.POSTED!not-for-mail From: Michael Clark Newsgroups: gmane.linux.lib.musl.general Subject: Re: riscv port for review Date: Wed, 10 Oct 2018 10:36:14 +1300 Message-ID: <00092035-D10F-4034-B6E4-47A063FEB81E@mac.com> References: <20180928022404.GQ17995@brightrain.aerifal.cx> <20180928024633.GR17995@brightrain.aerifal.cx> <20181009180515.GI17110@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 (1.0) Content-Type: multipart/alternative; boundary=Apple-Mail-ED5AB1F0-7BCF-4621-A08F-AA845A29F083 Content-Transfer-Encoding: 7bit X-Trace: blaine.gmane.org 1539120873 17442 195.159.176.226 (9 Oct 2018 21:34:33 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 9 Oct 2018 21:34:33 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-13365-gllmg-musl=m.gmane.org@lists.openwall.com Tue Oct 09 23:34:29 2018 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1g9ze8-0004R7-2X for gllmg-musl@m.gmane.org; Tue, 09 Oct 2018 23:34:28 +0200 Original-Received: (qmail 24087 invoked by uid 550); 9 Oct 2018 21:36:36 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 24030 invoked from network); 9 Oct 2018 21:36:35 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mac.com; s=04042017; t=1539120983; bh=R+YJbzwTuk75gihoK2hO0HAwXpgBkx3MRik/DE/ziKY=; h=From:Content-type:MIME-version:Date:Subject:Message-id:To; b=ND0VUkjTWSkEFi4UqwbC1cWPQWJDYjqNeVxDKOlSgXpfWcyjefYGFQevUUoCIH71l BN7Zh8kOhsSqa2YKtEjxnDRedZYJ8qOeQguJhiAu2RxX22ofh7LtoWkdk/lKPZa9kL oAqCnoktX8FizJZw8K0OKSeCs5+QCu6IYnqETvGiMsoZKIPjx80m2AeharnuWQkWMi Eny3PNDkqeXMQee1sXWJGyuZSgvDqM8/ENsif0xKrFyddG075y+J7+/qRsJlst2+9/ ZtgrXrmGMxkm8oPOaS5zxbJxX1SRyvPUOettnF+XBqrpdeheOHm7XD7n0YNIblnzEr XpLvWUPHHNCeg== X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1807170000 definitions=main-1810090204 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-10-09_14:,, signatures=0 In-reply-to: <20181009180515.GI17110@brightrain.aerifal.cx> X-Mailer: iPhone Mail (16A366) Xref: news.gmane.org gmane.linux.lib.musl.general:13349 Archived-At: --Apple-Mail-ED5AB1F0-7BCF-4621-A08F-AA845A29F083 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi, I have a status update. I haven=E2=80=99t made any changes to the musl port s= ince last week but I did investigate and fix the stat issue in qemu-riscv32.= I ran tests with riscv32 Linux kernel with glibc in QEMU full system emulat= ion as Linux kernel is canonical for the ABI. riscv32 is indeed a unique port in linux-kernel land. It does not define __A= RCH_WANT_STAT64 in arch/riscv/include/asm/unistd.h (unlike all other 32-bit p= orts which confused me a bit). It does not have fstat64 and its stat structu= re matches rv64. I=E2=80=99m kind of stubborn so I had to see the test pass/= fail so I spent some time getting riscv32 linux to build. I should submit a c= ouple of small patches for riscv-linux. I fixed riscv32 stat in riscv-qemu: https://github.com/riscv/riscv-qemu RISC-V QEMU had the 32-bit asm-generic which has a 32-bit stat, but no fstat= 64. We may have missed a chunk when we rebased the 2016 riscv-qemu baseline.= The stat patch is in qemu-for-upstream branch in the riscv-qemu branch. We need to work on getting our QEMU changes upstream. We have problems with g= etting code into upstream QEMU as they have very strict code review policy o= n pull requests. Every commit must have =E2=80=9CReviewed-by:=E2=80=9D with a= =E2=80=9Ctrusted reviewer=E2=80=9D. It doesn=E2=80=99t seem to prevent chan= ges coming from Linaro breaking the RISC-V port but it does prevent our fixe= s going in. My current focus is working on automated test cases for the fixe= s in the QEMU queue so we can change the discourse to does it pass an extens= ive set of tests. Currently the baseline for inclusion is does it compile an= d passes =E2=80=9Cmake check=E2=80=9D, have Reviewed-by and Signed-off-by ta= gs and does it conform to the QEMU coding style (checkpatch.pl). The issue i= s we are making changes that typically require reading the Privileged ISA ma= nual for verification and we don=E2=80=99t have high test case coverage for t= he Privileged ISA. The Base ISA has pretty good test coverage. I would be happy if someone volunteered to help with the RISC-V musl port...= Michael > On 10/10/2018, at 7:05 AM, Rich Felker wrote: >=20 > Ping. >=20 >> On Thu, Sep 27, 2018 at 10:46:33PM -0400, Rich Felker wrote: >>> On Thu, Sep 27, 2018 at 10:24:04PM -0400, Rich Felker wrote: >>> Pulled from here: >>> https://github.com/riscv/riscv-musl/commit/6a4f4a9c774608add4b02f9532251= 8bd2f5f51ee >>>=20 >>> Attached for review. >>=20 >> Review inline below: >>=20 >>> diff --git a/arch/riscv32/atomic_arch.h b/arch/riscv32/atomic_arch.h >>> new file mode 100644 >>> index 0000000..93c89cc >>> --- /dev/null >>> +++ b/arch/riscv32/atomic_arch.h >>> @@ -0,0 +1,35 @@ >>> +#define a_barrier a_barrier >>> +static inline void a_barrier() >>> +{ >>> + __asm__ __volatile__ ("fence rw,rw" : : : "memory"); >>> +} >>> + >>> +#define a_ll a_ll >>> +static inline int a_ll(volatile int *p) >>> +{ >>> + int v; >>> + __asm__ __volatile__ ("lr.w %0, (%1)" : "=3D&r"(v) : "r"(p)); >>> + return v; >>> +} >>> + >>> +#define a_sc a_sc >>> +static inline int a_sc(volatile int *p, int v) >>> +{ >>> + int r; >>> + __asm__ __volatile__ ("sc.w %0, %2, (%1)" : "=3D&r"(r) : "r"(p), "r= "(v) : "memory"); >>> + return !r; >>> +} >>> + >>> +#define a_cas a_cas >>> +static inline int a_cas(volatile int *p, int t, int s) >>> +{ >>> + int old, tmp; >>> + __asm__("1: lr.w %0, %2 \n" >>> + " bne %0, %3, 1f \n" >>> + " sc.w %1, %4, %2 \n" >>> + " bnez %1, 1b \n" >>> + "1: \n" >>> + : "=3D&r"(old), "+r"(tmp), "+A"(*p) >>> + : "r"(t), "r"(s)); >>> + return old; >>> +} >>=20 >> Why are both a_ll/a_sc and a_cas defined, and why is a_cas missing >> barriers? Normally if a_ll/a_sc/a_barrier are defined, the top-level >> atomic.h should be allowed to generate a_cas in terms of them. >>=20 >>> diff --git a/arch/riscv32/bits/signal.h b/arch/riscv32/bits/signal.h >>> new file mode 100644 >>> index 0000000..8b992cc >>> --- /dev/null >>> +++ b/arch/riscv32/bits/signal.h >>> @@ -0,0 +1,113 @@ >>> +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ >>> + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOUR= CE) >>> + >>> +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOUR= CE) >>> +# define MINSIGSTKSZ 2048 >>> +# define SIGSTKSZ 8192 >>> +#endif >>> + >>> +/* gregs[0] holds the program counter. */ >>> + >>> +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) >>> +typedef unsigned long greg_t; >>> +typedef unsigned long gregset_t[32]; >>> + >>> +struct __riscv_f_ext_state { >>> + unsigned int f[32]; >>> + unsigned int fcsr; >>> +}; >>> + >>> +struct __riscv_d_ext_state { >>> + unsigned long long f[32]; >>> + unsigned int fcsr; >>> +}; >>> + >>> +struct __riscv_q_ext_state { >>> + unsigned long long f[64] __attribute__((aligned(16))); >>> + unsigned int fcsr; >>> + unsigned int reserved[3]; >>> +}; >>> + >>> +union __riscv_fp_state { >>> + struct __riscv_f_ext_state f; >>> + struct __riscv_d_ext_state d; >>> + struct __riscv_q_ext_state q; >>> +}; >>> + >>> +typedef union __riscv_fp_state fpregset_t; >>> + >>> +typedef struct sigcontext { >>> + gregset_t gregs; >>> + fpregset_t fpregs; >>> +} mcontext_t; >>> + >>> +#else >>> +typedef struct { >>> + unsigned long gregs[32]; >>> + unsigned long long fpregs[66]; >>> +} mcontext_t; >>> +#endif >>=20 >> In the namespace-safe version of mcontext_t, the names gregs and >> fpregs are not valid here. They would need to be __-prefixed or in >> some other reserved namespace. >>=20 >>> +struct sigaltstack { >>> + void *ss_sp; >>> + int ss_flags; >>> + size_t ss_size; >>> +}; >>> + >>> +typedef struct __ucontext >>> +{ >>> + unsigned long uc_flags; >>> + struct __ucontext *uc_link; >>> + stack_t uc_stack; >>> + sigset_t uc_sigmask; >>> + char __unused[1024 / 8 - sizeof(sigset_t)]; >>=20 >> This is an invalid array of size zero and should just be removed. >>=20 >>> + mcontext_t uc_mcontext; >>> +} ucontext_t; >>=20 >> .... >>=20 >>> diff --git a/arch/riscv32/crt_arch.h b/arch/riscv32/crt_arch.h >>> new file mode 100644 >>> index 0000000..65187e1 >>> --- /dev/null >>> +++ b/arch/riscv32/crt_arch.h >>> @@ -0,0 +1,18 @@ >>> +__asm__( >>> +".text\n" >>> +".global " START "\n" >>> +".type " START ",%function\n" >>> +START ":\n" >>> +".weak __global_pointer$\n" >>> +".hidden __global_pointer$\n\t" >>> +".option push\n" >>> +".option norelax\n\t" >>> +"lla gp, __global_pointer$\n" >>> +".option pop\n\t" >>> +"mv a0, sp\n" >>> +".weak _DYNAMIC\n" >>> +".hidden _DYNAMIC\n\t" >>> +"lla a1, _DYNAMIC\n\t" >>> +"andi sp, sp, -16\n\t" >>> +"jal " START "_c" >>> +); >>> diff --git a/arch/riscv32/pthread_arch.h b/arch/riscv32/pthread_arch.h >>> new file mode 100644 >>> index 0000000..feffaa4 >>> --- /dev/null >>> +++ b/arch/riscv32/pthread_arch.h >>> @@ -0,0 +1,12 @@ >>> +static inline struct pthread *__pthread_self() >>> +{ >>> + char *tp; >>> + __asm__ __volatile__("mv %0, tp" : "=3Dr"(tp)); >>> + return (void *)(tp - sizeof(struct pthread)); >>> +} >>> + >>> +#define TLS_ABOVE_TP >>> +#define GAP_ABOVE_TP 0 >>> +#define TP_ADJ(p) ((char *)p + sizeof(struct pthread)) >>> + >>> +#define MC_PC gregs[0] >>> diff --git a/arch/riscv32/reloc.h b/arch/riscv32/reloc.h >>> new file mode 100644 >>> index 0000000..d057bbe >>> --- /dev/null >>> +++ b/arch/riscv32/reloc.h >>> @@ -0,0 +1,27 @@ >>> +#if defined __riscv_float_abi_soft >>> +#define RISCV_FP_SUFFIX "-sf" >>> +#elif defined __riscv_float_abi_single >>> +#define RISCV_FP_SUFFIX "-sp" >>> +#elif defined __riscv_float_abi_double >>> +#define RISCV_FP_SUFFIX "" >>> +#endif >>> + >>> +#define RISCV_LDSO_HELPER(x) "riscv" #x >>> +#define RISCV_LDSO(x) RISCV_LDSO_HELPER(x) >>> + >>> +#define LDSO_ARCH RISCV_LDSO(__riscv_xlen) RISCV_FP_SUFFIX >>=20 >> Elsewhere it looks like little/big endian are both options, but I see >> no endian variant here. If so this needs to be fixed. >>=20 >> Also what is __riscv_xlen? A predefined macro that expands to 32 or >> 64? Since this file is just for 32-bit it should just be hard-coded >> rather than assuming a macro would expand to the token 32 and not >> (31+1) or some other expression equal to 32, I think. >>=20 >>> diff --git a/arch/riscv32/syscall_arch.h b/arch/riscv32/syscall_arch.h >>> new file mode 100644 >>> index 0000000..bc60d1f >>> --- /dev/null >>> +++ b/arch/riscv32/syscall_arch.h >>> @@ -0,0 +1,78 @@ >>> +#define __SYSCALL_LL_E(x) \ >>> +((union { long long ll; long l[2]; }){ .ll =3D x }).l[0], \ >>> +((union { long long ll; long l[2]; }){ .ll =3D x }).l[1] >>> +#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x)) >>> + >>> +#define __asm_syscall(...) \ >>> + __asm__ __volatile__ ("scall\n\t" \ >>> + : "+r"(a0) : __VA_ARGS__ : "memory"); \ >>> + return a0; \ >>> + >>> +static inline long __syscall0(long n) >>> +{ >>> + register long a7 __asm__("a7") =3D n; >>> + register long a0 __asm__("a0"); >>> + __asm_syscall("r"(a7)) >>> +} >>> + >>> +static inline long __syscall1(long n, long a) >>> +{ >>> + register long a7 __asm__("a7") =3D n; >>> + register long a0 __asm__("a0") =3D a; >>> + __asm_syscall("r"(a7), "0"(a0)) >>> +} >>> + >>> +static inline long __syscall2(long n, long a, long b) >>> +{ >>> + register long a7 __asm__("a7") =3D n; >>> + register long a0 __asm__("a0") =3D a; >>> + register long a1 __asm__("a1") =3D b; >>> + __asm_syscall("r"(a7), "0"(a0), "r"(a1)) >>> +} >>> + >>> +static inline long __syscall3(long n, long a, long b, long c) >>> +{ >>> + register long a7 __asm__("a7") =3D n; >>> + register long a0 __asm__("a0") =3D a; >>> + register long a1 __asm__("a1") =3D b; >>> + register long a2 __asm__("a2") =3D c; >>> + __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2)) >>> +} >>> + >>> +static inline long __syscall4(long n, long a, long b, long c, long d) >>> +{ >>> + register long a7 __asm__("a7") =3D n; >>> + register long a0 __asm__("a0") =3D a; >>> + register long a1 __asm__("a1") =3D b; >>> + register long a2 __asm__("a2") =3D c; >>> + register long a3 __asm__("a3") =3D d; >>> + __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3)) >>> +} >>> + >>> +static inline long __syscall5(long n, long a, long b, long c, long d, l= ong e) >>> +{ >>> + register long a7 __asm__("a7") =3D n; >>> + register long a0 __asm__("a0") =3D a; >>> + register long a1 __asm__("a1") =3D b; >>> + register long a2 __asm__("a2") =3D c; >>> + register long a3 __asm__("a3") =3D d; >>> + register long a4 __asm__("a4") =3D e; >>> + __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4))= >>> +} >>> + >>> +static inline long __syscall6(long n, long a, long b, long c, long d, l= ong e, long f) >>> +{ >>> + register long a7 __asm__("a7") =3D n; >>> + register long a0 __asm__("a0") =3D a; >>> + register long a1 __asm__("a1") =3D b; >>> + register long a2 __asm__("a2") =3D c; >>> + register long a3 __asm__("a3") =3D d; >>> + register long a4 __asm__("a4") =3D e; >>> + register long a5 __asm__("a5") =3D f; >>> + __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4),= "r"(a5)) >>> +} >>> + >>> +#define VDSO_USEFUL >>> +/* We don't have a clock_gettime function. >>> +#define VDSO_CGT_SYM "__vdso_clock_gettime" >>> +#define VDSO_CGT_VER "LINUX_2.6" */ >>=20 >> In that case VDSO_USEFUL might as well also be omitted for now. >>=20 >>> diff --git a/arch/riscv64/atomic_arch.h b/arch/riscv64/atomic_arch.h >>> new file mode 100644 >>> index 0000000..018c7fd >>> --- /dev/null >>> +++ b/arch/riscv64/atomic_arch.h >>> @@ -0,0 +1,66 @@ >>> +#define a_barrier a_barrier >>> +static inline void a_barrier() >>> +{ >>> + __asm__ __volatile__ ("fence rw,rw" : : : "memory"); >>> +} >>> + >>> +#define a_ll a_ll >>> +static inline int a_ll(volatile int *p) >>> +{ >>> + int v; >>> + __asm__ __volatile__ ("lr.w %0, %1" : "=3D&r"(v), "+A"(*p)); >>> + return v; >>> +} >>> + >>> +#define a_sc a_sc >>> +static inline int a_sc(volatile int *p, int v) >>> +{ >>> + int r; >>> + __asm__ __volatile__ ("sc.w %0, %2, %1" : "=3D&r"(r), "+A"(*p) : "r= "(v) : "memory"); >>> +return !r; >>> +} >>> + >>> +#define a_cas a_cas >>> +static inline int a_cas(volatile int *p, int t, int s) >>> +{ >>> + int old, tmp; >>> + __asm__("1: lr.w %0, %2 \n" >>> + " bne %0, %3, 1f \n" >>> + " sc.w %1, %4, %2 \n" >>> + " bnez %1, 1b \n" >>> + "1: \n" >>> + : "=3D&r"(old), "+r"(tmp), "+A"(*p) >>> + : "r"(t), "r"(s)); >>> + return old; >>> +} >>> + >>> +#define a_ll_p a_ll_p >>> +static inline void *a_ll_p(volatile void *p) >>> +{ >>> + void *v; >>> + __asm__ __volatile__ ("lr.d %0, %1" : "=3D&r"(v), "+A"(*(long *)p))= ; >>> + return v; >>> +} >>> + >>> +#define a_sc_p a_sc_p >>> +static inline int a_sc_p(volatile int *p, void *v) >>> +{ >>> + int r; >>> + __asm__ __volatile__ ("sc.d %0, %2, %1" : "=3D&r"(r), "+A"(*(long *= )p) : "r"(v) : "memory"); >>> + return !r; >>> +} >>> + >>> +#define a_cas_p a_cas_p >>> +static inline void *a_cas_p(volatile void *p, void *t, void *s) >>> +{ >>> + void *old; >>> + int tmp; >>> + __asm__("1: lr.d %0, %2 \n" >>> + " bne %0, %3, 1f \n" >>> + " sc.d %1, %4, %2 \n" >>> + " bnez %1, 1b \n" >>> + "1: \n" >>> + : "=3D&r"(old), "+r"(tmp), "+A"(*(long *)p) >>> + : "r"(t), "r"(s)); >>> + return old; >>> +} >>=20 >> Same comments about cas vs ll/sc, and lack of barrier, as 32-bit version.= >>=20 >>> diff --git a/arch/riscv64/bits/signal.h b/arch/riscv64/bits/signal.h >>> new file mode 100644 >>> index 0000000..8b992cc >>> --- /dev/null >>> +++ b/arch/riscv64/bits/signal.h >>> @@ -0,0 +1,113 @@ >>> +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ >>> + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOUR= CE) >>> + >>> +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOUR= CE) >>> +# define MINSIGSTKSZ 2048 >>> +# define SIGSTKSZ 8192 >>> +#endif >>> + >>> +/* gregs[0] holds the program counter. */ >>> + >>> +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) >>> +typedef unsigned long greg_t; >>> +typedef unsigned long gregset_t[32]; >>> + >>> +struct __riscv_f_ext_state { >>> + unsigned int f[32]; >>> + unsigned int fcsr; >>> +}; >>> + >>> +struct __riscv_d_ext_state { >>> + unsigned long long f[32]; >>> + unsigned int fcsr; >>> +}; >>> + >>> +struct __riscv_q_ext_state { >>> + unsigned long long f[64] __attribute__((aligned(16))); >>> + unsigned int fcsr; >>> + unsigned int reserved[3]; >>> +}; >>> + >>> +union __riscv_fp_state { >>> + struct __riscv_f_ext_state f; >>> + struct __riscv_d_ext_state d; >>> + struct __riscv_q_ext_state q; >>> +}; >>> + >>> +typedef union __riscv_fp_state fpregset_t; >>> + >>> +typedef struct sigcontext { >>> + gregset_t gregs; >>> + fpregset_t fpregs; >>> +} mcontext_t; >>> + >>> +#else >>> +typedef struct { >>> + unsigned long gregs[32]; >>> + unsigned long long fpregs[66]; >>> +} mcontext_t; >>> +#endif >>> + >>> +struct sigaltstack { >>> + void *ss_sp; >>> + int ss_flags; >>> + size_t ss_size; >>> +}; >>> + >>> +typedef struct __ucontext >>> +{ >>> + unsigned long uc_flags; >>> + struct __ucontext *uc_link; >>> + stack_t uc_stack; >>> + sigset_t uc_sigmask; >>> + char __unused[1024 / 8 - sizeof(sigset_t)]; >>> + mcontext_t uc_mcontext; >>> +} ucontext_t; >>=20 >> Same issues here as 32-bit. >>=20 >>> diff --git a/arch/riscv64/reloc.h b/arch/riscv64/reloc.h >>> new file mode 100644 >>> index 0000000..8bd90dd >>> --- /dev/null >>> +++ b/arch/riscv64/reloc.h >>> @@ -0,0 +1,27 @@ >>> +#if defined __riscv_float_abi_soft >>> +#define RISCV_FP_SUFFIX "-sf" >>> +#elif defined __riscv_float_abi_single >>> +#define RISCV_FP_SUFFIX "-sp" >>> +#elif defined __riscv_float_abi_double >>> +#define RISCV_FP_SUFFIX "" >>> +#endif >>> + >>> +#define RISCV_LDSO_HELPER(x) "riscv" #x >>> +#define RISCV_LDSO(x) RISCV_LDSO_HELPER(x) >>> + >>> +#define LDSO_ARCH RISCV_LDSO(__riscv_xlen) RISCV_FP_SUFFIX >>=20 >> Same here. >>=20 >>> diff --git a/configure b/configure >>> index 997e665..4d3d8b4 100755 >>> --- a/configure >>> +++ b/configure >>> @@ -322,6 +322,8 @@ microblaze*) ARCH=3Dmicroblaze ;; >>> or1k*) ARCH=3Dor1k ;; >>> powerpc64*) ARCH=3Dpowerpc64 ;; >>> powerpc*) ARCH=3Dpowerpc ;; >>> +riscv64*) ARCH=3Driscv64 ;; >>> +riscv*) ARCH=3Driscv32 ;; >>> sh[1-9bel-]*|sh|superh*) ARCH=3Dsh ;; >>> s390x*) ARCH=3Ds390x ;; >>> unknown) fail "$0: unable to detect target arch; try $0 --target=3D..." ;= ; >>> @@ -640,6 +642,11 @@ trycppif __LITTLE_ENDIAN__ "$t" && SUBARCH=3D${SUBA= RCH}le >>> trycppif _SOFT_FLOAT "$t" && fail "$0: error: soft-float not supported o= n powerpc64" >>> fi >>>=20 >>> +if test "$ARCH" =3D "riscv" || test "$ARCH" =3D "riscv64" ; then >>> +trycppif "RISCVEB || _RISCVEB || __RISCVEB || __RISCVEB__" "$t" && SUBA= RCH=3D${SUBARCH}eb >>=20 >> Predefined macros that violate the namespace (RISCVEB) shouldn't be >> defined or observed. >>=20 >>> +trycppif __riscv_soft_float "$t" && SUBARCH=3D${SUBARCH}-sf >>> +fi >>> + >>> if test "$ARCH" =3D "sh" ; then >>> tryflag CFLAGS_AUTO -Wa,--isa=3Dany >>> trycppif __BIG_ENDIAN__ "$t" && SUBARCH=3D${SUBARCH}eb >>> diff --git a/crt/riscv32/crti.s b/crt/riscv32/crti.s >>> new file mode 100644 >>> index 0000000..6916bfd >>> --- /dev/null >>> +++ b/crt/riscv32/crti.s >>> @@ -0,0 +1,11 @@ >>> +.section .init >>> +.global _init >>> +.type _init,%function >>> +_init: >>> + ret >>> + >>> +.section .fini >>> +.global _fini >>> +.type _fini,%function >>> +_fini: >>> + ret >>> diff --git a/crt/riscv32/crtn.s b/crt/riscv32/crtn.s >>> new file mode 100644 >>> index 0000000..e69de29 >>=20 >> It looks like these are not used, right? >>=20 >>> diff --git a/include/elf.h b/include/elf.h >>> index c229735..ec2e8fd 100644 >>> --- a/include/elf.h >>> +++ b/include/elf.h >>> @@ -3164,6 +3164,62 @@ enum >>> #define R_BPF_NONE 0 >>> #define R_BPF_MAP_FD 1 >>>=20 >>> +#define R_RISCV_NONE 0 >>> +#define R_RISCV_32 1 >>> +#define R_RISCV_64 2 >>> +#define R_RISCV_RELATIVE 3 >>> +#define R_RISCV_COPY 4 >>> +#define R_RISCV_JUMP_SLOT 5 >>> +#define R_RISCV_TLS_DTPMOD32 6 >>> +#define R_RISCV_TLS_DTPMOD64 7 >>> +#define R_RISCV_TLS_DTPREL32 8 >>> +#define R_RISCV_TLS_DTPREL64 9 >>> +#define R_RISCV_TLS_TPREL32 10 >>> +#define R_RISCV_TLS_TPREL64 11 >>> + >>> +#define R_RISCV_BRANCH 16 >>> +#define R_RISCV_JAL 17 >>> +#define R_RISCV_CALL 18 >>> +#define R_RISCV_CALL_PLT 19 >>> +#define R_RISCV_GOT_HI20 20 >>> +#define R_RISCV_TLS_GOT_HI20 21 >>> +#define R_RISCV_TLS_GD_HI20 22 >>> +#define R_RISCV_PCREL_HI20 23 >>> +#define R_RISCV_PCREL_LO12_I 24 >>> +#define R_RISCV_PCREL_LO12_S 25 >>> +#define R_RISCV_HI20 26 >>> +#define R_RISCV_LO12_I 27 >>> +#define R_RISCV_LO12_S 28 >>> +#define R_RISCV_TPREL_HI20 29 >>> +#define R_RISCV_TPREL_LO12_I 30 >>> +#define R_RISCV_TPREL_LO12_S 31 >>> +#define R_RISCV_TPREL_ADD 32 >>> +#define R_RISCV_ADD8 33 >>> +#define R_RISCV_ADD16 34 >>> +#define R_RISCV_ADD32 35 >>> +#define R_RISCV_ADD64 36 >>> +#define R_RISCV_SUB8 37 >>> +#define R_RISCV_SUB16 38 >>> +#define R_RISCV_SUB32 39 >>> +#define R_RISCV_SUB64 40 >>> +#define R_RISCV_GNU_VTINHERIT 41 >>> +#define R_RISCV_GNU_VTENTRY 42 >>> +#define R_RISCV_ALIGN 43 >>> +#define R_RISCV_RVC_BRANCH 44 >>> +#define R_RISCV_RVC_JUMP 45 >>> +#define R_RISCV_RVC_LUI 46 >>> +#define R_RISCV_GPREL_I 47 >>> +#define R_RISCV_GPREL_S 48 >>> +#define R_RISCV_TPREL_I 49 >>> +#define R_RISCV_TPREL_S 50 >>> +#define R_RISCV_RELAX 51 >>> +#define R_RISCV_SUB6 52 >>> +#define R_RISCV_SET6 53 >>> +#define R_RISCV_SET8 54 >>> +#define R_RISCV_SET16 55 >>> +#define R_RISCV_SET32 56 >>> +#define R_RISCV_32_PCREL 57 >>> + >>> #ifdef __cplusplus >>> } >>> #endif >>=20 >> This should be its own patch independent of the port; I can commit it >> earlier. >>=20 >>> diff --git a/src/thread/riscv32/syscall_cp.s b/src/thread/riscv32/syscal= l_cp.s >>> new file mode 100644 >>> index 0000000..71bf6d3 >>> --- /dev/null >>> +++ b/src/thread/riscv32/syscall_cp.s >>> @@ -0,0 +1,29 @@ >>> +.global __cp_begin >>> +.hidden __cp_begin >>> +.global __cp_end >>> +.hidden __cp_end >>> +.global __cp_cancel >>> +.hidden __cp_cancel >>> +.hidden __cancel >>> +.global __syscall_cp_asm >>> +.hidden __syscall_cp_asm >>> +.type __syscall_cp_asm, %function >>> +__syscall_cp_asm: >>> +__cp_begin: >>> + lw t0, 0(a0) >>> + bnez t0, __cp_cancel >>> + >>> + mv t0, a1 >>> + mv a0, a2 >>> + mv a1, a3 >>> + mv a2, a4 >>> + mv a3, a5 >>> + mv a4, a6 >>> + mv a5, a7 >>> + lw a6, 0(sp) >>> + mv a7, t0 >>> + scall >>> +__cp_cancel: >>> + ret >>> +__cp_end: >>> + j __cancel >>=20 >> The labels here are backwards. __cp_end must point immediately after >> the syscall instruction, and __cp_end needs to jump to __cancel. >>=20 >>> diff --git a/src/thread/riscv64/syscall_cp.s b/src/thread/riscv64/syscal= l_cp.s >>> new file mode 100644 >>> index 0000000..c745b32 >>> --- /dev/null >>> +++ b/src/thread/riscv64/syscall_cp.s >>> @@ -0,0 +1,29 @@ >>> +.global __cp_begin >>> +.hidden __cp_begin >>> +.global __cp_end >>> +.hidden __cp_end >>> +.global __cp_cancel >>> +.hidden __cp_cancel >>> +.hidden __cancel >>> +.global __syscall_cp_asm >>> +.hidden __syscall_cp_asm >>> +.type __syscall_cp_asm, %function >>> +__syscall_cp_asm: >>> +__cp_begin: >>> + ld t0, 0(a0) >>> + bnez t0, __cp_cancel >>> + >>> + mv t0, a1 >>> + mv a0, a2 >>> + mv a1, a3 >>> + mv a2, a4 >>> + mv a3, a5 >>> + mv a4, a6 >>> + mv a5, a7 >>> + ld a6, 0(sp) >>> + mv a7, t0 >>> + scall >>> +__cp_cancel: >>> + ret >>> +__cp_end: >>> + j __cancel >>> --=20 >>> 2.10.0 >>>=20 >>=20 >> Likewise here. >>=20 >> Rich --Apple-Mail-ED5AB1F0-7BCF-4621-A08F-AA845A29F083 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
Hi,=

I have a status update. I h= aven=E2=80=99t made any changes to the musl port since last week but I did i= nvestigate and fix the stat issue in qemu-riscv32. I ran tests with riscv32 L= inux kernel with glibc in QEMU full system emulation as Linux kernel is cano= nical for the ABI.

riscv32 i= s indeed a unique port in linux-kernel land. It does not define __ARCH_WANT_= STAT64 in arch/riscv/include/asm/unistd.h (unlike all other 32-bit ports whi= ch confused me a bit). It does not have fstat64 and its stat structure match= es rv64. I=E2=80=99m kind of stubborn so I had to see the test pass/fail so I= spent some time getting riscv32 linux to build. I should submit a couple of= small patches for riscv-linux.

I fixed riscv32 stat in riscv-qemu: https://github.com/riscv/riscv-qemu

RISC-V QEMU had the 32-bit asm-generic which h= as a 32-bit stat, but no fstat64. We may have missed a chunk when we rebased= the 2016 riscv-qemu baseline. The stat patch is in qemu-for-upstream branch= in the riscv-qemu branch.

= We need to work on getting our QEMU changes upstream. We have problems with g= etting code into upstream QEMU as they have very strict code review policy o= n pull requests. Every commit must have =E2=80=9CReviewed-by:=E2=80=9D with a= =E2=80=9Ctrusted reviewer=E2=80=9D. It doesn=E2=80=99t seem to prevent chan= ges coming from Linaro breaking the RISC-V port but it does prevent our fixe= s going in. My current focus is working on automated test cases for the fixe= s in the QEMU queue so we can change the discourse to does it pass an extens= ive set of tests. Currently the baseline for inclusion is does it compile an= d passes =E2=80=9Cmake check=E2=80=9D, have Reviewed-by and Signed-off-by ta= gs and does it conform to the QEMU coding style (checkpatch.pl). The issue i= s we are making changes that typically require reading the Privileged ISA ma= nual for verification and we don=E2=80=99t have high test case coverage for t= he Privileged ISA. The Base ISA has pretty good test coverage.

I would be happy if someone volunteered t= o help with the RISC-V musl port...

Michael

On 10/10/2018, at 7:05 AM, Rich Fe= lker <dalias@libc.org> wrote:
Ping.
On Thu, Sep 27, 2018 at 10:46:33PM -0400, Rich Felke= r wrote:
On Thu, Sep 27, 2018 at 1= 0:24:04PM -0400, Rich Felker wrote:
Pulled from here:
<= a href=3D"https://github.com/riscv/riscv-musl/commit/6a4f4a9c774608add4b02f9= 5322518bd2f5f51ee">https://github.com/riscv/riscv-musl/commit/6a4f4a9c774608= add4b02f95322518bd2f5f51ee

Attached= for review.
<= span>
Review inline b= elow:

diff --gi= t a/arch/riscv32/atomic_arch.h b/arch/riscv32/atomic_arch.h
new file mode 100644
index 0000000..93c89cc
--- /dev/null
+++ b/arch/riscv32/atomic_arch.h<= br>
@@ -0,0 +1,35 @@
+#define a_barrier a_barrier
+static inline void a_barrier()
+{<= br>
+    __asm__ __volatile__ ("fence rw,rw" : : : "memory"= );
+}
+
+#define a_ll a= _ll
+static inline int a_ll(volatile int *p)
<= span>+{
+    int v;
+   &= nbsp;__asm__ __volatile__ ("lr.w %0, (%1)" : "=3D&r"(v) : "r"(p));
+    return v;
+}
+
+#define a_sc a_sc
=
+static inline int= a_sc(volatile int *p, int v)
+{
+  = ;  int r;
+    __asm__ __volatile__ ("sc.w %= 0, %2, (%1)" : "=3D&r"(r) : "r"(p), "r"(v) : "memory");
+    return !r;
+}
+
+#define a_cas a_cas
+static inline int a_cas(vo= latile int *p, int t, int s)
+{
+  =  int old, tmp;
+    __asm__("1:  lr.w=    %0, %2      \n"
+        "    bne    &nb= sp;%0, %3, 1f  \n"
+        " &nb= sp;  sc.w    %1, %4, %2  \n"
+        "    bnez    %1,= 1b      \n"
+     &nbs= p;  "1:           &nb= sp;          \n"
+        : "=3D&r"(old), "+r"(tmp), "+A"(*p= )
+        : "r"(t), "r"(s));
+    return old;
+}

Why are both a_ll/a_sc and a_cas defined, and w= hy is a_cas missing
b= arriers? Normally if a_ll/a_sc/a_barrier are defined, the top-level
atomic.h should be allowed to= generate a_cas in terms of them.

diff --git a/arch/riscv32/bits/signal.h b/arch/riscv32/bi= ts/signal.h
new file mode 100644
index 0= 000000..8b992cc
--- /dev/null
+++ b/arch= /riscv32/bits/signal.h
@@ -0,0 +1,113 @@
+= #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+= || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(= _GNU_SOURCE) || defined(_BSD_SOURCE)
+# define MINSIGSTKSZ= 2048
+# define SIGSTKSZ 8192
+#endif
+
+/* gregs[0] holds the program counter. *= /
+
+#if defined(_GNU_SOURCE) || defined(= _BSD_SOURCE)
<= blockquote type=3D"cite">+typedef unsigned long greg_t;
+typedef unsigned long gregset_t[32];
+
+struct __riscv_f_ext_state {
+    unsigned i= nt f[32];
+    unsigned int fcsr;
+};
+
+struct __riscv_d_ext_state {
+    unsigned long long f[32];
= +    unsigned int fcsr;
+};
+<= /span>
+struct __riscv_q_ext_state {
+   &= nbsp;unsigned long long f[64] __attribute__((aligned(16)));
+    unsigned int fcsr;
+    unsigne= d int reserved[3];
+};
+
+union __riscv_fp_state {
+    struct __riscv= _f_ext_state f;
+    struct __riscv_d_ext_state d= ;
+    struct __riscv_q_ext_state q;
= +};
+
+typedef union __riscv_fp_st= ate fpregset_t;
+
+typedef struct sigcon= text {
+    gregset_t gregs;
+=    fpregset_t fpregs;
+} mcontext_t;
=
+
+#else
+typedef struct {
+    unsigned long gregs[32];
=
+ &nb= sp;  unsigned long long fpregs[66];
+} mcontext_t;
+#endif

In t= he namespace-safe version of mcontext_t, the names gregs and
fpregs are not valid here. They woul= d need to be __-prefixed or in
some other reserved namespace.

+struct sigaltstack {
+   &n= bsp;void *ss_sp;
+    int ss_flags;
= +    size_t ss_size;
+};
+
+typedef struct __ucontext
+{<= br>
+    unsigned long uc_flags;
+  =  struct __ucontext *uc_link;
+    stack_t u= c_stack;
+    sigset_t uc_sigmask;
<= span>+    char __unused[1024 / 8 - sizeof(sigset_t)];

This is an invalid array of size zero an= d should just be removed.
<= span>
+    mcontext_t uc_mcontext;
+} ucont= ext_t;
<= /span>
....

diff --git a/arch/riscv32/crt_a= rch.h b/arch/riscv32/crt_arch.h
new file mode 100644
index 0000000..65187e1
--- /dev/null
+++ b/arch/riscv32/crt_arch.h
=
@@ -0,0 +1,18 @@
+__asm__(
+".text\n"
+"= .global " START "\n"
+".type " START ",%function\n"=
+START ":\n"
+".weak __global_pointer$\n"
+".hidden __global_pointer$\n\t"
+".option pu= sh\n"
+".option norelax\n\t"
+"lla gp, _= _global_pointer$\n"
+".option pop\n\t"
+= "mv a0, sp\n"
=
+".weak _DYNAMIC\n"
<= /blockquote>
+".hid= den _DYNAMIC\n\t"
+"lla a1, _DYNAMIC\n\t"
+"andi sp, sp, -16\n\t"
+"jal " START "_c"
<= span>+);
diff --git a/arch/riscv32/pthread_arch.h b/arch/r= iscv32/pthread_arch.h
new file mode 100644
index 0000000..feffaa4
--- /dev/null
+= ++ b/arch/riscv32/pthread_arch.h
@@ -0,0 +1,12 @@
+static inline struct pthread *__pthread_self()
= +{
+    char *tp;
+   &nb= sp;__asm__ __volatile__("mv %0, tp" : "=3Dr"(tp));
+  = ;  return (void *)(tp - sizeof(struct pthread));
+}
+
+#define TLS_ABOVE_TP
+#define GAP_ABOVE_TP 0
+#define TP_ADJ(p) ((char *)p + s= izeof(struct pthread))
+
+#define MC_PC gr= egs[0]
diff --git a/arch/riscv32/reloc.h b/arch/riscv32/re= loc.h
new file mode 100644
index 0000000= ..d057bbe
--- /dev/null
+++ b/arch/riscv= 32/reloc.h
@@ -0,0 +1,27 @@
+#if defined= __riscv_float_abi_soft
+#define RISCV_FP_SUFFIX "-sf"
+#elif defined __riscv_float_abi_single
=
+#def= ine RISCV_FP_SUFFIX "-sp"
+#elif defined __riscv_float_abi= _double
+#define RISCV_FP_SUFFIX ""
+#en= dif
+
+#define RISCV_LDSO_HELPER(x) "ris= cv" #x
+#define RISCV_LDSO(x) RISCV_LDSO_HELPER(x)<= br>
+
<= blockquote type=3D"cite">+#define LDSO_ARCH RISCV_LDSO(__riscv_xlen) R= ISCV_FP_SUFFIX

Elsewhere it l= ooks like little/big endian are both options, but I see
no endian variant here. If so this needs t= o be fixed.
Also what is __riscv_xlen? A p= redefined macro that expands to 32 or
64? Since this file is just for 32-bit it should just be ha= rd-coded
rather than a= ssuming a macro would expand to the token 32 and not
=
(31+1) or some other expression equal to 32,= I think.

=
diff -= -git a/arch/riscv32/syscall_arch.h b/arch/riscv32/syscall_arch.h
<= /blockquote>
new file mode 100644
index 0000000..bc60d1f
--- /dev/null
+++ b/arch/riscv32/syscall_arch.h<= /span>
@@ -0,0 +1,78 @@
+#define __SYSCALL_LL_E= (x) \
+((union { long long ll; long l[2]; }){ .ll =3D x })= .l[0], \
+((union { long long ll; long l[2]; }){ .ll =3D x= }).l[1]
+#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))=
+
+#define __asm_syscall(...) \<= br>
+    __asm__ __volatile__ ("scall\n\t" \
+    : "+r"(a0) : __VA_ARGS__ : "memory"); \
+    return a0; \
+
+static i= nline long __syscall0(long n)
+{
+  = ;  register long a7 __asm__("a7") =3D n;
+   &nb= sp;register long a0 __asm__("a0");
+    __asm_sy= scall("r"(a7))
+}
+
+s= tatic inline long __syscall1(long n, long a)
+{
=
+    register long a7 __asm__("a7") =3D n;
+    register long a0 __asm__("a0") =3D a;
+ &= nbsp;  __asm_syscall("r"(a7), "0"(a0))
+}
<= /blockquote>
+
+static inline long __syscall2(long n, long a, lo= ng b)
+{
+    register long a7= __asm__("a7") =3D n;
+    register long a0 __asm= __("a0") =3D a;
+    register long a1 __asm__("a= 1") =3D b;
+    __asm_syscall("r"(a7), "0"(a0), "= r"(a1))
+}
+
+static i= nline long __syscall3(long n, long a, long b, long c)
+{
+    register long a7 __asm__("a7") =3D n;=
+    register long a0 __asm__("a0") =3D a;
<= /blockquote>
+    register long a1 __asm__("a1") =3D b;
+    register long a2 __asm__("a2") =3D c;
+ &= nbsp;  __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2))
+}
+
+static inline long __syscall4(= long n, long a, long b, long c, long d)
=
+{
+    register long a7 __asm__("a7") =3D n;
+ &= nbsp;  register long a0 __asm__("a0") =3D a;
+  =  register long a1 __asm__("a1") =3D b;
+   &nbs= p;register long a2 __asm__("a2") =3D c;
=
+    reg= ister long a3 __asm__("a3") =3D d;
+    __asm_sy= scall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3))
+}
+
+static inline long __syscall5(long n, long= a, long b, long c, long d, long e)
+{
+=    register long a7 __asm__("a7") =3D n;
<= /blockquote>
+ &nbs= p;  register long a0 __asm__("a0") =3D a;
+   &n= bsp;register long a1 __asm__("a1") =3D b;
+    r= egister long a2 __asm__("a2") =3D c;
+    regist= er long a3 __asm__("a3") =3D d;
+    register lo= ng a4 __asm__("a4") =3D e;
+    __asm_syscall("r= "(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4))
<= /blockquote>
+}
+
+static inline long __syscall6(long n, long= a, long b, long c, long d, long e, long f)
+{
<= /blockquote>
+    register long a7 __asm__("a7") =3D n;
+    register long a0 __asm__("a0") =3D a;
+ &= nbsp;  register long a1 __asm__("a1") =3D b;
+  =  register long a2 __asm__("a2") =3D c;
+   &nbs= p;register long a3 __asm__("a3") =3D d;
=
+    reg= ister long a4 __asm__("a4") =3D e;
+    register= long a5 __asm__("a5") =3D f;
+    __asm_syscall= ("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5))
= +}
+
+#define VDSO_USEFUL
+/* We don't have a clock_gettime function.
+#de= fine VDSO_CGT_SYM "__vdso_clock_gettime"
+#define VDSO_CGT= _VER "LINUX_2.6" */

In that c= ase VDSO_USEFUL might as well also be omitted for now.

diff --git a/arch/riscv64/atomic_arch= .h b/arch/riscv64/atomic_arch.h
new file mode 100644
index 0000000..018c7fd
--- /dev/null
+++ b/arch/riscv64/atomic_arch.h
@@ -0,0 +1,66 @= @
+#define a_barrier a_barrier
+static in= line void a_barrier()
+{
+    _= _asm__ __volatile__ ("fence rw,rw" : : : "memory");
<= /blockquote>
+}
+
+#define a_ll a_ll
<= /blockquote>
+stati= c inline int a_ll(volatile int *p)
+{
+ &= nbsp;  int v;
+    __asm__ __volatile__ ("l= r.w %0, %1" : "=3D&r"(v), "+A"(*p));
+    re= turn v;
+}
+
+#define a= _sc a_sc
+static inline int a_sc(volatile int *p, int v)
+{
+    int r;
+    __asm__ __volatile__ ("sc.w %0, %2, %1" : "=3D&r"(r), "= +A"(*p) : "r"(v) : "memory");
+return !r;
+}
+
+#define a_cas a_cas
= +static inline int a_cas(volatile int *p, int t, int s)
+{
+    int old, tmp;
+ &n= bsp;  __asm__("1:  lr.w    %0, %2    = ;  \n"
+        "  &nbs= p; bne     %0, %3, 1f  \n"
+=        "    sc.w    %1, %= 4, %2  \n"
+        "   = ; bnez    %1, 1b      \n"
+        "1:      =             &nbs= p;   \n"
+        : "=3D= &r"(old), "+r"(tmp), "+A"(*p)
+       &= nbsp;: "r"(t), "r"(s));
+    return old;<= br>
+}
=
+
+#define a_ll_p a_ll_p
+static inline void *a_ll_p(volatile void *p)
<= span>+{
+    void *v;
+  =  __asm__ __volatile__ ("lr.d %0, %1" : "=3D&r"(v), "+A"(*(long *)p= ));
+    return v;
+}
+
+#define a_sc_p a_sc_p
=
+stat= ic inline int a_sc_p(volatile int *p, void *v)
+{
+    int r;
+    __asm__ __v= olatile__ ("sc.d %0, %2, %1" : "=3D&r"(r), "+A"(*(long *)p) : "r"(v) : "= memory");
+    return !r;
+}
+
+#define a_cas_p a_cas_p
+static inline void *a_cas_p(volatile void *p, void *t, void *s)<= br>
+{
=
+    void *old;
= +    int tmp;
+    __asm__("1:  l= r.d    %0, %2      \n"
<= span>+        "    bne    =  %0, %3, 1f  \n"
+        " &= nbsp;  sc.d    %1, %4, %2  \n"
+        "    bnez    %= 1, 1b      \n"
=
+     &n= bsp;  "1:           &= nbsp;          \n"<= br>
+        : "=3D&r"(old), "+r"(tmp), "+A"(= *(long *)p)
+        : "r"(t), "r"(s))= ;
+    return old;
+}

Same comments about cas vs ll/sc, and= lack of barrier, as 32-bit version.

diff --git a/arch/riscv64/bits/signal.h b/arch/riscv64= /bits/signal.h
new file mode 100644
inde= x 0000000..8b992cc
--- /dev/null
+++ b/a= rch/riscv64/bits/signal.h
@@ -0,0 +1,113 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOUR= CE)
+
+#if defined(_XOPEN_SOURCE) || def= ined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+# define MINSIG= STKSZ 2048
+# define SIGSTKSZ 8192
=
+#end= if
+
+/* gregs[0] holds the program counte= r. */
+
+#if defined(_GNU_SOURCE) || def= ined(_BSD_SOURCE)
+typedef unsigned long greg_t;
+typedef unsigned long gregset_t[32];
+
+struct __riscv_f_ext_state {
<= blockquote type=3D"cite">
+    unsi= gned int f[32];
+    unsigned int fcsr;
+};
=
+
+struct __riscv_d_ext_st= ate {
+    unsigned long long f[32];
<= /blockquote>
+    unsigned int fcsr;
+};
<= span>+
+struct __riscv_q_ext_state {
+ &= nbsp;  unsigned long long f[64] __attribute__((aligned(16)));
+    unsigned int fcsr;
+    = unsigned int reserved[3];
+};
+
+union __riscv_fp_state {
+    struct _= _riscv_f_ext_state f;
+    struct __riscv_d_ext_s= tate d;
+    struct __riscv_q_ext_state q;
+};
+
+typedef union __risc= v_fp_state fpregset_t;
+
+typedef struct s= igcontext {
+    gregset_t gregs;
+    fpregset_t fpregs;
+} mcontext_t;
+
+#else
=
+typedef struct {<= /span>
+    unsigned long gregs[32];
= +    unsigned long long fpregs[66];
+} mcontext_= t;
+#endif
+
+struct s= igaltstack {
<= blockquote type=3D"cite">+    void *ss_sp;
+    int ss_flags;
+    size_t ss_siz= e;
+};
+
+typedef stru= ct __ucontext
=
+{
+    unsigned= long uc_flags;
+    struct __ucontext *uc_link;=
+    stack_t uc_stack;
<= /blockquote>
+ &nbs= p;  sigset_t uc_sigmask;
+    char __unused= [1024 / 8 - sizeof(sigset_t)];
+    mcontext_t u= c_mcontext;
+} ucontext_t;

Same issues here as 32-bit.

diff --git a/arch/riscv64/reloc.h b/arch/riscv= 64/reloc.h
new file mode 100644
index 00= 00000..8bd90dd
--- /dev/null
+++ b/arch/= riscv64/reloc.h
@@ -0,0 +1,27 @@
+#if de= fined __riscv_float_abi_soft
+#define RISCV_FP_SUFFIX "-sf= "
+#elif defined __riscv_float_abi_single
+#define RISCV_FP_SUFFIX "-sp"
+#elif defined __riscv_flo= at_abi_double
=
+#define RISCV_FP_SUFFIX ""
+#endif
+
+#define RISCV_LDSO_HELPER(x= ) "riscv" #x
<= blockquote type=3D"cite">+#define RISCV_LDSO(x) RISCV_LDSO_HELPER(x)
+
+#define LDSO_ARCH RISCV_LDSO(__riscv_x= len) RISCV_FP_SUFFIX

Same he= re.

diff --git a= /configure b/configure
index 997e665..4d3d8b4 100755<= br>
--- a/configure
+++ b/configure
@@ -322,6 +322,8 @@ microblaze*) ARCH=3Dmicroblaze ;;
o= r1k*) ARCH=3Dor1k ;;
powerpc64*) ARCH=3Dpowerpc64 ;;
powerpc*) ARCH=3Dpowerpc ;;
+riscv64*) ARCH=3D= riscv64 ;;
+riscv*) ARCH=3Driscv32 ;;
s= h[1-9bel-]*|sh|superh*) ARCH=3Dsh ;;
s390x*) ARCH=3Ds390x= ;;
unknown) fail "$0: unable to detect target arch; try $= 0 --target=3D..." ;;
@@ -640,6 +642,11 @@ trycppif __LITTL= E_ENDIAN__ "$t" && SUBARCH=3D${SUBARCH}le
trycppi= f _SOFT_FLOAT "$t" && fail "$0: error: soft-float not supported on p= owerpc64"
fi

+if tes= t "$ARCH" =3D "riscv" || test "$ARCH" =3D "riscv64" ; then
+trycppif "RISCVEB || _RISCVEB || __RISCVEB || __RISCVEB__" "$t" &&= SUBARCH=3D${SUBARCH}eb

Pred= efined macros that violate the namespace (RISCVEB) shouldn't be
defined or observed.

+trycppif __riscv_soft_floa= t "$t" && SUBARCH=3D${SUBARCH}-sf
+fi
= +
if test "$ARCH" =3D "sh" ; then
tryflag CFLAGS_AUTO -Wa,--isa=3Dany
trycppif __BIG_ENDI= AN__ "$t" && SUBARCH=3D${SUBARCH}eb
diff --git a/c= rt/riscv32/crti.s b/crt/riscv32/crti.s
<= blockquote type=3D"cite">
new file mode 10064= 4
index 0000000..6916bfd
--- /dev/null
+++ b/crt/riscv32/crti.s
@@ -0,0 +1,11 @@<= /span>
+.section .init
+.global _init
+.type _init,%function
+_init:
= +        ret
+
+.section .fini
+.global _fini
+.type _fini,%function
+_fini:
+  =       ret
=
diff --git a/crt/r= iscv32/crtn.s b/crt/riscv32/crtn.s
new file mode 100644
index 0000000..e69de29
<= blockquote type=3D"cite">
It looks like these are not used, right?
<= blockquote type=3D"cite">
diff --git a/include/elf.h b/include/el= f.h
index c229735..ec2e8fd 100644
<= /blockquote>
--- a/= include/elf.h
=
+++ b/include/elf.h
<= /blockquote>
@@ -31= 64,6 +3164,62 @@ enum
#define R_BPF_NONE     &nb= sp;  0
#define R_BPF_MAP_FD       &nb= sp;1

+#define R_RISCV_NONE   =          0
+#= define R_RISCV_32          &nbs= p;   1
+#define R_RISCV_64    = ;          2
<= span>+#define R_RISCV_RELATIVE        3
+#define R_RISCV_COPY       &= nbsp;    4
+#define R_RISCV_JUMP_SLOT &= nbsp;     5
+#define R_RISCV_TLS_= DTPMOD32    6
+#define R_RISCV_TLS_DTPMOD64=    7
+#define R_RISCV_TLS_DTPREL32  &= nbsp; 8
<= blockquote type=3D"cite">+#define R_RISCV_TLS_DTPREL64   &nb= sp;9
+#define R_RISCV_TLS_TPREL32     = 10
+#define R_RISCV_TLS_TPREL64     11=
+
+#define R_RISCV_BRANCH   &= nbsp;      16
+#define R_RIS= CV_JAL            &nb= sp;17
+#define R_RISCV_CALL      =       18
<= blockquote type=3D"cite">
+#define R_RISCV_CA= LL_PLT        19
<= /blockquote>
+#defi= ne R_RISCV_GOT_HI20        20
<= /blockquote>
+#define R_RISCV_TLS_GOT_HI20    21
= +#define R_RISCV_TLS_GD_HI20     22
+#= define R_RISCV_PCREL_HI20      23
+#define R_RISCV_PCREL_LO12_I    24
<= /blockquote>
+#defi= ne R_RISCV_PCREL_LO12_S    25
+#define R_RI= SCV_HI20            2= 6
+#define R_RISCV_LO12_I      &nb= sp;   27
+#define R_RISCV_LO12_S  &nbs= p;       28
+#define R_= RISCV_TPREL_HI20      29
+#define= R_RISCV_TPREL_LO12_I    30
+#define R_RISC= V_TPREL_LO12_S    31
+#define R_RISCV_TPREL= _ADD       32
+#define R_RIS= CV_ADD8            33=
+#define R_RISCV_ADD16      &nbs= p;    34
+#define R_RISCV_ADD32  =          35
+= #define R_RISCV_ADD64          =  36
+#define R_RISCV_SUB8     &nb= sp;      37
+#define R_RISCV= _SUB16           38=
+#define R_RISCV_SUB32        = ;   39
+#define R_RISCV_SUB64   &n= bsp;       40
+#define R= _RISCV_GNU_VTINHERIT   41
+#define R_RISCV_GNU_V= TENTRY     42
+#define R_RISCV_ALIGN &= nbsp;         43
+#define R_RISCV_RVC_BRANCH      44
<= /blockquote>
+#define R_RISCV_RVC_JUMP        4= 5
+#define R_RISCV_RVC_LUI      &n= bsp;  46
+#define R_RISCV_GPREL_I   &n= bsp;     47
+#define R_RISCV_GPRE= L_S         48
+#d= efine R_RISCV_TPREL_I         49
+#define R_RISCV_TPREL_S       &n= bsp; 50
<= blockquote type=3D"cite">+#define R_RISCV_RELAX    &nbs= p;      51
+#define R_RISCV_= SUB6            52
+#define R_RISCV_SET6       &n= bsp;    53
+#define R_RISCV_SET8  = ;          54
= +#define R_RISCV_SET16         = ;  55
+#define R_RISCV_SET32    &= nbsp;      56
+#define R_RIS= CV_32_PCREL        57
+=
#ifdef __cplusplus
<= blockquote type=3D"cite">
}
#endif

This should be its= own patch independent of the port; I can commit it
<= blockquote type=3D"cite">earlier.

diff --git a/src/thread/riscv32/syscall_cp.s b/src/= thread/riscv32/syscall_cp.s
new file mode 100644
=
index 0000000..71bf6d3
--- /dev/null
<= span>+++ b/src/thread/riscv32/syscall_cp.s
@@ -0,0 +1,29 @= @
+.global __cp_begin
<= blockquote type=3D"cite">
+.hidden __cp_begin=
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type __syscal= l_cp_asm, %function
+__syscall_cp_asm:
+= __cp_begin:
+        lw= t0, 0(a0)
+        bne= z t0, __cp_cancel
+
+    =     mv t0, a1
+    &nbs= p;   mv a0, a2
+     &n= bsp;  mv a1, a3
+      =   mv a2, a4
+       = ; mv a3, a5
+       &nb= sp;mv a4, a6
<= blockquote type=3D"cite">+        m= v a5, a7
+        lw a6= , 0(sp)
+        mv a7,= t0
+        scall
+__cp_cancel:
+      = ;  ret
+__cp_end:
+  &nbs= p;     j __cancel

The labels here are backwards. __cp_end must point immediately a= fter
the syscall inst= ruction, and __cp_end needs to jump to __cancel.

diff --git a/src/thread/riscv64/syscall_cp= .s b/src/thread/riscv64/syscall_cp.s
new file mode 100644<= /span>
index 0000000..c745b32
--- /dev/null
+++ b/src/thread/riscv64/syscall_cp.s
@@ -0,0= +1,29 @@
+.global __cp_begin
+.hidden _= _cp_begin
+.global __cp_end
+.hidden __c= p_end
+.global __cp_cancel
+.hidden __cp= _cancel
+.hidden __cancel
+.global __sys= call_cp_asm
+.hidden __syscall_cp_asm
+.= type __syscall_cp_asm, %function
+__syscall_cp_asm:=
+__cp_begin:
+      &= nbsp; ld t0, 0(a0)
+      &n= bsp; bnez t0, __cp_cancel
+
+  = ;      mv t0, a1
+  &nb= sp;     mv a0, a2
+   &= nbsp;    mv a1, a3
<= blockquote type=3D"cite">
+    = ;    mv a2, a4
+    &nb= sp;   mv a3, a5
+     &= nbsp;  mv a4, a6
+      = ;  mv a5, a7
+       = ; ld a6, 0(sp)
+       =  mv a7, t0
+       &nbs= p;scall
+__cp_cancel:
=
+   &nbs= p;    ret
+__cp_end:
+        j __cancel
--=
2.10.0


Likewise here.

Rich
= --Apple-Mail-ED5AB1F0-7BCF-4621-A08F-AA845A29F083--