From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/13353 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 16:41:15 +1300 Message-ID: References: <20180928022404.GQ17995@brightrain.aerifal.cx> <20180928024633.GR17995@brightrain.aerifal.cx> <20181009180515.GI17110@brightrain.aerifal.cx> <00092035-D10F-4034-B6E4-47A063FEB81E@mac.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 (1.0) Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Trace: blaine.gmane.org 1539142777 22913 195.159.176.226 (10 Oct 2018 03:39:37 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 10 Oct 2018 03:39:37 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-13369-gllmg-musl=m.gmane.org@lists.openwall.com Wed Oct 10 05:39:33 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 1gA5LQ-0005sV-IL for gllmg-musl@m.gmane.org; Wed, 10 Oct 2018 05:39:33 +0200 Original-Received: (qmail 15603 invoked by uid 550); 10 Oct 2018 03:41:41 -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 15551 invoked from network); 10 Oct 2018 03:41:40 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mac.com; s=04042017; t=1539142884; bh=MMlzIISLEnlcLQKez84QOXluzPx4d8zyMLuMNgR9L2o=; h=From:Content-type:MIME-version:Date:Subject:Message-id:To; b=aAu62m38YFYs4YXhQoPqETU96NdDylahfoY1ZAx529ggdQacLvioPDTlCHaw8DLt4 e4CMF/TDJMaqxVtqXm2JEhdIOYqvSRWSsWgX5z9IAZfYwPeAXft2XvqjantjYG5SEJ mXHJoH7GXPYzEBlTwqdYpw+4M01dI71qf68d4Oi1c7mFQ+K0f0AA6QouWoug/aNqpk 6KqKm85hfnE5+D4ccJ0FGuMqwLr8m23cmY2UHfro9wDI8tfA6vc/TJLBHKnc53nwAW yAPPr5+Mfy01EaH3sVwjFgDwZSFqRTpHoIPGTEJgp5j5D70xS4qmdryf+kj7Ubc+7C XTB9HVorSHz5A== 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-1810100035 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-10-09_14:,, signatures=0 In-reply-to: X-Mailer: iPhone Mail (16A366) Xref: news.gmane.org gmane.linux.lib.musl.general:13353 Archived-At: > On 10/10/2018, at 2:14 PM, Khem Raj wrote: >=20 >> On Tue, Oct 9, 2018 at 2:36 PM Michael Clark wrot= e: >>=20 >> Hi, >>=20 >> I have a status update. I haven=E2=80=99t made any changes to the musl po= rt since last week but I did investigate and fix the stat issue in qemu-risc= v32. I ran tests with riscv32 Linux kernel with glibc in QEMU full system em= ulation as Linux kernel is canonical for the ABI. >>=20 >> riscv32 is 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-bi= t ports which confused me a bit). It does not have fstat64 and its stat stru= cture matches rv64. I=E2=80=99m kind of stubborn so I had to see the test pa= ss/fail so I spent some time getting riscv32 linux to build. I should submit= a couple of small patches for riscv-linux. >>=20 >> I fixed riscv32 stat in riscv-qemu: https://github.com/riscv/riscv-qemu >>=20 >> RISC-V QEMU had the 32-bit asm-generic which has a 32-bit stat, but no fs= tat64. We may have missed a chunk when we rebased the 2016 riscv-qemu baseli= ne. The stat patch is in qemu-for-upstream branch in the riscv-qemu branch. >>=20 >> We need to work on getting our QEMU changes upstream. We have problems wi= th getting code into upstream QEMU as they have very strict code review poli= cy on pull requests. Every commit must have =E2=80=9CReviewed-by:=E2=80=9D w= ith a =E2=80=9Ctrusted reviewer=E2=80=9D. It doesn=E2=80=99t seem to prevent= changes coming from Linaro breaking the RISC-V port but it does prevent our= fixes going in. My current focus is working on automated test cases for the= fixes in the QEMU queue so we can change the discourse to does it pass an e= xtensive set of tests. Currently the baseline for inclusion is does it compi= le and passes =E2=80=9Cmake check=E2=80=9D, have Reviewed-by and Signed-off-= by tags and does it conform to the QEMU coding style (checkpatch.pl). The is= sue is we are making changes that typically require reading the Privileged I= SA manual for verification and we don=E2=80=99t have high test case coverage= for the Privileged ISA. The Base ISA has pretty good test coverage. >>=20 >> I would be happy if someone volunteered to help with the RISC-V musl port= ... >=20 > Thanks Michael, its on my TODO list after ELCE, I have setup OE builds > already, but need to cherry-pick your patches and test a > core-image-minimal to start the process. Awesome! Thanks. I=E2=80=99ve squashed everything to make it easy to cherry-pick (a habit for= work-in-progress code). There was a bit of patch churn during some testing a= nd alignment with glibc/Linux. I tend to squash patch churn like this; when m= oving between trees. Fortunately it is easy with musl=E2=80=99s layout becau= se it is pretty much restricted to arch/riscv32 and arch/riscv64 Of course for changes this approach can make it harder for reviewers. I actu= ally think GitHub adds some value here. I like to see the code as a whole, n= ot as a context diff. It can be split appropriately when the time comes. It does make one consider= our view of history. Fortunately I think we are in the hands of good custod= ians... Hopefully we don=E2=80=99t have to split it up into 100 different patches. M= aybe we will. Who knows... I haven=E2=80=99t actually checked the whitespace= is conforming or not. >> Michael >>=20 >> 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: >>=20 >> On Thu, Sep 27, 2018 at 10:24:04PM -0400, Rich Felker wrote: >>=20 >> Pulled from here: >>=20 >> https://github.com/riscv/riscv-musl/commit/6a4f4a9c774608add4b02f95322518= bd2f5f51ee >>=20 >>=20 >> Attached for review. >>=20 >>=20 >> Review inline below: >>=20 >>=20 >> diff --git a/arch/riscv32/atomic_arch.h b/arch/riscv32/atomic_arch.h >>=20 >> new file mode 100644 >>=20 >> index 0000000..93c89cc >>=20 >> --- /dev/null >>=20 >> +++ b/arch/riscv32/atomic_arch.h >>=20 >> @@ -0,0 +1,35 @@ >>=20 >> +#define a_barrier a_barrier >>=20 >> +static inline void a_barrier() >>=20 >> +{ >>=20 >> + __asm__ __volatile__ ("fence rw,rw" : : : "memory"); >>=20 >> +} >>=20 >> + >>=20 >> +#define a_ll a_ll >>=20 >> +static inline int a_ll(volatile int *p) >>=20 >> +{ >>=20 >> + int v; >>=20 >> + __asm__ __volatile__ ("lr.w %0, (%1)" : "=3D&r"(v) : "r"(p)); >>=20 >> + return v; >>=20 >> +} >>=20 >> + >>=20 >> +#define a_sc a_sc >>=20 >> +static inline int a_sc(volatile int *p, int v) >>=20 >> +{ >>=20 >> + int r; >>=20 >> + __asm__ __volatile__ ("sc.w %0, %2, (%1)" : "=3D&r"(r) : "r"(p), "r"= (v) : "memory"); >>=20 >> + return !r; >>=20 >> +} >>=20 >> + >>=20 >> +#define a_cas a_cas >>=20 >> +static inline int a_cas(volatile int *p, int t, int s) >>=20 >> +{ >>=20 >> + int old, tmp; >>=20 >> + __asm__("1: lr.w %0, %2 \n" >>=20 >> + " bne %0, %3, 1f \n" >>=20 >> + " sc.w %1, %4, %2 \n" >>=20 >> + " bnez %1, 1b \n" >>=20 >> + "1: \n" >>=20 >> + : "=3D&r"(old), "+r"(tmp), "+A"(*p) >>=20 >> + : "r"(t), "r"(s)); >>=20 >> + return old; >>=20 >> +} >>=20 >>=20 >> Why are both a_ll/a_sc and a_cas defined, and why is a_cas missing >>=20 >> barriers? Normally if a_ll/a_sc/a_barrier are defined, the top-level >>=20 >> atomic.h should be allowed to generate a_cas in terms of them. >>=20 >>=20 >> diff --git a/arch/riscv32/bits/signal.h b/arch/riscv32/bits/signal.h >>=20 >> new file mode 100644 >>=20 >> index 0000000..8b992cc >>=20 >> --- /dev/null >>=20 >> +++ b/arch/riscv32/bits/signal.h >>=20 >> @@ -0,0 +1,113 @@ >>=20 >> +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ >>=20 >> + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURC= E) >>=20 >> + >>=20 >> +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURC= E) >>=20 >> +# define MINSIGSTKSZ 2048 >>=20 >> +# define SIGSTKSZ 8192 >>=20 >> +#endif >>=20 >> + >>=20 >> +/* gregs[0] holds the program counter. */ >>=20 >> + >>=20 >> +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) >>=20 >> +typedef unsigned long greg_t; >>=20 >> +typedef unsigned long gregset_t[32]; >>=20 >> + >>=20 >> +struct __riscv_f_ext_state { >>=20 >> + unsigned int f[32]; >>=20 >> + unsigned int fcsr; >>=20 >> +}; >>=20 >> + >>=20 >> +struct __riscv_d_ext_state { >>=20 >> + unsigned long long f[32]; >>=20 >> + unsigned int fcsr; >>=20 >> +}; >>=20 >> + >>=20 >> +struct __riscv_q_ext_state { >>=20 >> + unsigned long long f[64] __attribute__((aligned(16))); >>=20 >> + unsigned int fcsr; >>=20 >> + unsigned int reserved[3]; >>=20 >> +}; >>=20 >> + >>=20 >> +union __riscv_fp_state { >>=20 >> + struct __riscv_f_ext_state f; >>=20 >> + struct __riscv_d_ext_state d; >>=20 >> + struct __riscv_q_ext_state q; >>=20 >> +}; >>=20 >> + >>=20 >> +typedef union __riscv_fp_state fpregset_t; >>=20 >> + >>=20 >> +typedef struct sigcontext { >>=20 >> + gregset_t gregs; >>=20 >> + fpregset_t fpregs; >>=20 >> +} mcontext_t; >>=20 >> + >>=20 >> +#else >>=20 >> +typedef struct { >>=20 >> + unsigned long gregs[32]; >>=20 >> + unsigned long long fpregs[66]; >>=20 >> +} mcontext_t; >>=20 >> +#endif >>=20 >>=20 >> In the namespace-safe version of mcontext_t, the names gregs and >>=20 >> fpregs are not valid here. They would need to be __-prefixed or in >>=20 >> some other reserved namespace. >>=20 >>=20 >> +struct sigaltstack { >>=20 >> + void *ss_sp; >>=20 >> + int ss_flags; >>=20 >> + size_t ss_size; >>=20 >> +}; >>=20 >> + >>=20 >> +typedef struct __ucontext >>=20 >> +{ >>=20 >> + unsigned long uc_flags; >>=20 >> + struct __ucontext *uc_link; >>=20 >> + stack_t uc_stack; >>=20 >> + sigset_t uc_sigmask; >>=20 >> + char __unused[1024 / 8 - sizeof(sigset_t)]; >>=20 >>=20 >> This is an invalid array of size zero and should just be removed. >>=20 >>=20 >> + mcontext_t uc_mcontext; >>=20 >> +} ucontext_t; >>=20 >>=20 >> .... >>=20 >>=20 >> diff --git a/arch/riscv32/crt_arch.h b/arch/riscv32/crt_arch.h >>=20 >> new file mode 100644 >>=20 >> index 0000000..65187e1 >>=20 >> --- /dev/null >>=20 >> +++ b/arch/riscv32/crt_arch.h >>=20 >> @@ -0,0 +1,18 @@ >>=20 >> +__asm__( >>=20 >> +".text\n" >>=20 >> +".global " START "\n" >>=20 >> +".type " START ",%function\n" >>=20 >> +START ":\n" >>=20 >> +".weak __global_pointer$\n" >>=20 >> +".hidden __global_pointer$\n\t" >>=20 >> +".option push\n" >>=20 >> +".option norelax\n\t" >>=20 >> +"lla gp, __global_pointer$\n" >>=20 >> +".option pop\n\t" >>=20 >> +"mv a0, sp\n" >>=20 >> +".weak _DYNAMIC\n" >>=20 >> +".hidden _DYNAMIC\n\t" >>=20 >> +"lla a1, _DYNAMIC\n\t" >>=20 >> +"andi sp, sp, -16\n\t" >>=20 >> +"jal " START "_c" >>=20 >> +); >>=20 >> diff --git a/arch/riscv32/pthread_arch.h b/arch/riscv32/pthread_arch.h >>=20 >> new file mode 100644 >>=20 >> index 0000000..feffaa4 >>=20 >> --- /dev/null >>=20 >> +++ b/arch/riscv32/pthread_arch.h >>=20 >> @@ -0,0 +1,12 @@ >>=20 >> +static inline struct pthread *__pthread_self() >>=20 >> +{ >>=20 >> + char *tp; >>=20 >> + __asm__ __volatile__("mv %0, tp" : "=3Dr"(tp)); >>=20 >> + return (void *)(tp - sizeof(struct pthread)); >>=20 >> +} >>=20 >> + >>=20 >> +#define TLS_ABOVE_TP >>=20 >> +#define GAP_ABOVE_TP 0 >>=20 >> +#define TP_ADJ(p) ((char *)p + sizeof(struct pthread)) >>=20 >> + >>=20 >> +#define MC_PC gregs[0] >>=20 >> diff --git a/arch/riscv32/reloc.h b/arch/riscv32/reloc.h >>=20 >> new file mode 100644 >>=20 >> index 0000000..d057bbe >>=20 >> --- /dev/null >>=20 >> +++ b/arch/riscv32/reloc.h >>=20 >> @@ -0,0 +1,27 @@ >>=20 >> +#if defined __riscv_float_abi_soft >>=20 >> +#define RISCV_FP_SUFFIX "-sf" >>=20 >> +#elif defined __riscv_float_abi_single >>=20 >> +#define RISCV_FP_SUFFIX "-sp" >>=20 >> +#elif defined __riscv_float_abi_double >>=20 >> +#define RISCV_FP_SUFFIX "" >>=20 >> +#endif >>=20 >> + >>=20 >> +#define RISCV_LDSO_HELPER(x) "riscv" #x >>=20 >> +#define RISCV_LDSO(x) RISCV_LDSO_HELPER(x) >>=20 >> + >>=20 >> +#define LDSO_ARCH RISCV_LDSO(__riscv_xlen) RISCV_FP_SUFFIX >>=20 >>=20 >> Elsewhere it looks like little/big endian are both options, but I see >>=20 >> no endian variant here. If so this needs to be fixed. >>=20 >>=20 >> Also what is __riscv_xlen? A predefined macro that expands to 32 or >>=20 >> 64? Since this file is just for 32-bit it should just be hard-coded >>=20 >> rather than assuming a macro would expand to the token 32 and not >>=20 >> (31+1) or some other expression equal to 32, I think. >>=20 >>=20 >> diff --git a/arch/riscv32/syscall_arch.h b/arch/riscv32/syscall_arch.h >>=20 >> new file mode 100644 >>=20 >> index 0000000..bc60d1f >>=20 >> --- /dev/null >>=20 >> +++ b/arch/riscv32/syscall_arch.h >>=20 >> @@ -0,0 +1,78 @@ >>=20 >> +#define __SYSCALL_LL_E(x) \ >>=20 >> +((union { long long ll; long l[2]; }){ .ll =3D x }).l[0], \ >>=20 >> +((union { long long ll; long l[2]; }){ .ll =3D x }).l[1] >>=20 >> +#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x)) >>=20 >> + >>=20 >> +#define __asm_syscall(...) \ >>=20 >> + __asm__ __volatile__ ("scall\n\t" \ >>=20 >> + : "+r"(a0) : __VA_ARGS__ : "memory"); \ >>=20 >> + return a0; \ >>=20 >> + >>=20 >> +static inline long __syscall0(long n) >>=20 >> +{ >>=20 >> + register long a7 __asm__("a7") =3D n; >>=20 >> + register long a0 __asm__("a0"); >>=20 >> + __asm_syscall("r"(a7)) >>=20 >> +} >>=20 >> + >>=20 >> +static inline long __syscall1(long n, long a) >>=20 >> +{ >>=20 >> + register long a7 __asm__("a7") =3D n; >>=20 >> + register long a0 __asm__("a0") =3D a; >>=20 >> + __asm_syscall("r"(a7), "0"(a0)) >>=20 >> +} >>=20 >> + >>=20 >> +static inline long __syscall2(long n, long a, long b) >>=20 >> +{ >>=20 >> + register long a7 __asm__("a7") =3D n; >>=20 >> + register long a0 __asm__("a0") =3D a; >>=20 >> + register long a1 __asm__("a1") =3D b; >>=20 >> + __asm_syscall("r"(a7), "0"(a0), "r"(a1)) >>=20 >> +} >>=20 >> + >>=20 >> +static inline long __syscall3(long n, long a, long b, long c) >>=20 >> +{ >>=20 >> + register long a7 __asm__("a7") =3D n; >>=20 >> + register long a0 __asm__("a0") =3D a; >>=20 >> + register long a1 __asm__("a1") =3D b; >>=20 >> + register long a2 __asm__("a2") =3D c; >>=20 >> + __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2)) >>=20 >> +} >>=20 >> + >>=20 >> +static inline long __syscall4(long n, long a, long b, long c, long d) >>=20 >> +{ >>=20 >> + register long a7 __asm__("a7") =3D n; >>=20 >> + register long a0 __asm__("a0") =3D a; >>=20 >> + register long a1 __asm__("a1") =3D b; >>=20 >> + register long a2 __asm__("a2") =3D c; >>=20 >> + register long a3 __asm__("a3") =3D d; >>=20 >> + __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3)) >>=20 >> +} >>=20 >> + >>=20 >> +static inline long __syscall5(long n, long a, long b, long c, long d, lo= ng e) >>=20 >> +{ >>=20 >> + register long a7 __asm__("a7") =3D n; >>=20 >> + register long a0 __asm__("a0") =3D a; >>=20 >> + register long a1 __asm__("a1") =3D b; >>=20 >> + register long a2 __asm__("a2") =3D c; >>=20 >> + register long a3 __asm__("a3") =3D d; >>=20 >> + register long a4 __asm__("a4") =3D e; >>=20 >> + __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4)) >>=20 >> +} >>=20 >> + >>=20 >> +static inline long __syscall6(long n, long a, long b, long c, long d, lo= ng e, long f) >>=20 >> +{ >>=20 >> + register long a7 __asm__("a7") =3D n; >>=20 >> + register long a0 __asm__("a0") =3D a; >>=20 >> + register long a1 __asm__("a1") =3D b; >>=20 >> + register long a2 __asm__("a2") =3D c; >>=20 >> + register long a3 __asm__("a3") =3D d; >>=20 >> + register long a4 __asm__("a4") =3D e; >>=20 >> + register long a5 __asm__("a5") =3D f; >>=20 >> + __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "= r"(a5)) >>=20 >> +} >>=20 >> + >>=20 >> +#define VDSO_USEFUL >>=20 >> +/* We don't have a clock_gettime function. >>=20 >> +#define VDSO_CGT_SYM "__vdso_clock_gettime" >>=20 >> +#define VDSO_CGT_VER "LINUX_2.6" */ >>=20 >>=20 >> In that case VDSO_USEFUL might as well also be omitted for now. >>=20 >>=20 >> diff --git a/arch/riscv64/atomic_arch.h b/arch/riscv64/atomic_arch.h >>=20 >> new file mode 100644 >>=20 >> index 0000000..018c7fd >>=20 >> --- /dev/null >>=20 >> +++ b/arch/riscv64/atomic_arch.h >>=20 >> @@ -0,0 +1,66 @@ >>=20 >> +#define a_barrier a_barrier >>=20 >> +static inline void a_barrier() >>=20 >> +{ >>=20 >> + __asm__ __volatile__ ("fence rw,rw" : : : "memory"); >>=20 >> +} >>=20 >> + >>=20 >> +#define a_ll a_ll >>=20 >> +static inline int a_ll(volatile int *p) >>=20 >> +{ >>=20 >> + int v; >>=20 >> + __asm__ __volatile__ ("lr.w %0, %1" : "=3D&r"(v), "+A"(*p)); >>=20 >> + return v; >>=20 >> +} >>=20 >> + >>=20 >> +#define a_sc a_sc >>=20 >> +static inline int a_sc(volatile int *p, int v) >>=20 >> +{ >>=20 >> + int r; >>=20 >> + __asm__ __volatile__ ("sc.w %0, %2, %1" : "=3D&r"(r), "+A"(*p) : "r"= (v) : "memory"); >>=20 >> +return !r; >>=20 >> +} >>=20 >> + >>=20 >> +#define a_cas a_cas >>=20 >> +static inline int a_cas(volatile int *p, int t, int s) >>=20 >> +{ >>=20 >> + int old, tmp; >>=20 >> + __asm__("1: lr.w %0, %2 \n" >>=20 >> + " bne %0, %3, 1f \n" >>=20 >> + " sc.w %1, %4, %2 \n" >>=20 >> + " bnez %1, 1b \n" >>=20 >> + "1: \n" >>=20 >> + : "=3D&r"(old), "+r"(tmp), "+A"(*p) >>=20 >> + : "r"(t), "r"(s)); >>=20 >> + return old; >>=20 >> +} >>=20 >> + >>=20 >> +#define a_ll_p a_ll_p >>=20 >> +static inline void *a_ll_p(volatile void *p) >>=20 >> +{ >>=20 >> + void *v; >>=20 >> + __asm__ __volatile__ ("lr.d %0, %1" : "=3D&r"(v), "+A"(*(long *)p));= >>=20 >> + return v; >>=20 >> +} >>=20 >> + >>=20 >> +#define a_sc_p a_sc_p >>=20 >> +static inline int a_sc_p(volatile int *p, void *v) >>=20 >> +{ >>=20 >> + int r; >>=20 >> + __asm__ __volatile__ ("sc.d %0, %2, %1" : "=3D&r"(r), "+A"(*(long *)= p) : "r"(v) : "memory"); >>=20 >> + return !r; >>=20 >> +} >>=20 >> + >>=20 >> +#define a_cas_p a_cas_p >>=20 >> +static inline void *a_cas_p(volatile void *p, void *t, void *s) >>=20 >> +{ >>=20 >> + void *old; >>=20 >> + int tmp; >>=20 >> + __asm__("1: lr.d %0, %2 \n" >>=20 >> + " bne %0, %3, 1f \n" >>=20 >> + " sc.d %1, %4, %2 \n" >>=20 >> + " bnez %1, 1b \n" >>=20 >> + "1: \n" >>=20 >> + : "=3D&r"(old), "+r"(tmp), "+A"(*(long *)p) >>=20 >> + : "r"(t), "r"(s)); >>=20 >> + return old; >>=20 >> +} >>=20 >>=20 >> Same comments about cas vs ll/sc, and lack of barrier, as 32-bit version.= >>=20 >>=20 >> diff --git a/arch/riscv64/bits/signal.h b/arch/riscv64/bits/signal.h >>=20 >> new file mode 100644 >>=20 >> index 0000000..8b992cc >>=20 >> --- /dev/null >>=20 >> +++ b/arch/riscv64/bits/signal.h >>=20 >> @@ -0,0 +1,113 @@ >>=20 >> +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ >>=20 >> + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURC= E) >>=20 >> + >>=20 >> +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURC= E) >>=20 >> +# define MINSIGSTKSZ 2048 >>=20 >> +# define SIGSTKSZ 8192 >>=20 >> +#endif >>=20 >> + >>=20 >> +/* gregs[0] holds the program counter. */ >>=20 >> + >>=20 >> +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) >>=20 >> +typedef unsigned long greg_t; >>=20 >> +typedef unsigned long gregset_t[32]; >>=20 >> + >>=20 >> +struct __riscv_f_ext_state { >>=20 >> + unsigned int f[32]; >>=20 >> + unsigned int fcsr; >>=20 >> +}; >>=20 >> + >>=20 >> +struct __riscv_d_ext_state { >>=20 >> + unsigned long long f[32]; >>=20 >> + unsigned int fcsr; >>=20 >> +}; >>=20 >> + >>=20 >> +struct __riscv_q_ext_state { >>=20 >> + unsigned long long f[64] __attribute__((aligned(16))); >>=20 >> + unsigned int fcsr; >>=20 >> + unsigned int reserved[3]; >>=20 >> +}; >>=20 >> + >>=20 >> +union __riscv_fp_state { >>=20 >> + struct __riscv_f_ext_state f; >>=20 >> + struct __riscv_d_ext_state d; >>=20 >> + struct __riscv_q_ext_state q; >>=20 >> +}; >>=20 >> + >>=20 >> +typedef union __riscv_fp_state fpregset_t; >>=20 >> + >>=20 >> +typedef struct sigcontext { >>=20 >> + gregset_t gregs; >>=20 >> + fpregset_t fpregs; >>=20 >> +} mcontext_t; >>=20 >> + >>=20 >> +#else >>=20 >> +typedef struct { >>=20 >> + unsigned long gregs[32]; >>=20 >> + unsigned long long fpregs[66]; >>=20 >> +} mcontext_t; >>=20 >> +#endif >>=20 >> + >>=20 >> +struct sigaltstack { >>=20 >> + void *ss_sp; >>=20 >> + int ss_flags; >>=20 >> + size_t ss_size; >>=20 >> +}; >>=20 >> + >>=20 >> +typedef struct __ucontext >>=20 >> +{ >>=20 >> + unsigned long uc_flags; >>=20 >> + struct __ucontext *uc_link; >>=20 >> + stack_t uc_stack; >>=20 >> + sigset_t uc_sigmask; >>=20 >> + char __unused[1024 / 8 - sizeof(sigset_t)]; >>=20 >> + mcontext_t uc_mcontext; >>=20 >> +} ucontext_t; >>=20 >>=20 >> Same issues here as 32-bit. >>=20 >>=20 >> diff --git a/arch/riscv64/reloc.h b/arch/riscv64/reloc.h >>=20 >> new file mode 100644 >>=20 >> index 0000000..8bd90dd >>=20 >> --- /dev/null >>=20 >> +++ b/arch/riscv64/reloc.h >>=20 >> @@ -0,0 +1,27 @@ >>=20 >> +#if defined __riscv_float_abi_soft >>=20 >> +#define RISCV_FP_SUFFIX "-sf" >>=20 >> +#elif defined __riscv_float_abi_single >>=20 >> +#define RISCV_FP_SUFFIX "-sp" >>=20 >> +#elif defined __riscv_float_abi_double >>=20 >> +#define RISCV_FP_SUFFIX "" >>=20 >> +#endif >>=20 >> + >>=20 >> +#define RISCV_LDSO_HELPER(x) "riscv" #x >>=20 >> +#define RISCV_LDSO(x) RISCV_LDSO_HELPER(x) >>=20 >> + >>=20 >> +#define LDSO_ARCH RISCV_LDSO(__riscv_xlen) RISCV_FP_SUFFIX >>=20 >>=20 >> Same here. >>=20 >>=20 >> diff --git a/configure b/configure >>=20 >> index 997e665..4d3d8b4 100755 >>=20 >> --- a/configure >>=20 >> +++ b/configure >>=20 >> @@ -322,6 +322,8 @@ microblaze*) ARCH=3Dmicroblaze ;; >>=20 >> or1k*) ARCH=3Dor1k ;; >>=20 >> powerpc64*) ARCH=3Dpowerpc64 ;; >>=20 >> powerpc*) ARCH=3Dpowerpc ;; >>=20 >> +riscv64*) ARCH=3Driscv64 ;; >>=20 >> +riscv*) ARCH=3Driscv32 ;; >>=20 >> sh[1-9bel-]*|sh|superh*) ARCH=3Dsh ;; >>=20 >> s390x*) ARCH=3Ds390x ;; >>=20 >> unknown) fail "$0: unable to detect target arch; try $0 --target=3D..." ;= ; >>=20 >> @@ -640,6 +642,11 @@ trycppif __LITTLE_ENDIAN__ "$t" && SUBARCH=3D${SUBAR= CH}le >>=20 >> trycppif _SOFT_FLOAT "$t" && fail "$0: error: soft-float not supported on= powerpc64" >>=20 >> fi >>=20 >>=20 >> +if test "$ARCH" =3D "riscv" || test "$ARCH" =3D "riscv64" ; then >>=20 >> +trycppif "RISCVEB || _RISCVEB || __RISCVEB || __RISCVEB__" "$t" && SUBAR= CH=3D${SUBARCH}eb >>=20 >>=20 >> Predefined macros that violate the namespace (RISCVEB) shouldn't be >>=20 >> defined or observed. >>=20 >>=20 >> +trycppif __riscv_soft_float "$t" && SUBARCH=3D${SUBARCH}-sf >>=20 >> +fi >>=20 >> + >>=20 >> if test "$ARCH" =3D "sh" ; then >>=20 >> tryflag CFLAGS_AUTO -Wa,--isa=3Dany >>=20 >> trycppif __BIG_ENDIAN__ "$t" && SUBARCH=3D${SUBARCH}eb >>=20 >> diff --git a/crt/riscv32/crti.s b/crt/riscv32/crti.s >>=20 >> new file mode 100644 >>=20 >> index 0000000..6916bfd >>=20 >> --- /dev/null >>=20 >> +++ b/crt/riscv32/crti.s >>=20 >> @@ -0,0 +1,11 @@ >>=20 >> +.section .init >>=20 >> +.global _init >>=20 >> +.type _init,%function >>=20 >> +_init: >>=20 >> + ret >>=20 >> + >>=20 >> +.section .fini >>=20 >> +.global _fini >>=20 >> +.type _fini,%function >>=20 >> +_fini: >>=20 >> + ret >>=20 >> diff --git a/crt/riscv32/crtn.s b/crt/riscv32/crtn.s >>=20 >> new file mode 100644 >>=20 >> index 0000000..e69de29 >>=20 >>=20 >> It looks like these are not used, right? >>=20 >>=20 >> diff --git a/include/elf.h b/include/elf.h >>=20 >> index c229735..ec2e8fd 100644 >>=20 >> --- a/include/elf.h >>=20 >> +++ b/include/elf.h >>=20 >> @@ -3164,6 +3164,62 @@ enum >>=20 >> #define R_BPF_NONE 0 >>=20 >> #define R_BPF_MAP_FD 1 >>=20 >>=20 >> +#define R_RISCV_NONE 0 >>=20 >> +#define R_RISCV_32 1 >>=20 >> +#define R_RISCV_64 2 >>=20 >> +#define R_RISCV_RELATIVE 3 >>=20 >> +#define R_RISCV_COPY 4 >>=20 >> +#define R_RISCV_JUMP_SLOT 5 >>=20 >> +#define R_RISCV_TLS_DTPMOD32 6 >>=20 >> +#define R_RISCV_TLS_DTPMOD64 7 >>=20 >> +#define R_RISCV_TLS_DTPREL32 8 >>=20 >> +#define R_RISCV_TLS_DTPREL64 9 >>=20 >> +#define R_RISCV_TLS_TPREL32 10 >>=20 >> +#define R_RISCV_TLS_TPREL64 11 >>=20 >> + >>=20 >> +#define R_RISCV_BRANCH 16 >>=20 >> +#define R_RISCV_JAL 17 >>=20 >> +#define R_RISCV_CALL 18 >>=20 >> +#define R_RISCV_CALL_PLT 19 >>=20 >> +#define R_RISCV_GOT_HI20 20 >>=20 >> +#define R_RISCV_TLS_GOT_HI20 21 >>=20 >> +#define R_RISCV_TLS_GD_HI20 22 >>=20 >> +#define R_RISCV_PCREL_HI20 23 >>=20 >> +#define R_RISCV_PCREL_LO12_I 24 >>=20 >> +#define R_RISCV_PCREL_LO12_S 25 >>=20 >> +#define R_RISCV_HI20 26 >>=20 >> +#define R_RISCV_LO12_I 27 >>=20 >> +#define R_RISCV_LO12_S 28 >>=20 >> +#define R_RISCV_TPREL_HI20 29 >>=20 >> +#define R_RISCV_TPREL_LO12_I 30 >>=20 >> +#define R_RISCV_TPREL_LO12_S 31 >>=20 >> +#define R_RISCV_TPREL_ADD 32 >>=20 >> +#define R_RISCV_ADD8 33 >>=20 >> +#define R_RISCV_ADD16 34 >>=20 >> +#define R_RISCV_ADD32 35 >>=20 >> +#define R_RISCV_ADD64 36 >>=20 >> +#define R_RISCV_SUB8 37 >>=20 >> +#define R_RISCV_SUB16 38 >>=20 >> +#define R_RISCV_SUB32 39 >>=20 >> +#define R_RISCV_SUB64 40 >>=20 >> +#define R_RISCV_GNU_VTINHERIT 41 >>=20 >> +#define R_RISCV_GNU_VTENTRY 42 >>=20 >> +#define R_RISCV_ALIGN 43 >>=20 >> +#define R_RISCV_RVC_BRANCH 44 >>=20 >> +#define R_RISCV_RVC_JUMP 45 >>=20 >> +#define R_RISCV_RVC_LUI 46 >>=20 >> +#define R_RISCV_GPREL_I 47 >>=20 >> +#define R_RISCV_GPREL_S 48 >>=20 >> +#define R_RISCV_TPREL_I 49 >>=20 >> +#define R_RISCV_TPREL_S 50 >>=20 >> +#define R_RISCV_RELAX 51 >>=20 >> +#define R_RISCV_SUB6 52 >>=20 >> +#define R_RISCV_SET6 53 >>=20 >> +#define R_RISCV_SET8 54 >>=20 >> +#define R_RISCV_SET16 55 >>=20 >> +#define R_RISCV_SET32 56 >>=20 >> +#define R_RISCV_32_PCREL 57 >>=20 >> + >>=20 >> #ifdef __cplusplus >>=20 >> } >>=20 >> #endif >>=20 >>=20 >> This should be its own patch independent of the port; I can commit it >>=20 >> earlier. >>=20 >>=20 >> diff --git a/src/thread/riscv32/syscall_cp.s b/src/thread/riscv32/syscall= _cp.s >>=20 >> new file mode 100644 >>=20 >> index 0000000..71bf6d3 >>=20 >> --- /dev/null >>=20 >> +++ b/src/thread/riscv32/syscall_cp.s >>=20 >> @@ -0,0 +1,29 @@ >>=20 >> +.global __cp_begin >>=20 >> +.hidden __cp_begin >>=20 >> +.global __cp_end >>=20 >> +.hidden __cp_end >>=20 >> +.global __cp_cancel >>=20 >> +.hidden __cp_cancel >>=20 >> +.hidden __cancel >>=20 >> +.global __syscall_cp_asm >>=20 >> +.hidden __syscall_cp_asm >>=20 >> +.type __syscall_cp_asm, %function >>=20 >> +__syscall_cp_asm: >>=20 >> +__cp_begin: >>=20 >> + lw t0, 0(a0) >>=20 >> + bnez t0, __cp_cancel >>=20 >> + >>=20 >> + mv t0, a1 >>=20 >> + mv a0, a2 >>=20 >> + mv a1, a3 >>=20 >> + mv a2, a4 >>=20 >> + mv a3, a5 >>=20 >> + mv a4, a6 >>=20 >> + mv a5, a7 >>=20 >> + lw a6, 0(sp) >>=20 >> + mv a7, t0 >>=20 >> + scall >>=20 >> +__cp_cancel: >>=20 >> + ret >>=20 >> +__cp_end: >>=20 >> + j __cancel >>=20 >>=20 >> The labels here are backwards. __cp_end must point immediately after >>=20 >> the syscall instruction, and __cp_end needs to jump to __cancel. >>=20 >>=20 >> diff --git a/src/thread/riscv64/syscall_cp.s b/src/thread/riscv64/syscall= _cp.s >>=20 >> new file mode 100644 >>=20 >> index 0000000..c745b32 >>=20 >> --- /dev/null >>=20 >> +++ b/src/thread/riscv64/syscall_cp.s >>=20 >> @@ -0,0 +1,29 @@ >>=20 >> +.global __cp_begin >>=20 >> +.hidden __cp_begin >>=20 >> +.global __cp_end >>=20 >> +.hidden __cp_end >>=20 >> +.global __cp_cancel >>=20 >> +.hidden __cp_cancel >>=20 >> +.hidden __cancel >>=20 >> +.global __syscall_cp_asm >>=20 >> +.hidden __syscall_cp_asm >>=20 >> +.type __syscall_cp_asm, %function >>=20 >> +__syscall_cp_asm: >>=20 >> +__cp_begin: >>=20 >> + ld t0, 0(a0) >>=20 >> + bnez t0, __cp_cancel >>=20 >> + >>=20 >> + mv t0, a1 >>=20 >> + mv a0, a2 >>=20 >> + mv a1, a3 >>=20 >> + mv a2, a4 >>=20 >> + mv a3, a5 >>=20 >> + mv a4, a6 >>=20 >> + mv a5, a7 >>=20 >> + ld a6, 0(sp) >>=20 >> + mv a7, t0 >>=20 >> + scall >>=20 >> +__cp_cancel: >>=20 >> + ret >>=20 >> +__cp_end: >>=20 >> + j __cancel >>=20 >> -- >>=20 >> 2.10.0 >>=20 >>=20 >>=20 >> Likewise here. >>=20 >>=20 >> Rich