diff options
Diffstat (limited to 'libc/sysdeps/linux')
33 files changed, 1700 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/kvx/Makefile b/libc/sysdeps/linux/kvx/Makefile new file mode 100644 index 000000000..633c91f3e --- /dev/null +++ b/libc/sysdeps/linux/kvx/Makefile @@ -0,0 +1,13 @@ +# Makefile for uClibc +# +# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +top_srcdir=../../../../ +top_builddir=../../../../ +all: objs +include $(top_builddir)Rules.mak +include Makefile.arch +include $(top_srcdir)Makerules diff --git a/libc/sysdeps/linux/kvx/Makefile.arch b/libc/sysdeps/linux/kvx/Makefile.arch new file mode 100644 index 000000000..3ad290915 --- /dev/null +++ b/libc/sysdeps/linux/kvx/Makefile.arch @@ -0,0 +1,10 @@ +# Makefile for uClibc +# +# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +CSRC-y := __syscall_error.c +CSRC-$(UCLIBC_LINUX_SPECIFIC) += cachectl.c +SSRC-y := setjmp.S bsd-setjmp.S bsd-_setjmp.S __longjmp.S clone.S vfork.S diff --git a/libc/sysdeps/linux/kvx/__longjmp.S b/libc/sysdeps/linux/kvx/__longjmp.S new file mode 100644 index 000000000..fbfefe81c --- /dev/null +++ b/libc/sysdeps/linux/kvx/__longjmp.S @@ -0,0 +1,53 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#include <sysdep.h> +#define _SETJMP_H +#define _ASM +#include <bits/setjmp.h> +#include <libc-symbols.h> + +/** + * void __longjmp(__jmp_buf __env, int __val) + */ +ENTRY(__longjmp) + /* Load $ra and $csinto r40r41 */ + lq $r40r41 = JMPBUF_RA_CS_OFFSET[$r0] + ;; + /* Load $r36r37r38r39 with r12(sp) r14 r18 r19 */ + lo $r36r37r38r39 = (JMPBUF_REGS_OFFSET)[$r0] + set $ra = $r40 + ;; + /* Load $lc, $le and $ls */ + lo $r32r33r34r35 = JMPBUF_LC_LE_LS_OFFSET[$r0] + copyd $sp = $r36 + copyd $r14 = $r37 + set $cs = $r41 + ;; + /* Load r20r21r22r23 */ + lo $r20r21r22r23 = (JMPBUF_REGS_OFFSET + QUAD_REG_SIZE)[$r0] + copyd $r18 = $r38 + copyd $r19 = $r39 + set $lc = $r32 + ;; + /* Load r24r25r26r27 */ + lo $r24r25r26r27 = (JMPBUF_REGS_OFFSET + 2 * QUAD_REG_SIZE)[$r0] + set $le = $r33 + ;; + /* Load r28r29r30r31 */ + lo $r28r29r30r31 = (JMPBUF_REGS_OFFSET + 3 * QUAD_REG_SIZE)[$r0] + set $ls = $r34 + /* Copy retval */ + copyd $r0 = $r1 + ;; + /* According to man, if retval is equal to 0, then we should return 1 */ + cmoved.deqz $r0? $r0 = 1 + ret + ;; +END(__longjmp) +libc_hidden_def(__longjmp) diff --git a/libc/sysdeps/linux/kvx/__syscall_error.c b/libc/sysdeps/linux/kvx/__syscall_error.c new file mode 100644 index 000000000..d534ee7d4 --- /dev/null +++ b/libc/sysdeps/linux/kvx/__syscall_error.c @@ -0,0 +1,19 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#include <errno.h> +#include <features.h> + +/* This routine is jumped to by all the syscall handlers, to stash + * an error number into errno. */ +long __syscall_error(int err_no) attribute_hidden; +long __syscall_error(int err_no) +{ + __set_errno(-err_no); + return -1; +} diff --git a/libc/sysdeps/linux/kvx/bits/atomic.h b/libc/sysdeps/linux/kvx/bits/atomic.h new file mode 100644 index 000000000..3c423e9ba --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/atomic.h @@ -0,0 +1,141 @@ +/* Copyright (C) 2010-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _KVX_BITS_ATOMIC_H +#define _KVX_BITS_ATOMIC_H + +#include <stdint.h> + +typedef int8_t atomic8_t; +typedef uint8_t uatomic8_t; +typedef int_fast8_t atomic_fast8_t; +typedef uint_fast8_t uatomic_fast8_t; + +typedef int16_t atomic16_t; +typedef uint16_t uatomic16_t; +typedef int_fast16_t atomic_fast16_t; +typedef uint_fast16_t uatomic_fast16_t; + +typedef int32_t atomic32_t; +typedef uint32_t uatomic32_t; +typedef int_fast32_t atomic_fast32_t; +typedef uint_fast32_t uatomic_fast32_t; + +typedef int64_t atomic64_t; +typedef uint64_t uatomic64_t; +typedef int_fast64_t atomic_fast64_t; +typedef uint_fast64_t uatomic_fast64_t; + +typedef intptr_t atomicptr_t; +typedef uintptr_t uatomicptr_t; +typedef intmax_t atomic_max_t; +typedef uintmax_t uatomic_max_t; + + +#ifndef atomic_full_barrier +# define atomic_full_barrier() do { atomic_read_barrier(); \ + atomic_write_barrier(); } while(0) +#endif + +#ifndef atomic_read_barrier +# define atomic_read_barrier() __builtin_kvx_dinval() +#endif + +#ifndef atomic_write_barrier +# define atomic_write_barrier() __builtin_kvx_fence() +#endif + +/* + * On kvx, we have a boolean compare and swap which means that the operation + * returns only the success of operation. + * If operation succeeds, this is simple, we just need to return the provided + * old value. However, if it fails, we need to load the value to return it for + * the caller. If the loaded value is different from the "old" provided by the + * caller, we can return it since it will mean it failed. + * However, if for some reason the value we read is equal to the old value + * provided by the caller, we can't simply return it or the caller will think it + * succeeded. So if the value we read is the same as the "old" provided by + * the caller, we try again until either we succeed or we fail with a different + * value than the provided one. + */ +#define __cmpxchg(ptr, old, new, op_suffix, load_suffix) \ +({ \ + register unsigned long __rn __asm__("r62"); \ + register unsigned long __ro __asm__("r63"); \ + __asm__ __volatile__ ( \ + /* Fence to guarantee previous store to be committed */ \ + "fence\n" \ + /* Init "expect" with previous value */ \ + "copyd $r63 = %[rOld]\n" \ + ";;\n" \ + "1:\n" \ + /* Init "update" value with new */ \ + "copyd $r62 = %[rNew]\n" \ + ";;\n" \ + "acswap" #op_suffix " 0[%[rPtr]], $r62r63\n" \ + ";;\n" \ + /* if acswap succeeds, simply return */ \ + "cb.dnez $r62? 2f\n" \ + ";;\n" \ + /* We failed, load old value */ \ + "l" #op_suffix #load_suffix" $r63 = 0[%[rPtr]]\n" \ + ";;\n" \ + /* Check if equal to "old" one */ \ + "compd.ne $r62 = $r63, %[rOld]\n" \ + ";;\n" \ + /* If different from "old", return it to caller */ \ + "cb.deqz $r62? 1b\n" \ + ";;\n" \ + "2:\n" \ + : "+r" (__rn), "+r" (__ro) \ + : [rPtr] "r" (ptr), [rOld] "r" (old), [rNew] "r" (new) \ + : "memory"); \ + (__ro); \ +}) + +#define cmpxchg(ptr, o, n) \ +({ \ + unsigned long __cmpxchg__ret; \ + switch (sizeof(*(ptr))) { \ + case 4: \ + __cmpxchg__ret = __cmpxchg((ptr), (o), (n), w, s); \ + break; \ + case 8: \ + __cmpxchg__ret = __cmpxchg((ptr), (o), (n), d, ); \ + break; \ + } \ + (__typeof(*(ptr))) (__cmpxchg__ret); \ +}) + +#define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ + cmpxchg((mem), (oldval), (newval)) + + +#define atomic_exchange_acq(mem, newval) \ +({ \ + unsigned long __aea__ret, __aea__old; \ + volatile __typeof((mem)) __aea__m = (mem); \ + do { \ + __aea__old = *__aea__m; \ + __aea__ret = atomic_compare_and_exchange_val_acq((mem), \ + (newval), (__aea__old));\ + } while (__aea__old != __aea__ret); \ + (__aea__old); \ +}) + +#endif diff --git a/libc/sysdeps/linux/kvx/bits/endian.h b/libc/sysdeps/linux/kvx/bits/endian.h new file mode 100644 index 000000000..03a1b7f0c --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/endian.h @@ -0,0 +1,13 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#ifndef _ENDIAN_H +# error "Never use <bits/endian.h> directly; include <endian.h> instead." +#endif + +#define __BYTE_ORDER __LITTLE_ENDIAN diff --git a/libc/sysdeps/linux/kvx/bits/fcntl.h b/libc/sysdeps/linux/kvx/bits/fcntl.h new file mode 100644 index 000000000..c1815b44f --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/fcntl.h @@ -0,0 +1,226 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#ifndef _FCNTL_H +# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead." +#endif + +#include <sys/types.h> +#ifdef __USE_GNU +# include <bits/uio.h> +#endif + +/* open/fcntl - O_SYNC is only implemented on blocks devices and on files + located on an ext2 file system */ +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#define O_SYNC 010000 +#define O_FSYNC O_SYNC +#define O_ASYNC 020000 + +#ifdef __USE_XOPEN2K8 +# define O_DIRECTORY 0200000 /* Must be a directory. */ +# define O_NOFOLLOW 0400000 /* Do not follow links. */ +# define O_CLOEXEC 02000000 /* Set close_on_exec. */ +#endif + +#ifdef __USE_GNU +# define O_DIRECT 040000 /* Direct disk access. */ +# define O_NOATIME 01000000 /* Do not set atime. */ +# define O_PATH 010000000 /* Resolve pathname but do not open file. */ +#endif + +#ifdef __USE_LARGEFILE64 +# define O_LARGEFILE 0100000 +#endif + +/* For now Linux has synchronisity options for data and read operations. + We define the symbols here but let them do the same as O_SYNC since + this is a superset. */ +#if defined __USE_POSIX199309 || defined __USE_UNIX98 +# define O_DSYNC O_SYNC /* Synchronize data. */ +# define O_RSYNC O_SYNC /* Synchronize read operations. */ +#endif + +/* Values for the second argument to `fcntl'. */ +#define F_DUPFD 0 /* Duplicate file descriptor. */ +#define F_GETFD 1 /* Get file descriptor flags. */ +#define F_SETFD 2 /* Set file descriptor flags. */ +#define F_GETFL 3 /* Get file status flags. */ +#define F_SETFL 4 /* Set file status flags. */ + +#define F_GETLK 5 /* Get record locking info. */ +#define F_SETLK 6 /* Set record locking info (non-blocking). */ +#define F_SETLKW 7 /* Set record locking info (blocking). */ + +/* Same as standard, since we always have 64-bit offsets. */ +#define F_GETLK64 F_GETLK /* Get record locking info. */ +#define F_SETLK64 F_SETLK /* Set record locking info (non-blocking). */ +#define F_SETLKW64 F_SETLKW /* Set record locking info (blocking). */ + +#if defined __USE_BSD || defined __USE_XOPEN2K +# define F_SETOWN 8 /* Get owner of socket (receiver of SIGIO). */ +# define F_GETOWN 9 /* Set owner of socket (receiver of SIGIO). */ +#endif + +#ifdef __USE_GNU +# define F_SETSIG 10 /* Set number of signal to be sent. */ +# define F_GETSIG 11 /* Get number of signal to be sent. */ +#endif + +#ifdef __USE_GNU +# define F_SETLEASE 1024 /* Set a lease. */ +# define F_GETLEASE 1025 /* Enquire what lease is active. */ +# define F_NOTIFY 1026 /* Request notfications on a directory. */ +# define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with + close-on-exit set on new fd. */ +# define F_SETPIPE_SZ 1031 /* Set pipe page size array. */ +# define F_GETPIPE_SZ 1032 /* Get pipe page size array. */ +#endif + +/* For F_[GET|SET]FL. */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */ +#define F_RDLCK 0 /* Read lock. */ +#define F_WRLCK 1 /* Write lock. */ +#define F_UNLCK 2 /* Remove lock. */ + +/* For old implementation of bsd flock(). */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +#ifdef __USE_BSD +/* Operations for bsd flock(), also used by the kernel implementation. */ +# define LOCK_SH 1 /* shared lock */ +# define LOCK_EX 2 /* exclusive lock */ +# define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +# define LOCK_UN 8 /* remove lock */ +#endif + +#ifdef __USE_GNU +# define LOCK_MAND 32 /* This is a mandatory flock: */ +# define LOCK_READ 64 /* ... which allows concurrent read operations. */ +# define LOCK_WRITE 128 /* ... which allows concurrent write operations. */ +# define LOCK_RW 192 /* ... Which allows concurrent read & write operations. */ +#endif + +#ifdef __USE_GNU +/* Types of directory notifications that may be requested with F_NOTIFY. */ +# define DN_ACCESS 0x00000001 /* File accessed. */ +# define DN_MODIFY 0x00000002 /* File modified. */ +# define DN_CREATE 0x00000004 /* File created. */ +# define DN_DELETE 0x00000008 /* File removed. */ +# define DN_RENAME 0x00000010 /* File renamed. */ +# define DN_ATTRIB 0x00000020 /* File changed attibutes. */ +# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */ +#endif + +struct flock + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ +#ifndef __USE_FILE_OFFSET64 + __off_t l_start; /* Offset where the lock begins. */ + __off_t l_len; /* Size of the locked area; zero means until EOF. */ +#else + __off64_t l_start; /* Offset where the lock begins. */ + __off64_t l_len; /* Size of the locked area; zero means until EOF. */ +#endif + __pid_t l_pid; /* Process holding the lock. */ + }; + +#ifdef __USE_LARGEFILE64 +struct flock64 + { + short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ + short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ + __off64_t l_start; /* Offset where the lock begins. */ + __off64_t l_len; /* Size of the locked area; zero means until EOF. */ + __pid_t l_pid; /* Process holding the lock. */ + }; +#endif + +/* Define some more compatibility macros to be backward compatible with + BSD systems which did not managed to hide these kernel macros. */ +#ifdef __USE_BSD +# define FAPPEND O_APPEND +# define FFSYNC O_FSYNC +# define FASYNC O_ASYNC +# define FNONBLOCK O_NONBLOCK +# define FNDELAY O_NDELAY +#endif /* Use BSD. */ + +/* Advise to `posix_fadvise'. */ +#ifdef __USE_XOPEN2K +# define POSIX_FADV_NORMAL 0 /* No further special treatment. */ +# define POSIX_FADV_RANDOM 1 /* Expect random page references. */ +# define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */ +# define POSIX_FADV_WILLNEED 3 /* Will need these pages. */ +# define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ +# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ +#endif + +#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__ +/* Flags for SYNC_FILE_RANGE. */ +# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages + in the range before performing the + write. */ +# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those + dirty pages in the range which are + not presently under writeback. */ +# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in + the range after performing the + write. */ + +/* Flags for SPLICE and VMSPLICE. */ +# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */ +# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing + (but we may still block on the fd + we splice from/to). */ +# define SPLICE_F_MORE 4 /* Expect more data. */ +# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */ +#endif + +__BEGIN_DECLS + +#if defined __USE_GNU && defined __UCLIBC_LINUX_SPECIFIC__ + +/* Provide kernel hint to read ahead. */ +extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count) + __THROW; + +/* Selective file content synch'ing. */ +extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to, + unsigned int __flags); + +/* Splice address range into a pipe. */ +extern ssize_t vmsplice (int __fdout, const struct iovec *__iov, + size_t __count, unsigned int __flags); + +/* Splice two files together. */ +extern ssize_t splice (int __fdin, __off64_t *__offin, int __fdout, + __off64_t *__offout, size_t __len, + unsigned int __flags); + +/* In-kernel implementation of tee for pipe buffers. */ +extern ssize_t tee (int __fdin, int __fdout, size_t __len, + unsigned int __flags); + +#endif +__END_DECLS diff --git a/libc/sysdeps/linux/kvx/bits/fenv.h b/libc/sysdeps/linux/kvx/bits/fenv.h new file mode 100644 index 000000000..445ec7aff --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/fenv.h @@ -0,0 +1,106 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _FENV_H +# error "Never use <bits/fenv.h> directly; include <fenv.h> instead." +#endif + +/* $cs register number for use in kvx builtins */ +#define KVX_SFR_CS 4 + +/* Each core of the Coolidge processor has a coprocessor. They share + the CS register but have distinct bit-fields for their + floating-point environment. This implementation synchronizes them + in such a way that they cannot be managed separately. */ + +/* Compute Status ($cs) register contains the following bit-fields for + floating-point execption flags. + + Bit-field Condition of the IEEE 754 binary floating-point standard + --------- -------------------------------------------------------- + IO Invalid Operation + DZ Divide by Zero + OV Overflow + UN Underflow + IN Inexact + XIO Invalid Operation (coprocessor) + XDZ Divide by Zero (coprocessor) + XOV Overflow (coprocessor) + XUN Underflow (coprocessor) + XIN Inexact (coprocessor) */ + +#define _FE_INVALID 0x02 +#define _FE_DIVBYZERO 0x04 +#define _FE_OVERFLOW 0x08 +#define _FE_UNDERFLOW 0x10 +#define _FE_INEXACT 0x20 + +#define _FE_X_INVALID 0x0200 +#define _FE_X_DIVBYZERO 0x0400 +#define _FE_X_OVERFLOW 0x0800 +#define _FE_X_UNDERFLOW 0x1000 +#define _FE_X_INEXACT 0x2000 + +#define FE_INVALID (_FE_INVALID | _FE_X_INVALID) +#define FE_DIVBYZERO (_FE_DIVBYZERO | _FE_X_DIVBYZERO) +#define FE_OVERFLOW (_FE_OVERFLOW | _FE_X_OVERFLOW) +#define FE_UNDERFLOW (_FE_UNDERFLOW | _FE_X_UNDERFLOW) +#define FE_INEXACT (_FE_INEXACT | _FE_X_INEXACT) + +#define FE_ALL_EXCEPT (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW|FE_INEXACT) + +/* Compute Status ($cs) register contains the following bit-fields for + floating-point rounding modes. + + Following table describes both the RM and XRM (coproc) bit-fields. + + Value Rounding Mode of the IEEE 754 binary floating-point standard + ----- ------------------------------------------------------------ + 0b00 to nearest even + 0b01 toward +inf + 0b10 toward -inf + 0b11 toward zero */ + +#define _FE_TONEAREST 0 +#define _FE_UPWARD 1 +#define _FE_DOWNWARD 2 +#define _FE_TOWARDZERO 3 + +#define _FE_X_TONEAREST 0 +#define _FE_X_UPWARD 1 +#define _FE_X_DOWNWARD 2 +#define _FE_X_TOWARDZERO 3 + + +#define FE_TONEAREST ((_FE_TONEAREST << 16) | (_FE_X_TONEAREST << 20)) +#define FE_UPWARD ((_FE_UPWARD << 16) | (_FE_X_UPWARD << 20)) +#define FE_DOWNWARD ((_FE_DOWNWARD << 16) | (_FE_X_DOWNWARD << 20)) +#define FE_TOWARDZERO ((_FE_TOWARDZERO << 16) | (_FE_X_TOWARDZERO << 20)) + +#define FE_RND_MASK FE_TOWARDZERO + +/* The type representing all floating-point status flags collectively. + The environment is simply a copy from the FPU related bits in the + CS register, but can be improved in the future. */ +typedef unsigned int fexcept_t; +/* The type representing the entire floating-point environment. The + environment is simply a copy from the FPU related bits in the CS + register. */ +typedef unsigned int fenv_t; + +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV __fe_dfl_env diff --git a/libc/sysdeps/linux/kvx/bits/kernel_types.h b/libc/sysdeps/linux/kvx/bits/kernel_types.h new file mode 100644 index 000000000..832b17674 --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/kernel_types.h @@ -0,0 +1,42 @@ +/* Note that we use the exact same include guard #define names + * as asm/posix_types.h. This will avoid gratuitous conflicts + * with the posix_types.h kernel header, and will ensure that + * our private content, and not the kernel header, will win. + * -Erik + */ +#ifndef __ASM_GENERIC_POSIX_TYPES_H +#define __ASM_GENERIC_POSIX_TYPES_H + +typedef unsigned long __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned int __kernel_mode_t; +typedef unsigned int __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef int __kernel_ipc_pid_t; +typedef unsigned int __kernel_uid_t; +typedef unsigned int __kernel_gid_t; +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef long long __kernel_loff_t; +typedef unsigned int __kernel_old_dev_t; +typedef long __kernel_long_t; +typedef unsigned long __kernel_ulong_t; + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#endif /* __ASM_GENERIC_POSIX_TYPES_H */ diff --git a/libc/sysdeps/linux/kvx/bits/posix_types.h b/libc/sysdeps/linux/kvx/bits/posix_types.h new file mode 100644 index 000000000..e556fda5d --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/posix_types.h @@ -0,0 +1,14 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2017 Kalray Inc. + */ + +#ifndef _UAPI_ASM_KVX_POSIX_TYPES_H +#define _UAPI_ASM_KVX_POSIX_TYPES_H + +#include <asm-generic/posix_types.h> + +#endif /* _UAPI_ASM_KVX_POSIX_TYPES_H */ diff --git a/libc/sysdeps/linux/kvx/bits/sem.h b/libc/sysdeps/linux/kvx/bits/sem.h new file mode 100644 index 000000000..4d412a2cb --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/sem.h @@ -0,0 +1,84 @@ +/* Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_SEM_H +# error "Never include <bits/sem.h> directly; use <sys/sem.h> instead." +#endif + +#include <sys/types.h> + +/* Flags for `semop'. */ +#define SEM_UNDO 0x1000 /* undo the operation on exit */ + +/* Commands for `semctl'. */ +#define GETPID 11 /* get sempid */ +#define GETVAL 12 /* get semval */ +#define GETALL 13 /* get all semval's */ +#define GETNCNT 14 /* get semncnt */ +#define GETZCNT 15 /* get semzcnt */ +#define SETVAL 16 /* set semval */ +#define SETALL 17 /* set all semval's */ + + +/* Data structure describing a set of semaphores. */ +struct semid_ds +{ + struct ipc_perm sem_perm; /* operation permission struct */ + __time_t sem_otime; /* last semop() time */ + __time_t sem_ctime; /* last time changed by semctl() */ + unsigned long int sem_nsems; /* number of semaphores in set */ + unsigned long int __unused1; + unsigned long int __unused2; +}; + +/* The user should define a union like the following to use it for arguments + for `semctl'. + + union semun + { + int val; <= value for SETVAL + struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET + unsigned short int *array; <= array for GETALL & SETALL + struct seminfo *__buf; <= buffer for IPC_INFO + }; + + Previous versions of this file used to define this union but this is + incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether + one must define the union or not. */ +#define _SEM_SEMUN_UNDEFINED 1 + +#ifdef __USE_MISC + +/* ipcs ctl cmds */ +# define SEM_STAT 18 +# define SEM_INFO 19 + +struct seminfo +{ + int semmap; + int semmni; + int semmns; + int semmnu; + int semmsl; + int semopm; + int semume; + int semusz; + int semvmx; + int semaem; +}; + +#endif /* __USE_MISC */ diff --git a/libc/sysdeps/linux/kvx/bits/setjmp.h b/libc/sysdeps/linux/kvx/bits/setjmp.h new file mode 100644 index 000000000..59faa7620 --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/setjmp.h @@ -0,0 +1,46 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#ifndef _BITS_SETJMP_H +#define _BITS_SETJMP_H 1 + +#if !defined _SETJMP_H && !defined _PTHREAD_H +# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." +#endif + +#define SIZE_OF_REG 8 + +/* Size of a quad reg (can't use sizeof(uint64_t) since it will be in asm */ +#define QUAD_REG_SIZE (4 * SIZE_OF_REG) + + +#define JMPBUF_RA_CS_OFFSET 0 +#define JMPBUF_LC_LE_LS_OFFSET (2 * SIZE_OF_REG) +/* Start offset of regs[] in __jmp_buf struct */ +#define JMPBUF_REGS_OFFSET (JMPBUF_LC_LE_LS_OFFSET + (4 * SIZE_OF_REG)) + +#ifndef _ASM +typedef struct + { + /* Return address */ + unsigned long ra; + unsigned long cs; + + /* Store lc, le, ls into this buf */ + unsigned long lc_le_ls[4]; + + /* Callee-saved GPR registers: + * r12(sp) r14 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 + */ + unsigned long regs[16]; + + } __jmp_buf[1] __attribute__((__aligned__ (8))); + +#endif + +#endif /* bits/setjmp.h */ diff --git a/libc/sysdeps/linux/kvx/bits/stackinfo.h b/libc/sysdeps/linux/kvx/bits/stackinfo.h new file mode 100644 index 000000000..0a17bff30 --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/stackinfo.h @@ -0,0 +1,29 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This file contains a bit of information about the stack allocation + of the processor. Since there is no general truth we can't say + anything here. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +#define _STACK_GROWS_DOWN 1 + +#endif /* stackinfo.h */ + + diff --git a/libc/sysdeps/linux/kvx/bits/statfs.h b/libc/sysdeps/linux/kvx/bits/statfs.h new file mode 100644 index 000000000..660ae8f5f --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/statfs.h @@ -0,0 +1,64 @@ +/* Copyright (C) 1997, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_STATFS_H +# error "Never include <bits/statfs.h> directly; use <sys/statfs.h> instead." +#endif + +#include <bits/types.h> /* for __fsid_t and __fsblkcnt_t*/ + +struct statfs + { + long int f_type; + long int f_bsize; + __fsblkcnt64_t f_blocks; + __fsblkcnt64_t f_bfree; + __fsblkcnt64_t f_bavail; + __fsfilcnt64_t f_files; + __fsfilcnt64_t f_ffree; + + /* Linux specials */ + __fsid_t f_fsid; + long int f_namelen; + long int f_frsize; + long int f_flags; + long int f_spare[4]; + }; + +#ifdef __USE_LARGEFILE64 +struct statfs64 + { + long int f_type; + long int f_bsize; + __fsblkcnt64_t f_blocks; + __fsblkcnt64_t f_bfree; + __fsblkcnt64_t f_files; + __fsfilcnt64_t f_ffree; + __fsfilcnt64_t f_bavail; + + /* Linux specials */ + __fsid_t f_fsid; + long int f_namelen; + long int f_frsize; + long int f_flags; + long int f_spare[4]; + }; +#endif + +/* Tell code we have these members. */ +#define _STATFS_F_NAMELEN +#define _STATFS_F_FRSIZE diff --git a/libc/sysdeps/linux/kvx/bits/syscalls.h b/libc/sysdeps/linux/kvx/bits/syscalls.h new file mode 100644 index 000000000..71bd5e4fe --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/syscalls.h @@ -0,0 +1,80 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#ifndef _BITS_SYSCALLS_H +#define _BITS_SYSCALLS_H +#ifndef _SYSCALL_H +# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead." +#endif + +#ifndef __ASSEMBLER__ + +#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + register long _ret __asm__("r0"); \ + register unsigned long _scno __asm__("r6") = name; \ + LOAD_ARGS_##nr (args) \ + __asm__ __volatile__("scall %[r_scno]" \ + : "=r" (_ret) \ + : [r_scno] "r" (_scno) ASM_ARGS_##nr \ + : ASM_CLOBBER_##nr); \ + _ret; \ + }) + +/* Mark all argument registers as per ABI in the range r1-r5 as + clobbered when they are not used for the invocation of the scall */ +#define ASM_CLOBBER_6 "cc", "memory", \ + "r7", "r8", "r9", "r10", "r11", /* unused argument registers */ \ + "r15", /* struct pointer */ \ + "r16", "r17", /* veneer registers */ \ + "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", /* 32->63 are caller-saved */ \ + "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", \ + "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", \ + "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63" +#define ASM_CLOBBER_5 "r5", ASM_CLOBBER_6 +#define ASM_CLOBBER_4 "r4", ASM_CLOBBER_5 +#define ASM_CLOBBER_3 "r3", ASM_CLOBBER_4 +#define ASM_CLOBBER_2 "r2", ASM_CLOBBER_3 +#define ASM_CLOBBER_1 "r1", ASM_CLOBBER_2 +#define ASM_CLOBBER_0 ASM_CLOBBER_1 + +#define LOAD_ARGS_0() +#define ASM_ARGS_0 + +#define LOAD_ARGS_1(a1) \ + LOAD_ARGS_0(); \ + _ret = (long) a1; +#define ASM_ARGS_1 ASM_ARGS_0, "r"(_ret) + +#define LOAD_ARGS_2(a1, a2) \ + LOAD_ARGS_1(a1); \ + register long _a2 __asm__("r1") = (long) a2; +#define ASM_ARGS_2 ASM_ARGS_1, "r"(_a2) + +#define LOAD_ARGS_3(a1, a2, a3) \ + LOAD_ARGS_2(a1, a2); \ + register long _a3 __asm__("r2") = (long) a3; +#define ASM_ARGS_3 ASM_ARGS_2, "r"(_a3) + +#define LOAD_ARGS_4(a1, a2, a3, a4) \ + LOAD_ARGS_3(a1, a2, a3); \ + register long _a4 __asm__("r3") = (long) a4; +#define ASM_ARGS_4 ASM_ARGS_3, "r"(_a4) + +#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \ + LOAD_ARGS_4(a1, a2, a3, a4); \ + register long _a5 __asm__("r4") = (long) a5; +#define ASM_ARGS_5 ASM_ARGS_4, "r"(_a5) + +#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \ + LOAD_ARGS_5(a1, a2, a3, a4, a5); \ + register long _a6 __asm__("r5") = (long) a6; +#define ASM_ARGS_6 ASM_ARGS_5, "r"(_a6) + +#endif /* __ASSEMBLER__ */ +#endif /* _BITS_SYSCALLS_H */ diff --git a/libc/sysdeps/linux/kvx/bits/uClibc_arch_features.h b/libc/sysdeps/linux/kvx/bits/uClibc_arch_features.h new file mode 100644 index 000000000..7aae2d7c3 --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/uClibc_arch_features.h @@ -0,0 +1,41 @@ +/* + * Track misc arch-specific features that aren't config options + */ + +#ifndef _BITS_UCLIBC_ARCH_FEATURES_H +#define _BITS_UCLIBC_ARCH_FEATURES_H + +/* instruction used when calling abort() to kill yourself */ +#define __UCLIBC_ABORT_INSTRUCTION__ "errop\n\t;;\n" + +/* can your target use syscall6() for mmap ? */ +#define __UCLIBC_MMAP_HAS_6_ARGS__ + +/* does your target align 64bit values in register pairs ? (32bit arches only) */ +#undef __UCLIBC_SYSCALL_ALIGN_64BIT__ + +/* does your target have a broken create_module() ? */ +#undef __UCLIBC_BROKEN_CREATE_MODULE__ + +/* does your target have to worry about older [gs]etrlimit() ? */ +#undef __UCLIBC_HANDLE_OLDER_RLIMIT__ + +/* does your target have an asm .set ? */ +#define __UCLIBC_HAVE_ASM_SET_DIRECTIVE__ + +/* define if target supports .weak */ +#define __UCLIBC_HAVE_ASM_WEAK_DIRECTIVE__ + +/* define if target supports .weakext */ +#undef __UCLIBC_HAVE_ASM_WEAKEXT_DIRECTIVE__ + +/* define if target supports CFI pseudo ops */ +#undef __UCLIBC_HAVE_ASM_CFI_DIRECTIVES__ + +/* define if target supports IEEE signed zero floats */ +#define __UCLIBC_HAVE_SIGNED_ZERO__ + +/* only weird assemblers generally need this */ +#undef __UCLIBC_ASM_LINE_SEP__ + +#endif /* _BITS_UCLIBC_ARCH_FEATURES_H */ diff --git a/libc/sysdeps/linux/kvx/bits/wordsize.h b/libc/sysdeps/linux/kvx/bits/wordsize.h new file mode 100644 index 000000000..751c41ab7 --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/wordsize.h @@ -0,0 +1,9 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#define __WORDSIZE 64 diff --git a/libc/sysdeps/linux/kvx/bsd-_setjmp.S b/libc/sysdeps/linux/kvx/bsd-_setjmp.S new file mode 100644 index 000000000..a4c4f87b0 --- /dev/null +++ b/libc/sysdeps/linux/kvx/bsd-_setjmp.S @@ -0,0 +1,18 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#include <sysdep.h> + +ENTRY(_setjmp) + /* Set second argument to 0 */ + make $r1 = 0 + ;; + goto HIDDEN_JUMPTARGET(__sigsetjmp) + ;; +END(_setjmp) +libc_hidden_def (_setjmp) diff --git a/libc/sysdeps/linux/kvx/bsd-setjmp.S b/libc/sysdeps/linux/kvx/bsd-setjmp.S new file mode 100644 index 000000000..d79f603d5 --- /dev/null +++ b/libc/sysdeps/linux/kvx/bsd-setjmp.S @@ -0,0 +1,17 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#include <sysdep.h> + +ENTRY(setjmp) + /* Set second argument to 1 */ + make $r1 = 1 + ;; + goto HIDDEN_JUMPTARGET(__sigsetjmp) + ;; +END(setjmp) diff --git a/libc/sysdeps/linux/kvx/cachectl.c b/libc/sysdeps/linux/kvx/cachectl.c new file mode 100644 index 000000000..9afeb44a1 --- /dev/null +++ b/libc/sysdeps/linux/kvx/cachectl.c @@ -0,0 +1,15 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2020 Kalray Inc. + */ + +#include <sys/syscall.h> + +#ifdef __NR_cachectl +# include <sys/cachectl.h> +_syscall4(int, cachectl, void *, addr, size_t, len, + unsigned long, cache, unsigned long, flags) +#endif diff --git a/libc/sysdeps/linux/kvx/clone.S b/libc/sysdeps/linux/kvx/clone.S new file mode 100644 index 000000000..71ea80a01 --- /dev/null +++ b/libc/sysdeps/linux/kvx/clone.S @@ -0,0 +1,100 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#include <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/** + * Clone system call implementation for kvx + * int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg, + * pid_t *ptid, struct user_desc *tls, pid_t *ctid); + * $r0 = fn + * $r1 = child_stack + * $r2 = flags + * $r3 = args + * $r4 = ptid + * $r5 = tls + * $r6 = ctid + * + * The kernel expects to find its arguments in the following order: + * sys_clone(unsigned long clone_flags, unsigned long newsp, + * int __user * parent_tidptr, + * int __user * child_tidptr, + * unsigned long tls) + * + * So we have to make a few modifications before calling + * + */ + +ENTRY (__clone) + /* Check fn and stack to be non-null */ + cb.deqz $r1? L(clone_einval_error) + /* Align child stack first */ + andd $r1 = $r1, -32 + ;; + cb.deqz $r0? L(clone_einval_error) + /* Prepare space for child arguments on stack and stay aligned */ + addd $r1 = $r1, -32 + ;; + /* Save fn ($r0) on child stack */ + sd 0[$r1] = $r0 + /* Set clone_flags */ + copyd $r0 = $r2 + ;; + /* Save args ($r3) on child stack */ + sd 8[$r1] = $r3 + /* Set parent_tidptr */ + copyd $r2 = $r4 + /* Set child_tidptr */ + copyd $r3 = $r6 + /* Set tls */ + copyd $r4 = $r5 + ;; + scall SYS_ify(clone) + ;; + /* If 0, then we are the child */ + cb.deqz $r0, L(child_start) + ;; + /* Else we are the parent, and we need to check for errors */ + cb.dltz $r0, L(clone_error) + ;; + /* No error ! Yeepa ! */ + ret + ;; +L(child_start): + /* get fn from stack */ + ld $r1 = 0[$sp] + ;; + /* Get args from stack */ + ld $r0 = 8[$sp] + addd $sp = $sp, 32 + ;; + icall $r1 + ;; + scall SYS_ify(exit) + ;; + /* We should never ever get here ! */ + errop + ;; +L(clone_einval_error): + make $r0 = -EINVAL + ;; +L(clone_error): + /* goto __syscall_error but do not use call or $ra will be + * destroyed */ + goto __syscall_error + ;; + /* We will not return here but to clone caller + * (stored in $ra) */ + errop + ;; +END(__clone) + +libc_hidden_def (__clone) +weak_alias (__clone,clone) diff --git a/libc/sysdeps/linux/kvx/crt1.S b/libc/sysdeps/linux/kvx/crt1.S new file mode 100644 index 000000000..34501103e --- /dev/null +++ b/libc/sysdeps/linux/kvx/crt1.S @@ -0,0 +1,83 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +/* Startup code compliant to the ELF KVX ABI */ + +#include <libc-symbols.h> +#include <features.h> + +.type main,@function +.type __uClibc_main,@function + +/* + * When we enter this piece of code, the program stack has been + * layed out by the kernel like this: + * argc argument counter (integer) + * argv[0] program name (pointer) + * argv[1...N] program args (pointers) + * argv[argc-1] end of args (integer) + * NULL + * env[0...N] environment variables (pointers) + * NULL + * + * Moreover, when using dynamic loader, $r0 contains the rtld_fini + * address + * + * And we need to call the following function: + * __uClibc_main (int (*main) (int, char **, char **), int argc, + * char **argv, void (*init) (void), void (*fini) (void), + * void (*rtld_fini) (void), void *stack_end) + */ +.text +.globl _start +.type _start,@function +.align 8 +C_SYMBOL_NAME(_start): + /* Load argc from stack */ + ld $r1 = 0[$sp] + /* Load argv addr from stack */ + addd $r2 = $sp, 0x8 +#ifdef __PIC__ + pcrel $r7 = @gotaddr() +#endif + ;; + /* $r0 contains rtld_fini when run by dynamic loader */ + copyd $r5 = $r0 + /* prepare __uClibc_main arg */ +#ifndef __PIC__ + make $r3 = _init + make $r4 = _fini +#endif + ;; + /* Align stack to 32-byte boundary */ + andd $sp = $sp, -32 + make $r8 = 0 + make $fp = 0 + /* prepare __uClibc_main arg */ +#ifdef __PIC__ + ld $r3 = @got(_init)[$r7] +#endif + ;; + /* Setup stack_end for __uClibc_main */ + copyd $r6 = $sp + /* Clear compute status */ + set $cs = $r8 +#ifdef __PIC__ + ld $r4 = @got(_fini)[$r7] +#endif + ;; +#ifdef __PIC__ + ld $r0 = @got(main)[$r7] +#else + make $r0 = main +#endif + goto __uClibc_main + ;; + /* We should never return ! */ + errop + ;; diff --git a/libc/sysdeps/linux/kvx/crti.S b/libc/sysdeps/linux/kvx/crti.S new file mode 100644 index 000000000..cf5fb2b42 --- /dev/null +++ b/libc/sysdeps/linux/kvx/crti.S @@ -0,0 +1,31 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + + .section .init + .align 8 + .global _init + .type _init,@function +_init: + addd $sp = $sp, -32 + get $r15 = $ra + ;; + sq 0[$sp] = $r14r15 + copyd $fp = $sp + ;; + + .section .fini + .align 8 + .global _fini + .type _fini,@function +_fini: + addd $sp = $sp, -32 + get $r15 = $ra + ;; + sq 0[$sp] = $r14r15 + copyd $fp = $sp + ;; diff --git a/libc/sysdeps/linux/kvx/crtn.S b/libc/sysdeps/linux/kvx/crtn.S new file mode 100644 index 000000000..c1ba48096 --- /dev/null +++ b/libc/sysdeps/linux/kvx/crtn.S @@ -0,0 +1,33 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + + .section .init + .align 8 + .global _init + .type _init,@function + # EPILOGUE + lq $r14r15 = 0[$sp] + ;; + set $ra = $r15 + addd $sp = $sp, 32 + ;; + ret + ;; + + .section .fini + .align 8 + .global _fini + .type _fini,@function + # EPILOGUE + lq $r14r15 = 0[$sp] + ;; + set $ra = $r15 + addd $sp = $sp, 32 + ;; + ret + ;; diff --git a/libc/sysdeps/linux/kvx/jmpbuf-offsets.h b/libc/sysdeps/linux/kvx/jmpbuf-offsets.h new file mode 100644 index 000000000..27636fa33 --- /dev/null +++ b/libc/sysdeps/linux/kvx/jmpbuf-offsets.h @@ -0,0 +1,50 @@ +/* + * Private macros for accessing __jmp_buf contents. kvx version. + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2019 Kalray Inc. + */ + +#include <bits/wordsize.h> + +#if __WORDSIZE == 64 + +/* We only need to save callee-saved registers plus stackpointer */ +# define JB_R12 0 /* stack pointer */ +# define JB_R14 1 /* frame pointer */ +# define JB_R18 2 +# define JB_R19 3 +# define JB_R20 4 +# define JB_R21 5 +# define JB_R22 6 +# define JB_R23 7 +# define JB_R24 8 +# define JB_R25 9 +# define JB_R26 10 +# define JB_R27 11 +# define JB_R28 12 +# define JB_R29 13 +# define JB_R30 14 +# define JB_R31 15 + +#ifndef __ASSEMBLER__ +#include <setjmp.h> +#include <stdint.h> +#include <sysdep.h> + +static inline uintptr_t __attribute__ ((unused)) +_jmpbuf_sp (__jmp_buf jmpbuf) +{ + uintptr_t sp = jmpbuf[0].regs[JB_R12]; + return sp; +} +#endif + + +#else + +#error unsupported 32 bit wordsize + +#endif diff --git a/libc/sysdeps/linux/kvx/jmpbuf-unwind.h b/libc/sysdeps/linux/kvx/jmpbuf-unwind.h new file mode 100644 index 000000000..544da7012 --- /dev/null +++ b/libc/sysdeps/linux/kvx/jmpbuf-unwind.h @@ -0,0 +1,30 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2019 Kalray Inc. + */ + +#include <setjmp.h> +#include <jmpbuf-offsets.h> + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#if __WORDSIZE == 64 +# define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) (jmpbuf)[JB_R12]) +#else +#error 32-bit unsupported +#endif + +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ +#include <stdint.h> +#include <unwind.h> + +#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ + _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) + +#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ + ((uintptr_t) (_address) - (_adj) < (uintptr_t) _jmpbuf_sp(_jmpbuf) - (_adj)) +#endif diff --git a/libc/sysdeps/linux/kvx/setjmp.S b/libc/sysdeps/linux/kvx/setjmp.S new file mode 100644 index 000000000..1a8fce3fd --- /dev/null +++ b/libc/sysdeps/linux/kvx/setjmp.S @@ -0,0 +1,59 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#include <sysdep.h> + +#define _SETJMP_H +#define _ASM +#include <bits/setjmp.h> +#include <libc-symbols.h> + +/** + * Simply save the user context to $r0 (jmpbuf) + * + * This function has the following prototype: + * int __sigsetjmp (r0 = jmp_buf env, r1 = int savemask) + * At the end, we call sigjmp_save + * int __sigjmp_save (sigjmp_buf env, int savemask) + * which will save signal mask if needed (set by setjmp/_setjmp) + * + * NOTE: since r0 and r1 are used by __sigjmp_save, we must not + * clobber them during this function + */ +ENTRY(__sigsetjmp) + /* Save r20r21r22r23 */ + so (JMPBUF_REGS_OFFSET + QUAD_REG_SIZE)[$r0] = $r20r21r22r23 + get $r40 = $ra + ;; + /* Save r24r25r26r27 */ + so (JMPBUF_REGS_OFFSET + 2 * QUAD_REG_SIZE) [$r0] = $r24r25r26r27 + get $r41 = $cs + ;; + copyd $r36 = $sp + copyd $r37 = $r14 + copyd $r38 = $r18 + copyd $r39 = $r19 + ;; + /* Save r12(sp) r14 r18 r19 stored in $r36r37r38r39 */ + so (JMPBUF_REGS_OFFSET)[$r0] = $r36r37r38r39 + get $r32 = $lc + ;; + /* Save r28r29r30r31 */ + so (JMPBUF_REGS_OFFSET + 3 * QUAD_REG_SIZE) [$r0] = $r28r29r30r31 + get $r33 = $le + ;; + /* Save $cs and $ra */ + sq JMPBUF_RA_CS_OFFSET[$r0] = $r40r41 + get $r34 = $ls + ;; + /* Save $lc, $le and $ls */ + so JMPBUF_LC_LE_LS_OFFSET[$r0] = $r32r33r34r35 + goto __sigjmp_save + ;; +END(__sigsetjmp) +libc_hidden_def(__sigsetjmp) diff --git a/libc/sysdeps/linux/kvx/sys/cachectl.h b/libc/sysdeps/linux/kvx/sys/cachectl.h new file mode 100644 index 000000000..707de263e --- /dev/null +++ b/libc/sysdeps/linux/kvx/sys/cachectl.h @@ -0,0 +1,21 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2020 Kalray Inc. + */ + +#ifndef _SYS_CACHECTL_H +#define _SYS_CACHECTL_H 1 + +#include <asm/cachectl.h> + +__BEGIN_DECLS + +extern int cachectl(void *addr, size_t len, unsigned long cache, + unsigned long flags); + +__END_DECLS + +#endif diff --git a/libc/sysdeps/linux/kvx/sys/procfs.h b/libc/sysdeps/linux/kvx/sys/procfs.h new file mode 100644 index 000000000..bbbfb838e --- /dev/null +++ b/libc/sysdeps/linux/kvx/sys/procfs.h @@ -0,0 +1,101 @@ +/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_PROCFS_H +#define _SYS_PROCFS_H 1 + +/* This is somewhat modelled after the file of the same name on SVR4 + systems. It provides a definition of the core file format for ELF + used on Linux. It doesn't have anything to do with the /proc file + system, even though Linux has one. + + Anyway, the whole purpose of this file is for GDB and GDB only. + Don't read too much into it. Don't use it for anything other than + GDB unless you know what you are doing. */ + +#include <features.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/user.h> + +__BEGIN_DECLS + +/* Type for a general-purpose register. */ +typedef unsigned long elf_greg_t; +/* No FP registers for kvx. */ +typedef struct {} elf_fpregset_t; + +/* And the whole bunch of them. We could have used `struct + pt_regs' directly in the typedef, but tradition says that + the register set is an array, which does have some peculiar + semantics, so leave it that way. */ +#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +/* Signal info. */ +struct elf_siginfo + { + int si_signo; /* Signal number. */ + int si_code; /* Extra code. */ + int si_errno; /* Errno. */ + }; + +/* Definitions to generate Intel SVR4-like core files. These mostly + have the same names as the SVR4 types with "elf_" tacked on the + front to prevent clashes with Linux definitions, and the typedef + forms have been avoided. This is mostly like the SVR4 structure, + but more Linuxy, with things that Linux does not support and which + GDB doesn't really use excluded. */ + +struct elf_prstatus + { + short int pr_cursig; /* Current signal. */ + __pid_t pr_pid; + elf_gregset_t pr_reg; /* GP registers. */ + }; + + +#define ELF_PRARGSZ (80) /* Number of chars for args. */ + +struct elf_prpsinfo + { + char pr_fname[16]; /* Filename of executable. */ + char pr_psargs[ELF_PRARGSZ]; /* Initial part of arg list. */ + }; + +/* The rest of this file provides the types for emulation of the + Solaris <proc_service.h> interfaces that should be implemented by + users of libthread_db. */ + +/* Addresses. */ +typedef void *psaddr_t; + +/* Register sets. Linux has different names. */ +typedef elf_gregset_t prgregset_t; +typedef elf_fpregset_t prfpregset_t; + +/* We don't have any differences between processes and threads, + therefore have only one PID type. */ +typedef __pid_t lwpid_t; + +/* Process status and info. In the end we do provide typedefs for them. */ +typedef struct elf_prstatus prstatus_t; +typedef struct elf_prpsinfo prpsinfo_t; + +__END_DECLS + +#endif /* sys/procfs.h */ diff --git a/libc/sysdeps/linux/kvx/sys/ucontext.h b/libc/sysdeps/linux/kvx/sys/ucontext.h new file mode 100644 index 000000000..548892389 --- /dev/null +++ b/libc/sysdeps/linux/kvx/sys/ucontext.h @@ -0,0 +1,29 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include <signal.h> +#include <bits/sigcontext.h> + +/* Type for general register. */ +typedef unsigned long greg_t; + +/* Number of general registers. */ +#define NGREG 64 + +typedef struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; /* mask last for extensibility */ +} ucontext_t; + +#endif /* sys/ucontext.h */ diff --git a/libc/sysdeps/linux/kvx/sys/user.h b/libc/sysdeps/linux/kvx/sys/user.h new file mode 100644 index 000000000..2e228ff19 --- /dev/null +++ b/libc/sysdeps/linux/kvx/sys/user.h @@ -0,0 +1,27 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2019 Kalray Inc. + */ + +#ifndef _SYS_USER_H +#define _SYS_USER_H 1 + +struct user_regs_struct +{ + /* GPR */ + unsigned long long gpr_regs[64]; + + /* SFR */ + unsigned long lc; + unsigned long le; + unsigned long ls; + unsigned long ra; + + unsigned long cs; + unsigned long spc; +}; + +#endif diff --git a/libc/sysdeps/linux/kvx/sysdep.h b/libc/sysdeps/linux/kvx/sysdep.h new file mode 100644 index 000000000..944fedead --- /dev/null +++ b/libc/sysdeps/linux/kvx/sysdep.h @@ -0,0 +1,49 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#ifndef _LINUX_KVX_SYSDEP_H +#define _LINUX_KVX_SYSDEP_H 1 + +#include <common/sysdep.h> + +#define SYS_ify(syscall_name) (__NR_##syscall_name) + +#ifdef __ASSEMBLER__ + +# define _ENTRY(name) \ + .align 8; \ + .globl C_SYMBOL_NAME(name); \ + .func C_SYMBOL_NAME(name); \ + .type C_SYMBOL_NAME(name), @function; \ +C_SYMBOL_NAME(name): \ + cfi_startproc; + +/* Define an entry point visible from C. */ +# ifdef PIC +# define ENTRY(name) \ + .pic \ + _ENTRY(name) + +# else +# define ENTRY(name) _ENTRY(name) +# endif + +#endif + +/* Local label name for asm code. */ +# ifndef L +# define L(name) $L##name +# endif + +#undef END +#define END(name) \ + cfi_endproc; \ + .endfunc; \ + .size C_SYMBOL_NAME(name), .-C_SYMBOL_NAME(name) + +#endif //_LINUX_KVX_SYSDEP_H diff --git a/libc/sysdeps/linux/kvx/vfork.S b/libc/sysdeps/linux/kvx/vfork.S new file mode 100644 index 000000000..7c6a17133 --- /dev/null +++ b/libc/sysdeps/linux/kvx/vfork.S @@ -0,0 +1,47 @@ +/* + * This file is subject to the terms and conditions of the LGPL V2.1 + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2018 Kalray Inc. + */ + +#include <sys/syscall.h> +#include <sysdep.h> + +/* We do not want COMPAT to be enabled in our kernel, hence vfork + * is not available. Use clone to do the same job with appropriate flags */ +#define _SIGNAL_H +#include <bits/signum.h> /* For SIGCHLD */ + +#define CLONE_VM 0x00000100 +#define CLONE_VFORK 0x00004000 +#define CLONE_FLAGS_FOR_VFORK (CLONE_VM|CLONE_VFORK|SIGCHLD) + +ENTRY(__vfork) + make $r0 = CLONE_FLAGS_FOR_VFORK + /* Not sure if needed to zero-out other parameters but better + * be safe than sorry */ + make $r1 = 0 + make $r2 = 0 + ;; + make $r3 = 0 + make $r4 = 0 + ;; + scall SYS_ify(clone) + ;; + /* If PID < 0 then it's an error, else, simply return */ + cb.dltz $r0 ? err + ;; + ret + ;; +L(err): + goto __syscall_error + ;; + /* Never return */ + errop + ;; +END(__vfork) + +weak_alias(__vfork,vfork) +libc_hidden_def(vfork) |