diff options
Diffstat (limited to 'lib/libc/arm/gen')
25 files changed, 1840 insertions, 0 deletions
diff --git a/lib/libc/arm/gen/Makefile.inc b/lib/libc/arm/gen/Makefile.inc new file mode 100644 index 000000000000..dfb83da20a1f --- /dev/null +++ b/lib/libc/arm/gen/Makefile.inc @@ -0,0 +1,33 @@ +SRCS+= \ + __aeabi_read_tp.S \ + _ctx_start.S \ + _setjmp.S \ + alloca.S \ + arm_initfini.c \ + arm_drain_writebuf.c \ + arm_sync_icache.c \ + fabs.c \ + flt_rounds.c \ + getcontextx.c \ + infinity.c \ + ldexp.c \ + makecontext.c \ + setjmp.S \ + signalcontext.c \ + sigsetjmp.S \ + +MAN+= \ + arm_drain_writebuf.2 \ + arm_sync_icache.2 \ + +.if !defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "" + +SRCS+= \ + fpgetmask_vfp.c \ + fpgetround_vfp.c \ + fpgetsticky_vfp.c \ + fpsetmask_vfp.c \ + fpsetround_vfp.c \ + fpsetsticky_vfp.c \ + +.endif diff --git a/lib/libc/arm/gen/__aeabi_read_tp.S b/lib/libc/arm/gen/__aeabi_read_tp.S new file mode 100644 index 000000000000..066d92e2e956 --- /dev/null +++ b/lib/libc/arm/gen/__aeabi_read_tp.S @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2012 Oleksandr Tymoshenko + * Copyright (c) 2012 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/asm.h> +#include <machine/sysarch.h> + +ENTRY(__aeabi_read_tp) + mrc p15, 0, r0, c13, c0, 3 + RET +END(__aeabi_read_tp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/_ctx_start.S b/lib/libc/arm/gen/_ctx_start.S new file mode 100644 index 000000000000..cd8d25b9e583 --- /dev/null +++ b/lib/libc/arm/gen/_ctx_start.S @@ -0,0 +1,11 @@ +#include <machine/asm.h> + +ENTRY(_ctx_start) + mov lr, pc + mov pc, r4 + mov r0, r5 + bl _C_LABEL(ctx_done) + bl _C_LABEL(abort) +END(_ctx_start) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/_setjmp.S b/lib/libc/arm/gen/_setjmp.S new file mode 100644 index 000000000000..9e655d2e9e2e --- /dev/null +++ b/lib/libc/arm/gen/_setjmp.S @@ -0,0 +1,135 @@ +/* $NetBSD: _setjmp.S,v 1.12 2013/04/19 13:45:45 matt Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__ARM_PCS) +#error FPA is not supported anymore +#endif + +#if !defined(_STANDALONE) + .fpu vfp +#endif + +#include <machine/asm.h> +#include <machine/setjmp.h> +/* + * C library -- _setjmp, _longjmp + * + * _longjmp(a,v) + * will generate a "return(v)" from the last call to + * _setjmp(a) + * by restoring registers from the stack. + * The previous signal state is NOT restored. + * + * Note: r0 is the return value + * r1-r3,ip are scratch registers in functions + */ + +ENTRY(_setjmp) + ldr r1, .L_setjmp_magic + +#if !defined(_STANDALONE) && !defined(SOFTFLOAT_FOR_GCC) + add r2, r0, #(_JB_REG_D8 * 4) + vstmia r2, {d8-d15} + vmrs r2, fpscr + str r2, [r0, #(_JB_REG_FPSCR * 4)] +#endif /* !_STANDALONE && !SOFTFLOAT_FOR_GCC */ + + str r1, [r0] + + add r0, r0, #(_JB_REG_R4 * 4) + /* Store integer registers */ +#ifndef __thumb__ + stmia r0, {r4-r14} +#else + stmia r0, {r4-r12} + str r13, [r0, #((_JB_REG_R13 - _JB_REG_R4) * 4)] + str r14, [r0, #((_JB_REG_R14 - _JB_REG_R4) * 4)] +#endif + + mov r0, #0x00000000 + RET +END(_setjmp) + +.L_setjmp_magic: + .word _JB_MAGIC__SETJMP + +WEAK_ALIAS(___longjmp, _longjmp) +ENTRY(_longjmp) + ldr r2, [r0] /* get magic from jmp_buf */ + ldr ip, .L_setjmp_magic /* load magic */ + teq ip, r2 /* magic correct? */ + bne botch /* no, botch */ + +#if !defined(_STANDALONE) && !defined(SOFTFLOAT_FOR_GCC) + add ip, r0, #(_JB_REG_D8 * 4) + vldmia ip, {d8-d15} + ldr ip, [r0, #(_JB_REG_FPSCR * 4)] + vmsr fpscr, ip +#endif /* !_STANDALONE && !SOFTFLOAT_FOR_GCC */ + + add r0, r0, #(_JB_REG_R4 * 4) + /* Restore integer registers */ +#ifndef __thumb__ + ldmia r0, {r4-r14} +#else + ldmia r0, {r4-r12} + ldr r13, [r0, #((_JB_REG_R13 - _JB_REG_R4) * 4)] + ldr r14, [r0, #((_JB_REG_R14 - _JB_REG_R4) * 4)] +#endif + + /* Validate sp and r14 */ + teq sp, #0 + it ne + teqne r14, #0 + it eq + beq botch + + /* Set return value */ + movs r0, r1 + it eq + moveq r0, #0x00000001 + RET + + /* validation failed, die die die. */ +botch: +#if !defined(_STANDALONE) + bl PIC_SYM(_C_LABEL(longjmperror), PLT) + bl PIC_SYM(_C_LABEL(abort), PLT) +1: b 1b /* Cannot get here */ +#else + b . +#endif +END(_longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/alloca.S b/lib/libc/arm/gen/alloca.S new file mode 100644 index 000000000000..3545cc642aad --- /dev/null +++ b/lib/libc/arm/gen/alloca.S @@ -0,0 +1,46 @@ +/* $NetBSD: alloca.S,v 1.3 2003/04/05 23:08:51 bjh21 Exp $ */ + +/* + * Copyright (c) 1995 Mark Brinicombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* like alloc, but automatic automatic free in return */ + +#include <machine/asm.h> +ENTRY(alloca) + add r0, r0, #0x00000007 /* round up to next 8 byte alignment */ + bic r0, r0, #0x00000007 + sub sp, sp, r0 /* Adjust the stack pointer */ + mov r0, sp /* r0 = base of new space */ + RET +END(alloca) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/arm_drain_writebuf.2 b/lib/libc/arm/gen/arm_drain_writebuf.2 new file mode 100644 index 000000000000..613c35d39ef2 --- /dev/null +++ b/lib/libc/arm/gen/arm_drain_writebuf.2 @@ -0,0 +1,75 @@ +.\" Copyright (c) 2019 Ian Lepore <ian@FreeBSD.org> +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd July 10, 2019 +.Dt ARM_DRAIN_WRITEBUF 2 +.Os +.Sh NAME +.Nm arm_drain_writebuf +.Nd drain pending writes from cores and caches +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In machine/sysarch.h +.Ft int +.Fn arm_drain_writebuf void +.Sh DESCRIPTION +The +.Nm +system call causes all pending writes from ARM cores and caches to be +written out to main memory or memory-mapped I/O registers. +Not all hardware supports buffered writes; on such systems the +.Nm +function is a no-op. +.Pp +On ARMv5 systems, this executes a cp15 coprocessor +.Dq drain write buffer +operation. +On ARMv6 and ARMv7 systems, this executes a +.Dq DSB SY +synchronization barrier, followed by an L2 cache drain on +systems where the DSB does not include L2 automatically. +.Pp +.Nm +attempts to wait for the drain operation to complete, but cannot +guarantee the writes have reached their ultimate destination on all hardware. +For example, on an ARMv7 system, +.Nm +tells the L2 cache controller to drain its buffers, and it waits until +the controller indicates that operation is complete. +However, all the L2 controller knows is that the data was accepted for +delivery by the AXI bus. +If the ultimate destination of the write is a device on a subordinate +bus connected to the AXI bus, more buffering or other delays may occur +on that subordinate bus. +The only way to be certain a pending write has reached its +ultimate destination is to issue a read from that destination after +.Nm +returns. +.Sh RETURN VALUES +The +.Nm +system call cannot fail, and always returns 0. +.Sh AUTHORS +This man page was written by +.An Ian Lepore . diff --git a/lib/libc/arm/gen/arm_drain_writebuf.c b/lib/libc/arm/gen/arm_drain_writebuf.c new file mode 100644 index 000000000000..30c93718bfe6 --- /dev/null +++ b/lib/libc/arm/gen/arm_drain_writebuf.c @@ -0,0 +1,36 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2019 Ian Lepore <ian@FreeBSD.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/sysarch.h> +#include <stddef.h> + +int +arm_drain_writebuf(void) +{ + sysarch(ARM_DRAIN_WRITEBUF, NULL); + return (0); +} diff --git a/lib/libc/arm/gen/arm_initfini.c b/lib/libc/arm/gen/arm_initfini.c new file mode 100644 index 000000000000..31756aa852a4 --- /dev/null +++ b/lib/libc/arm/gen/arm_initfini.c @@ -0,0 +1,77 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * Copyright (c) 2013 Andrew Turner + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Bases on NetBSD lib/libc/arch/arm/misc/arm_initfini.c + * $NetBSD: arm_initfini.c,v 1.2 2013/01/31 06:47:55 matt Exp $ + */ + +/* + * To properly implement setjmp/longjmp for the ARM AAPCS ABI, it has to be + * aware of whether there is a FPU is present or not. Regardless of whether + * the hard-float ABI is being used, setjmp needs to save D8-D15. But it can + * only do this if those instructions won't cause an exception. + */ + +#include <sys/param.h> +#include <sys/sysctl.h> + +#include <stdbool.h> +#include <stddef.h> + +extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen); + +int _libc_arm_fpu_present; +static bool _libc_aapcs_initialized; + +void _libc_aapcs_init(void) __attribute__((__constructor__, __used__)); + +void +_libc_aapcs_init(void) +{ + int mib[2]; + size_t len; + + if (_libc_aapcs_initialized) + return; + + mib[0] = CTL_HW; + mib[1] = HW_FLOATINGPT; + + len = sizeof(_libc_arm_fpu_present); + if (__sysctl(mib, 2, &_libc_arm_fpu_present, &len, NULL, 0) == -1 || + len != sizeof(_libc_arm_fpu_present)) { + /* sysctl failed, assume no vfp */ + _libc_arm_fpu_present = 0; + } + + _libc_aapcs_initialized = true; +} diff --git a/lib/libc/arm/gen/arm_sync_icache.2 b/lib/libc/arm/gen/arm_sync_icache.2 new file mode 100644 index 000000000000..c91904aa55d6 --- /dev/null +++ b/lib/libc/arm/gen/arm_sync_icache.2 @@ -0,0 +1,77 @@ +.\" Copyright (c) 2019 Ian Lepore <ian@FreeBSD.org> +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd July 10, 2019 +.Dt ARM_sync_icache 2 +.Os +.Sh NAME +.Nm arm_sync_icache +.Nd synchronize the data and instruction caches +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In machine/sysarch.h +.Ft int +.Fn arm_sync_icache "u_int addr" "int len" +.Sh DESCRIPTION +The +.Nm +system call synchronizes the contents of any data and instructions caches +with the contents of main memory for the given range. +Use this after loading executable code or modifying existing code in memory, +before attempting to execute that code. +.Pp +The +.Va addr +and +.Va len +arguments do not need to be aligned to any particular boundary, but +cache operations will affect entire cache lines, even those which are only +partially overlapped by the given range. +.Pp +This takes one or more of the following actions, depending on the requirements +of the hardware: +.Bl -bullet +.It +Write dirty data cache lines within the range back to main memory. +.It +Invalidate existing instruction cache contents for the range. +.It +Invalidate branch prediction caches for the range. +.El +.Pp +On hardware which supports multiple synchronization points for cache +operations, the caches are maintained to the point of unification, +making the data in the range coherent amongst all cores. +.Sh RETURN VALUES +The +.Nm +system call always returns 0. +.Sh ERRORS +If a call refers to memory which the calling process does not have rights +to access, or if the +.Va len +argument is negative, a SIGSEGV signal is delivered to the calling thread. +.Sh AUTHORS +This man page was written by +.An Ian Lepore . diff --git a/lib/libc/arm/gen/arm_sync_icache.c b/lib/libc/arm/gen/arm_sync_icache.c new file mode 100644 index 000000000000..b5872fb8ef00 --- /dev/null +++ b/lib/libc/arm/gen/arm_sync_icache.c @@ -0,0 +1,41 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2019 Ian Lepore <ian@FreeBSD.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <machine/sysarch.h> +#include <stddef.h> + +int +arm_sync_icache(u_int addr, int len) +{ + struct arm_sync_icache_args args; + + args.addr = addr; + args.len = len; + sysarch(ARM_SYNC_ICACHE, &args); + return (0); +} diff --git a/lib/libc/arm/gen/divsi3.S b/lib/libc/arm/gen/divsi3.S new file mode 100644 index 000000000000..9fddebaf96f3 --- /dev/null +++ b/lib/libc/arm/gen/divsi3.S @@ -0,0 +1,391 @@ +/* $NetBSD: divsi3.S,v 1.4 2003/04/05 23:27:15 bjh21 Exp $ */ + +/* + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/asm.h> +/* + * stack is aligned as there's a possibility of branching to L_overflow + * which makes a C call + */ + +ENTRY(__umodsi3) + stmfd sp!, {lr} + sub sp, sp, #4 /* align stack */ + bl .L_udivide + add sp, sp, #4 /* unalign stack */ + mov r0, r1 + ldmfd sp!, {pc} +END(__umodsi3) + +ENTRY(__modsi3) + stmfd sp!, {lr} + sub sp, sp, #4 /* align stack */ + bl .L_divide + add sp, sp, #4 /* unalign stack */ + mov r0, r1 + ldmfd sp!, {pc} + +.L_overflow: +#if !defined(_KERNEL) && !defined(_STANDALONE) + mov r0, #8 /* SIGFPE */ + bl PIC_SYM(_C_LABEL(raise), PLT) /* raise it */ + mov r0, #0 +#else + /* XXX should cause a fatal error */ + mvn r0, #0 +#endif + RET +END(__modsi3) + +ENTRY(__udivsi3) +.L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */ + eor r0, r1, r0 + eor r1, r0, r1 + eor r0, r1, r0 + /* r0 = r1 / r0; r1 = r1 % r0 */ + cmp r0, #1 + bcc .L_overflow + beq .L_divide_l0 + mov ip, #0 + movs r1, r1 + bpl .L_divide_l1 + orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */ + movs r1, r1, lsr #1 + orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */ + b .L_divide_l1 + +.L_divide_l0: /* r0 == 1 */ + mov r0, r1 + mov r1, #0 + RET +END(__udivsi3) + +ENTRY(__divsi3) +.L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */ + eor r0, r1, r0 + eor r1, r0, r1 + eor r0, r1, r0 + /* r0 = r1 / r0; r1 = r1 % r0 */ + cmp r0, #1 + bcc .L_overflow + beq .L_divide_l0 + ands ip, r0, #0x80000000 + rsbmi r0, r0, #0 + ands r2, r1, #0x80000000 + eor ip, ip, r2 + rsbmi r1, r1, #0 + orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */ + /* ip bit 0x80000000 = -ve remainder */ + +.L_divide_l1: + mov r2, #1 + mov r3, #0 + + /* + * If the highest bit of the dividend is set, we have to be + * careful when shifting the divisor. Test this. + */ + movs r1,r1 + bpl .L_old_code + + /* + * At this point, the highest bit of r1 is known to be set. + * We abuse this below in the tst instructions. + */ + tst r1, r0 /*, lsl #0 */ + bmi .L_divide_b1 + tst r1, r0, lsl #1 + bmi .L_divide_b2 + tst r1, r0, lsl #2 + bmi .L_divide_b3 + tst r1, r0, lsl #3 + bmi .L_divide_b4 + tst r1, r0, lsl #4 + bmi .L_divide_b5 + tst r1, r0, lsl #5 + bmi .L_divide_b6 + tst r1, r0, lsl #6 + bmi .L_divide_b7 + tst r1, r0, lsl #7 + bmi .L_divide_b8 + tst r1, r0, lsl #8 + bmi .L_divide_b9 + tst r1, r0, lsl #9 + bmi .L_divide_b10 + tst r1, r0, lsl #10 + bmi .L_divide_b11 + tst r1, r0, lsl #11 + bmi .L_divide_b12 + tst r1, r0, lsl #12 + bmi .L_divide_b13 + tst r1, r0, lsl #13 + bmi .L_divide_b14 + tst r1, r0, lsl #14 + bmi .L_divide_b15 + tst r1, r0, lsl #15 + bmi .L_divide_b16 + tst r1, r0, lsl #16 + bmi .L_divide_b17 + tst r1, r0, lsl #17 + bmi .L_divide_b18 + tst r1, r0, lsl #18 + bmi .L_divide_b19 + tst r1, r0, lsl #19 + bmi .L_divide_b20 + tst r1, r0, lsl #20 + bmi .L_divide_b21 + tst r1, r0, lsl #21 + bmi .L_divide_b22 + tst r1, r0, lsl #22 + bmi .L_divide_b23 + tst r1, r0, lsl #23 + bmi .L_divide_b24 + tst r1, r0, lsl #24 + bmi .L_divide_b25 + tst r1, r0, lsl #25 + bmi .L_divide_b26 + tst r1, r0, lsl #26 + bmi .L_divide_b27 + tst r1, r0, lsl #27 + bmi .L_divide_b28 + tst r1, r0, lsl #28 + bmi .L_divide_b29 + tst r1, r0, lsl #29 + bmi .L_divide_b30 + tst r1, r0, lsl #30 + bmi .L_divide_b31 +/* + * instead of: + * tst r1, r0, lsl #31 + * bmi .L_divide_b32 + */ + b .L_divide_b32 + +.L_old_code: + cmp r1, r0 + bcc .L_divide_b0 + cmp r1, r0, lsl #1 + bcc .L_divide_b1 + cmp r1, r0, lsl #2 + bcc .L_divide_b2 + cmp r1, r0, lsl #3 + bcc .L_divide_b3 + cmp r1, r0, lsl #4 + bcc .L_divide_b4 + cmp r1, r0, lsl #5 + bcc .L_divide_b5 + cmp r1, r0, lsl #6 + bcc .L_divide_b6 + cmp r1, r0, lsl #7 + bcc .L_divide_b7 + cmp r1, r0, lsl #8 + bcc .L_divide_b8 + cmp r1, r0, lsl #9 + bcc .L_divide_b9 + cmp r1, r0, lsl #10 + bcc .L_divide_b10 + cmp r1, r0, lsl #11 + bcc .L_divide_b11 + cmp r1, r0, lsl #12 + bcc .L_divide_b12 + cmp r1, r0, lsl #13 + bcc .L_divide_b13 + cmp r1, r0, lsl #14 + bcc .L_divide_b14 + cmp r1, r0, lsl #15 + bcc .L_divide_b15 + cmp r1, r0, lsl #16 + bcc .L_divide_b16 + cmp r1, r0, lsl #17 + bcc .L_divide_b17 + cmp r1, r0, lsl #18 + bcc .L_divide_b18 + cmp r1, r0, lsl #19 + bcc .L_divide_b19 + cmp r1, r0, lsl #20 + bcc .L_divide_b20 + cmp r1, r0, lsl #21 + bcc .L_divide_b21 + cmp r1, r0, lsl #22 + bcc .L_divide_b22 + cmp r1, r0, lsl #23 + bcc .L_divide_b23 + cmp r1, r0, lsl #24 + bcc .L_divide_b24 + cmp r1, r0, lsl #25 + bcc .L_divide_b25 + cmp r1, r0, lsl #26 + bcc .L_divide_b26 + cmp r1, r0, lsl #27 + bcc .L_divide_b27 + cmp r1, r0, lsl #28 + bcc .L_divide_b28 + cmp r1, r0, lsl #29 + bcc .L_divide_b29 + cmp r1, r0, lsl #30 + bcc .L_divide_b30 +.L_divide_b32: + cmp r1, r0, lsl #31 + subhs r1, r1,r0, lsl #31 + addhs r3, r3,r2, lsl #31 +.L_divide_b31: + cmp r1, r0, lsl #30 + subhs r1, r1,r0, lsl #30 + addhs r3, r3,r2, lsl #30 +.L_divide_b30: + cmp r1, r0, lsl #29 + subhs r1, r1,r0, lsl #29 + addhs r3, r3,r2, lsl #29 +.L_divide_b29: + cmp r1, r0, lsl #28 + subhs r1, r1,r0, lsl #28 + addhs r3, r3,r2, lsl #28 +.L_divide_b28: + cmp r1, r0, lsl #27 + subhs r1, r1,r0, lsl #27 + addhs r3, r3,r2, lsl #27 +.L_divide_b27: + cmp r1, r0, lsl #26 + subhs r1, r1,r0, lsl #26 + addhs r3, r3,r2, lsl #26 +.L_divide_b26: + cmp r1, r0, lsl #25 + subhs r1, r1,r0, lsl #25 + addhs r3, r3,r2, lsl #25 +.L_divide_b25: + cmp r1, r0, lsl #24 + subhs r1, r1,r0, lsl #24 + addhs r3, r3,r2, lsl #24 +.L_divide_b24: + cmp r1, r0, lsl #23 + subhs r1, r1,r0, lsl #23 + addhs r3, r3,r2, lsl #23 +.L_divide_b23: + cmp r1, r0, lsl #22 + subhs r1, r1,r0, lsl #22 + addhs r3, r3,r2, lsl #22 +.L_divide_b22: + cmp r1, r0, lsl #21 + subhs r1, r1,r0, lsl #21 + addhs r3, r3,r2, lsl #21 +.L_divide_b21: + cmp r1, r0, lsl #20 + subhs r1, r1,r0, lsl #20 + addhs r3, r3,r2, lsl #20 +.L_divide_b20: + cmp r1, r0, lsl #19 + subhs r1, r1,r0, lsl #19 + addhs r3, r3,r2, lsl #19 +.L_divide_b19: + cmp r1, r0, lsl #18 + subhs r1, r1,r0, lsl #18 + addhs r3, r3,r2, lsl #18 +.L_divide_b18: + cmp r1, r0, lsl #17 + subhs r1, r1,r0, lsl #17 + addhs r3, r3,r2, lsl #17 +.L_divide_b17: + cmp r1, r0, lsl #16 + subhs r1, r1,r0, lsl #16 + addhs r3, r3,r2, lsl #16 +.L_divide_b16: + cmp r1, r0, lsl #15 + subhs r1, r1,r0, lsl #15 + addhs r3, r3,r2, lsl #15 +.L_divide_b15: + cmp r1, r0, lsl #14 + subhs r1, r1,r0, lsl #14 + addhs r3, r3,r2, lsl #14 +.L_divide_b14: + cmp r1, r0, lsl #13 + subhs r1, r1,r0, lsl #13 + addhs r3, r3,r2, lsl #13 +.L_divide_b13: + cmp r1, r0, lsl #12 + subhs r1, r1,r0, lsl #12 + addhs r3, r3,r2, lsl #12 +.L_divide_b12: + cmp r1, r0, lsl #11 + subhs r1, r1,r0, lsl #11 + addhs r3, r3,r2, lsl #11 +.L_divide_b11: + cmp r1, r0, lsl #10 + subhs r1, r1,r0, lsl #10 + addhs r3, r3,r2, lsl #10 +.L_divide_b10: + cmp r1, r0, lsl #9 + subhs r1, r1,r0, lsl #9 + addhs r3, r3,r2, lsl #9 +.L_divide_b9: + cmp r1, r0, lsl #8 + subhs r1, r1,r0, lsl #8 + addhs r3, r3,r2, lsl #8 +.L_divide_b8: + cmp r1, r0, lsl #7 + subhs r1, r1,r0, lsl #7 + addhs r3, r3,r2, lsl #7 +.L_divide_b7: + cmp r1, r0, lsl #6 + subhs r1, r1,r0, lsl #6 + addhs r3, r3,r2, lsl #6 +.L_divide_b6: + cmp r1, r0, lsl #5 + subhs r1, r1,r0, lsl #5 + addhs r3, r3,r2, lsl #5 +.L_divide_b5: + cmp r1, r0, lsl #4 + subhs r1, r1,r0, lsl #4 + addhs r3, r3,r2, lsl #4 +.L_divide_b4: + cmp r1, r0, lsl #3 + subhs r1, r1,r0, lsl #3 + addhs r3, r3,r2, lsl #3 +.L_divide_b3: + cmp r1, r0, lsl #2 + subhs r1, r1,r0, lsl #2 + addhs r3, r3,r2, lsl #2 +.L_divide_b2: + cmp r1, r0, lsl #1 + subhs r1, r1,r0, lsl #1 + addhs r3, r3,r2, lsl #1 +.L_divide_b1: + cmp r1, r0 + subhs r1, r1, r0 + addhs r3, r3, r2 +.L_divide_b0: + + tst ip, #0x20000000 + bne .L_udivide_l1 + mov r0, r3 + cmp ip, #0 + rsbmi r1, r1, #0 + movs ip, ip, lsl #1 + bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */ + rsbmi r0, r0, #0 + RET + +.L_udivide_l1: + tst ip, #0x10000000 + mov r1, r1, lsl #1 + orrne r1, r1, #1 + mov r3, r3, lsl #1 + cmp r1, r0 + subhs r1, r1, r0 + addhs r3, r3, r2 + mov r0, r3 + RET +END(__divsi3) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/fabs.c b/lib/libc/arm/gen/fabs.c new file mode 100644 index 000000000000..2e0abbb8a42a --- /dev/null +++ b/lib/libc/arm/gen/fabs.c @@ -0,0 +1,45 @@ +/* $NetBSD: fabs.c,v 1.2 2002/05/26 11:48:01 wiz Exp $ */ + +/*- + * SPDX-License-Identifier: BSD-4-Clause + * + * Copyright (c) 1996 Mark Brinicombe + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * fabs(x) returns the absolute value of x. + */ +double +fabs(double x) +{ + if (x < 0) + x = -x; + return(x); +} diff --git a/lib/libc/arm/gen/flt_rounds.c b/lib/libc/arm/gen/flt_rounds.c new file mode 100644 index 000000000000..7621262419a4 --- /dev/null +++ b/lib/libc/arm/gen/flt_rounds.c @@ -0,0 +1,68 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2012 Ian Lepore <freebsd@damnhippie.dyndns.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <fenv.h> +#include <float.h> + +#ifndef __ARM_PCS_VFP +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" +#endif + +int +__flt_rounds(void) +{ + int mode; + +#ifndef __ARM_PCS_VFP + /* + * Translate our rounding modes to the unnamed + * manifest constants required by C99 et. al. + */ + mode = __softfloat_float_rounding_mode; +#else /* __ARM_PCS_VFP */ + /* + * Read the floating-point status and control register + */ + __asm __volatile("vmrs %0, fpscr" : "=&r"(mode)); + mode &= _ROUND_MASK; +#endif /* __ARM_PCS_VFP */ + + switch (mode) { + case FE_TOWARDZERO: + return (0); + case FE_TONEAREST: + return (1); + case FE_UPWARD: + return (2); + case FE_DOWNWARD: + return (3); + } + return (-1); +} diff --git a/lib/libc/arm/gen/fpgetmask_vfp.c b/lib/libc/arm/gen/fpgetmask_vfp.c new file mode 100644 index 000000000000..5e73a274dafa --- /dev/null +++ b/lib/libc/arm/gen/fpgetmask_vfp.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/types.h> +#include <ieeefp.h> + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except_t +fpgetmask(void) +{ + fp_except mask; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(mask)); + + return ((mask >> 8) & FP_X_MASK); +} + diff --git a/lib/libc/arm/gen/fpgetround_vfp.c b/lib/libc/arm/gen/fpgetround_vfp.c new file mode 100644 index 000000000000..21debc0b028d --- /dev/null +++ b/lib/libc/arm/gen/fpgetround_vfp.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2014 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/types.h> +#include <ieeefp.h> + +#ifdef __weak_alias +__weak_alias(fpgetround,_fpgetround) +#endif + +fp_rnd_t +fpgetround(void) +{ + uint32_t fpscr; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(fpscr)); + + return ((fpscr >> 22) & 3); +} + diff --git a/lib/libc/arm/gen/fpgetsticky_vfp.c b/lib/libc/arm/gen/fpgetsticky_vfp.c new file mode 100644 index 000000000000..651610dddf83 --- /dev/null +++ b/lib/libc/arm/gen/fpgetsticky_vfp.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/types.h> +#include <ieeefp.h> + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except +fpgetsticky(void) +{ + fp_except old; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + + return (old & FP_X_MASK); +} + diff --git a/lib/libc/arm/gen/fpsetmask_vfp.c b/lib/libc/arm/gen/fpsetmask_vfp.c new file mode 100644 index 000000000000..92ad97e6dfa2 --- /dev/null +++ b/lib/libc/arm/gen/fpsetmask_vfp.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/types.h> +#include <ieeefp.h> + +#ifdef __weak_alias +__weak_alias(fpsetmask,_fpsetmask) +#endif + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except_t +fpsetmask(fp_except_t mask) +{ + fp_except old, new; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + mask = (mask & FP_X_MASK) << 8; + new = (old & ~(FP_X_MASK << 8)) | mask; + __asm __volatile("vmsr fpscr, %0" : : "r"(new)); + + return ((old >> 8) & FP_X_MASK); +} + diff --git a/lib/libc/arm/gen/fpsetround_vfp.c b/lib/libc/arm/gen/fpsetround_vfp.c new file mode 100644 index 000000000000..4e55335f6a3b --- /dev/null +++ b/lib/libc/arm/gen/fpsetround_vfp.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/types.h> +#include <ieeefp.h> + +#ifdef __weak_alias +__weak_alias(fpsetround,_fpsetround) +#endif + +fp_rnd_t +fpsetround(fp_rnd_t rnd_dir) +{ + uint32_t old, new; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + new = old & ~(3 << 22); + new |= rnd_dir << 22; + __asm __volatile("vmsr fpscr, %0" : : "r"(new)); + + return ((old >> 22) & 3); +} + diff --git a/lib/libc/arm/gen/fpsetsticky_vfp.c b/lib/libc/arm/gen/fpsetsticky_vfp.c new file mode 100644 index 000000000000..fb3a59b25178 --- /dev/null +++ b/lib/libc/arm/gen/fpsetsticky_vfp.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Andrew Turner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/types.h> +#include <ieeefp.h> + +#ifdef __weak_alias +__weak_alias(fpsetsticky,_fpsetsticky) +#endif + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except +fpsetsticky(fp_except except) +{ + fp_except old, new; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + new = old & ~(FP_X_MASK); + new &= ~except; + __asm __volatile("vmsr fpscr, %0" : : "r"(new)); + + return (old & except); +} + diff --git a/lib/libc/arm/gen/getcontextx.c b/lib/libc/arm/gen/getcontextx.c new file mode 100644 index 000000000000..357d3a2a0416 --- /dev/null +++ b/lib/libc/arm/gen/getcontextx.c @@ -0,0 +1,98 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2017 Michal Meloun <mmel@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/ucontext.h> +#include <errno.h> +#include <stdlib.h> +#include <machine/sysarch.h> + +struct ucontextx { + ucontext_t ucontext; + mcontext_vfp_t mcontext_vfp; +}; + +int +__getcontextx_size(void) +{ + + return (sizeof(struct ucontextx)); +} + +int +__fillcontextx2(char *ctx) +{ + struct ucontextx *ucxp; + ucontext_t *ucp; + mcontext_vfp_t *mvp; + struct arm_get_vfpstate_args vfp_arg; + + ucxp = (struct ucontextx *)ctx; + ucp = &ucxp->ucontext; + mvp = &ucxp->mcontext_vfp; + + vfp_arg.mc_vfp_size = sizeof(mcontext_vfp_t); + vfp_arg.mc_vfp = mvp; + if (sysarch(ARM_GET_VFPSTATE, &vfp_arg) == -1) + return (-1); + ucp->uc_mcontext.mc_vfp_size = sizeof(mcontext_vfp_t); + ucp->uc_mcontext.mc_vfp_ptr = mvp; + return (0); +} + +int +__fillcontextx(char *ctx) +{ + struct ucontextx *ucxp; + + ucxp = (struct ucontextx *)ctx; + if (getcontext(&ucxp->ucontext) == -1) + return (-1); + __fillcontextx2(ctx); + return (0); +} + +__weak_reference(__getcontextx, getcontextx); + +ucontext_t * +__getcontextx(void) +{ + char *ctx; + int error; + + ctx = malloc(__getcontextx_size()); + if (ctx == NULL) + return (NULL); + if (__fillcontextx(ctx) == -1) { + error = errno; + free(ctx); + errno = error; + return (NULL); + } + return ((ucontext_t *)ctx); +} diff --git a/lib/libc/arm/gen/infinity.c b/lib/libc/arm/gen/infinity.c new file mode 100644 index 000000000000..1a78a03be2e3 --- /dev/null +++ b/lib/libc/arm/gen/infinity.c @@ -0,0 +1,23 @@ +/* + * infinity.c + */ + +#include <math.h> + +/* bytes for +Infinity on a 387 */ +const union __infinity_un __infinity = { +#if BYTE_ORDER == BIG_ENDIAN + { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } +#else + { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } +#endif +}; + +/* bytes for NaN */ +const union __nan_un __nan = { +#if BYTE_ORDER == BIG_ENDIAN + {0xff, 0xc0, 0, 0} +#else + { 0, 0, 0xc0, 0xff } +#endif +}; diff --git a/lib/libc/arm/gen/makecontext.c b/lib/libc/arm/gen/makecontext.c new file mode 100644 index 000000000000..ac338085f2ed --- /dev/null +++ b/lib/libc/arm/gen/makecontext.c @@ -0,0 +1,88 @@ +/* $NetBSD: makecontext.c,v 1.2 2003/01/18 11:06:24 thorpej Exp $ */ + +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <stddef.h> +#include <inttypes.h> +#include <ucontext.h> + +#include <stdarg.h> + +extern void _ctx_start(void); + +void +ctx_done(ucontext_t *ucp) +{ + + if (ucp->uc_link == NULL) + exit(0); + else { + setcontext((const ucontext_t *)ucp->uc_link); + abort(); + } +} + +__weak_reference(__makecontext, makecontext); + +void +__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) +{ + __greg_t *gr = ucp->uc_mcontext.__gregs; + int i; + unsigned int *sp; + va_list ap; + + /* Compute and align stack pointer. */ + sp = (unsigned int *) + (((uintptr_t)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size - + sizeof(double)) & ~7); + /* Allocate necessary stack space for arguments exceeding r0-3. */ + if (argc > 4) + sp -= argc - 4; + gr[_REG_SP] = (__greg_t)sp; + /* Wipe out frame pointer. */ + gr[_REG_FP] = 0; + /* Arrange for return via the trampoline code. */ + gr[_REG_PC] = (__greg_t)_ctx_start; + gr[_REG_R4] = (__greg_t)func; + gr[_REG_R5] = (__greg_t)ucp; + + va_start(ap, argc); + /* Pass up to four arguments in r0-3. */ + for (i = 0; i < argc && i < 4; i++) + gr[_REG_R0 + i] = va_arg(ap, int); + /* Pass any additional arguments on the stack. */ + for (argc -= i; argc > 0; argc--) + *sp++ = va_arg(ap, int); + va_end(ap); +} diff --git a/lib/libc/arm/gen/setjmp.S b/lib/libc/arm/gen/setjmp.S new file mode 100644 index 000000000000..e7f8b788e878 --- /dev/null +++ b/lib/libc/arm/gen/setjmp.S @@ -0,0 +1,142 @@ +/* $NetBSD: setjmp.S,v 1.14 2013/04/19 13:45:45 matt Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__ARM_PCS) +#error FPA is not supported anymore +#endif + + .fpu vfp + +#include <machine/asm.h> +#include <machine/setjmp.h> +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a) + * by restoring registers from the stack. + * The previous signal state is restored. + */ + +ENTRY(setjmp) + /* Block all signals and retrieve the old signal mask */ + stmfd sp!, {r0, r14} + add r2, r0, #(_JB_SIGMASK * 4) /* oset */ + mov r1, #0x00000000 /* set */ + mov r0, #0x00000001 /* SIG_BLOCK */ + bl PIC_SYM(_C_LABEL(sigprocmask), PLT) + ldmfd sp!, {r0, r14} + + ldr r1, .Lsetjmp_magic + +#if !defined(SOFTFLOAT_FOR_GCC) + add r2, r0, #(_JB_REG_D8 * 4) + vstmia r2, {d8-d15} + vmrs r2, fpscr + str r2, [r0, #(_JB_REG_FPSCR * 4)] +#endif + + str r1, [r0] /* store magic */ + + /* Store integer registers */ + add r0, r0, #(_JB_REG_R4 * 4) +#ifndef __thumb__ + stmia r0, {r4-r14} +#else + stmia r0, {r4-r12} + str r13, [r0, #((_JB_REG_R13 - _JB_REG_R4) * 4)] + str r14, [r0, #((_JB_REG_R14 - _JB_REG_R4) * 4)] +#endif + mov r0, #0x00000000 + RET + +.Lsetjmp_magic: + .word _JB_MAGIC_SETJMP +END(setjmp) + +.weak _C_LABEL(longjmp) +.set _C_LABEL(longjmp), _C_LABEL(__longjmp) +ENTRY(__longjmp) + ldr r2, [r0] + ldr ip, .Lsetjmp_magic + teq r2, ip + bne .Lbotch + + /* Restore the signal mask. */ + stmfd sp!, {r0-r2, r14} + mov r2, #0x00000000 + add r1, r0, #(_JB_SIGMASK * 4) /* Signal mask */ + mov r0, #3 /* SIG_SETMASK */ + bl PIC_SYM(_C_LABEL(sigprocmask), PLT) + ldmfd sp!, {r0-r2, r14} + +#if !defined(SOFTFLOAT_FOR_GCC) + add ip, r0, #(_JB_REG_D8 * 4) + vldmia ip, {d8-d15} + ldr ip, [r0, #(_JB_REG_FPSCR * 4)] + vmsr fpscr, ip +#endif + + add r0, r0, #(_JB_REG_R4 * 4) + /* Restore integer registers */ +#ifndef __thumb__ + ldmia r0, {r4-r14} +#else + ldmia r0, {r4-r12} + ldr r13, [r0, #((_JB_REG_R13 - _JB_REG_R4) * 4)] + ldr r14, [r0, #((_JB_REG_R14 - _JB_REG_R4) * 4)] +#endif + + /* Validate sp and r14 */ + teq sp, #0 + it ne + teqne r14, #0 + it eq + beq .Lbotch + + /* Set return value */ + movs r0, r1 + it eq + moveq r0, #0x00000001 + RET + + /* validation failed, die die die. */ +.Lbotch: + bl PIC_SYM(_C_LABEL(longjmperror), PLT) + bl PIC_SYM(_C_LABEL(abort), PLT) +1: b 1b /* Cannot get here */ +END(__longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/signalcontext.c b/lib/libc/arm/gen/signalcontext.c new file mode 100644 index 000000000000..e66a08928355 --- /dev/null +++ b/lib/libc/arm/gen/signalcontext.c @@ -0,0 +1,77 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2004 Olivier Houchard + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/signal.h> +#include <sys/ucontext.h> + +#include <machine/frame.h> +#include <machine/sigframe.h> + +#include <errno.h> +#include <stdarg.h> +#include <stdlib.h> +#include <unistd.h> +#include <strings.h> +#include <signal.h> + +__weak_reference(__signalcontext, signalcontext); + +extern void _ctx_start(void); + +int +__signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func) +{ + struct sigframe *sfp; + __greg_t *gr = ucp->uc_mcontext.__gregs; + unsigned int *sp; + + sp = (unsigned int *)gr[_REG_SP]; + + sfp = (struct sigframe *)sp - 1; + + bzero(sfp, sizeof(*sfp)); + bcopy(ucp, &sfp->sf_uc, sizeof(*ucp)); + sfp->sf_si.si_signo = sig; + + gr[_REG_SP] = (__greg_t)sfp; + /* Wipe out frame pointer. */ + gr[_REG_FP] = 0; + /* Arrange for return via the trampoline code. */ + gr[_REG_PC] = (__greg_t)_ctx_start; + gr[_REG_R4] = (__greg_t)func; + gr[_REG_R5] = (__greg_t)ucp; + gr[_REG_R0] = (__greg_t)sig; + gr[_REG_R1] = (__greg_t)&sfp->sf_si; + gr[_REG_R2] = (__greg_t)&sfp->sf_uc; + + ucp->uc_link = &sfp->sf_uc; + sigdelset(&ucp->uc_sigmask, sig); + + return (0); +} diff --git a/lib/libc/arm/gen/sigsetjmp.S b/lib/libc/arm/gen/sigsetjmp.S new file mode 100644 index 000000000000..a4e2e974c945 --- /dev/null +++ b/lib/libc/arm/gen/sigsetjmp.S @@ -0,0 +1,68 @@ +/* $NetBSD: sigsetjmp.S,v 1.6 2013/04/19 16:50:22 matt Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/asm.h> +#include <machine/setjmp.h> + +/* + * C library -- sigsetjmp, siglongjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a, m) + * by restoring registers from the stack. + * The previous signal state is restored. + */ + +ENTRY(sigsetjmp) + teq r1, #0 + beq PIC_SYM(_C_LABEL(_setjmp), PLT) + b PIC_SYM(_C_LABEL(setjmp), PLT) +END(sigsetjmp) + +.L_setjmp_magic: + .word _JB_MAGIC__SETJMP +WEAK_ALIAS(__siglongjmp, siglongjmp) + +ENTRY(siglongjmp) + ldr r2, .L_setjmp_magic /* load magic */ + ldr r3, [r0] /* get magic from jmp_buf */ + bic r3, r3, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP) + /* ignore VFP-ness of magic */ + teq r2, r3 /* magic correct? */ + beq PIC_SYM(_C_LABEL(_longjmp), PLT) + b PIC_SYM(_C_LABEL(longjmp), PLT) +END(siglongjmp) + + .section .note.GNU-stack,"",%progbits |