diff options
Diffstat (limited to 'libc/sysdeps/linux/bfin')
-rw-r--r-- | libc/sysdeps/linux/bfin/Makefile.arch | 4 | ||||
-rw-r--r-- | libc/sysdeps/linux/bfin/bfin_fixed_code.h | 155 | ||||
-rw-r--r-- | libc/sysdeps/linux/bfin/bfin_sram.h | 1 | ||||
-rw-r--r-- | libc/sysdeps/linux/bfin/bits/syscalls.h | 53 | ||||
-rw-r--r-- | libc/sysdeps/linux/bfin/brk.c | 36 | ||||
-rw-r--r-- | libc/sysdeps/linux/bfin/syscall.c | 26 | ||||
-rw-r--r-- | libc/sysdeps/linux/bfin/sysdep.h | 1 |
7 files changed, 221 insertions, 55 deletions
diff --git a/libc/sysdeps/linux/bfin/Makefile.arch b/libc/sysdeps/linux/bfin/Makefile.arch index 6c271509e..81fca3295 100644 --- a/libc/sysdeps/linux/bfin/Makefile.arch +++ b/libc/sysdeps/linux/bfin/Makefile.arch @@ -5,11 +5,11 @@ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. # -CSRC := brk.c bsdsetjmp.c clone.c syscall.c \ +CSRC := bsdsetjmp.c clone.c syscall.c \ sram-alloc.c sram-free.c dma-memcpy.c SSRC := __longjmp.S setjmp.S bsd-_setjmp.S vfork.S -ARCH_HEADERS := bfin_l1layout.h bfin_sram.h +ARCH_HEADERS := bfin_fixed_code.h bfin_l1layout.h bfin_sram.h include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch diff --git a/libc/sysdeps/linux/bfin/bfin_fixed_code.h b/libc/sysdeps/linux/bfin/bfin_fixed_code.h new file mode 100644 index 000000000..914257156 --- /dev/null +++ b/libc/sysdeps/linux/bfin/bfin_fixed_code.h @@ -0,0 +1,155 @@ +/* Atomic instructions for userspace. + * + * The actual implementations can be found in the kernel. + * + * Copyright (c) 2008 Analog Devices, Inc. + * + * Licensed under the LGPL v2.1. + */ + +#ifndef __BFIN_FIXED_CODE_H__ +#define __BFIN_FIXED_CODE_H__ + +#include <stdint.h> + +#include <asm/fixed_code.h> + +#ifndef __ASSEMBLY__ + +static inline +uint32_t bfin_atomic_xchg32(uint32_t *__bfin_ptr, uint32_t __bfin_newval) +{ + uint32_t __bfin_ret; + /* Input: P0: memory address to use + * R1: value to store + * Output: R0: old contents of the memory address + */ + __asm__ __volatile__( + "CALL (%[__bfin_func])" + : "=q0" (__bfin_ret), "=m" (*__bfin_ptr) + : [__bfin_func] "a" (ATOMIC_XCHG32), "q1" (__bfin_newval), + "qA" (__bfin_ptr), "m" (*__bfin_ptr) + : "RETS", "memory" + ); + return __bfin_ret; +} + +static inline +uint32_t bfin_atomic_cas32(uint32_t *__bfin_ptr, uint32_t __bfin_exp, uint32_t __bfin_newval) +{ + uint32_t __bfin_ret; + /* Input: P0: memory address to use + * R1: compare value + * R2: new value to store + * Output: R0: old contents of the memory address + */ + __asm__ __volatile__( + "CALL (%[__bfin_func])" + : "=q0" (__bfin_ret), "=m" (*__bfin_ptr) + : [__bfin_func] "a" (ATOMIC_CAS32), "q1" (__bfin_exp), "q2" (__bfin_newval), + "qA" (__bfin_ptr), "m" (*__bfin_ptr) + : "RETS", "memory" + ); + return __bfin_ret; +} + +static inline +uint32_t bfin_atomic_add32(uint32_t *__bfin_ptr, uint32_t __bfin_inc) +{ + uint32_t __bfin_ret; + /* Input: P0: memory address to use + * R0: value to add + * Output: R0: new contents of the memory address + * R1: previous contents of the memory address + */ + __asm__ __volatile__( + "CALL (%[__bfin_func])" + : "=q0" (__bfin_ret), "=m" (*__bfin_ptr) + : [__bfin_func] "a" (ATOMIC_ADD32), "q0" (__bfin_inc), + "qA" (__bfin_ptr), "m" (*__bfin_ptr) + : "R1", "RETS", "memory" + ); + return __bfin_ret; +} +#define bfin_atomic_inc32(ptr) bfin_atomic_add32(ptr, 1) + +static inline +uint32_t bfin_atomic_sub32(uint32_t *__bfin_ptr, uint32_t __bfin_dec) +{ + uint32_t __bfin_ret; + /* Input: P0: memory address to use + * R0: value to subtract + * Output: R0: new contents of the memory address + * R1: previous contents of the memory address + */ + __asm__ __volatile__( + "CALL (%[__bfin_func])" + : "=q0" (__bfin_ret), "=m" (*__bfin_ptr) + : [__bfin_func] "a" (ATOMIC_SUB32), "q0" (__bfin_dec), + "qA" (__bfin_ptr), "m" (*__bfin_ptr) + : "R1", "RETS", "memory" + ); + return __bfin_ret; +} +#define bfin_atomic_dec32(ptr) bfin_atomic_sub32(ptr, 1) + +static inline +uint32_t bfin_atomic_ior32(uint32_t *__bfin_ptr, uint32_t __bfin_ior) +{ + uint32_t __bfin_ret; + /* Input: P0: memory address to use + * R0: value to ior + * Output: R0: new contents of the memory address + * R1: previous contents of the memory address + */ + __asm__ __volatile__( + "CALL (%[__bfin_func])" + : "=q0" (__bfin_ret), "=m" (*__bfin_ptr) + : [__bfin_func] "a" (ATOMIC_IOR32), "q0" (__bfin_ior), + "qA" (__bfin_ptr), "m" (*__bfin_ptr) + : "R1", "RETS", "memory" + ); + return __bfin_ret; +} + +static inline +uint32_t bfin_atomic_and32(uint32_t *__bfin_ptr, uint32_t __bfin_and) +{ + uint32_t __bfin_ret; + /* Input: P0: memory address to use + * R0: value to and + * Output: R0: new contents of the memory address + * R1: previous contents of the memory address + */ + __asm__ __volatile__( + "CALL (%[__bfin_func])" + : "=q0" (__bfin_ret), "=m" (*__bfin_ptr) + : [__bfin_func] "a" (ATOMIC_AND32), "q0" (__bfin_and), + "qA" (__bfin_ptr), "m" (*__bfin_ptr) + : "R1", "RETS", "memory" + ); + return __bfin_ret; +} + +static inline +uint32_t bfin_atomic_xor32(uint32_t *__bfin_ptr, uint32_t __bfin_xor) +{ + uint32_t __bfin_ret; + /* Input: P0: memory address to use + * R0: value to xor + * Output: R0: new contents of the memory address + * R1: previous contents of the memory address + */ + __asm__ __volatile__( + "CALL (%[__bfin_func])" + : "=q0" (__bfin_ret), "=m" (*__bfin_ptr) + : [__bfin_func] "a" (ATOMIC_XOR32), "q0" (__bfin_xor), + "qA" (__bfin_ptr), "m" (*__bfin_ptr) + : "R1", "RETS", "memory" + ); + return __bfin_ret; +} + +#endif + +#endif diff --git a/libc/sysdeps/linux/bfin/bfin_sram.h b/libc/sysdeps/linux/bfin/bfin_sram.h index eea729b05..278514d5d 100644 --- a/libc/sysdeps/linux/bfin/bfin_sram.h +++ b/libc/sysdeps/linux/bfin/bfin_sram.h @@ -18,6 +18,7 @@ __BEGIN_DECLS #define L1_DATA_A_SRAM 0x00000002 #define L1_DATA_B_SRAM 0x00000004 #define L1_DATA_SRAM 0x00000006 +#define L2_SRAM 0x00000008 extern void *sram_alloc(size_t size, unsigned long flags) __attribute_malloc__ __attribute_warn_unused_result__; diff --git a/libc/sysdeps/linux/bfin/bits/syscalls.h b/libc/sysdeps/linux/bfin/bits/syscalls.h index 0833a1fc1..37e564d2c 100644 --- a/libc/sysdeps/linux/bfin/bits/syscalls.h +++ b/libc/sysdeps/linux/bfin/bits/syscalls.h @@ -134,5 +134,58 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6 __syscall_return(type,__res); \ } + +/* Define a macro which expands into the inline wrapper code for a system call */ +#define INLINE_SYSCALL(name, nr, args...) \ +({ \ + INTERNAL_SYSCALL_DECL(err); \ + long result_var = INTERNAL_SYSCALL(name, err, nr, args); \ + if (INTERNAL_SYSCALL_ERROR_P(result_var, err)) { \ + __set_errno(INTERNAL_SYSCALL_ERRNO(result_var, err)); \ + result_var = -1L; \ + } \ + result_var; \ +}) + +#define INTERNAL_SYSCALL_DECL(err) do { } while (0) +#define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned long)val >= (unsigned long)(-4095)) +#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) + +#define INTERNAL_SYSCALL(name, err, nr, args...) \ +({ \ + long __res; \ + __asm__ __volatile__ ( \ + "excpt 0;\n\t" \ + : "=q0" (__res) \ + : "qA" (__NR_##name) ASMFMT_##nr(args) \ + : "memory","CC"); \ + __res; \ +}) + +#define ASMFMT_0() + +#define ASMFMT_1(arg1) \ + , "q0" ((long)(arg1)) + +#define ASMFMT_2(arg1, arg2) \ + ASMFMT_1(arg1) \ + , "q1" ((long)(arg2)) + +#define ASMFMT_3(arg1, arg2, arg3) \ + ASMFMT_2(arg1, arg2) \ + , "q2" ((long)(arg3)) + +#define ASMFMT_4(arg1, arg2, arg3, arg4) \ + ASMFMT_3(arg1, arg2, arg3) \ + , "q3" ((long)(arg4)) + +#define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \ + ASMFMT_4(arg1, arg2, arg3, arg4) \ + , "q4" ((long)(arg5)) + +#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \ + ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \ + , "q5" ((long)(arg6)) + #endif /* __ASSEMBLER__ */ #endif /* _BITS_SYSCALLS_H */ diff --git a/libc/sysdeps/linux/bfin/brk.c b/libc/sysdeps/linux/bfin/brk.c deleted file mode 100644 index 88b82cf64..000000000 --- a/libc/sysdeps/linux/bfin/brk.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> - * - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - */ - -#include <errno.h> -#include <unistd.h> -#include <sys/syscall.h> - -/* libc_hidden_proto(brk) */ - -/* This must be initialized data because commons can't have aliases. */ -void * __curbrk attribute_hidden = 0; - -int brk (void *addr) -{ - void *newbrk; - - __asm__ __volatile__( - "P0 = %2;\n\t" - "excpt 0;\n\t" - : "=q0" (newbrk) - : "q0" (addr), "i" (__NR_brk): "P0" ); - - __curbrk = newbrk; - - if (newbrk < addr) - { - __set_errno (ENOMEM); - return -1; - } - - return 0; -} -libc_hidden_def(brk) diff --git a/libc/sysdeps/linux/bfin/syscall.c b/libc/sysdeps/linux/bfin/syscall.c index 1db873874..d68eb6e2f 100644 --- a/libc/sysdeps/linux/bfin/syscall.c +++ b/libc/sysdeps/linux/bfin/syscall.c @@ -29,24 +29,16 @@ long syscall(long sysnum, long a, long b, long c, long d, long e, long f) int _r0 = 0; __asm__ __volatile__ ( - "R5 = %7;" - "R4 = %6;" - "R3 = %5;" - "R2 = %4;" - "R1 = %3;" - "R0 = %2;" - "P0 = %1;" "excpt 0;" - "%0 = R0;" - : "=r" (_r0) - : "rm" (sysnum), - "rm" (a), - "rm" (b), - "rm" (c), - "rm" (d), - "rm" (e), - "rm" (f) - : "memory","CC","R0","R1","R2","R3","R4","R5","P0"); + : "=q0" (_r0) + : "qA" (sysnum), + "q0" (a), + "q1" (b), + "q2" (c), + "q3" (d), + "q4" (e), + "q5" (f) + : "memory", "CC"); if (_r0 >= (unsigned long) -4095) { (*__errno_location()) = (-_r0); diff --git a/libc/sysdeps/linux/bfin/sysdep.h b/libc/sysdeps/linux/bfin/sysdep.h index 4080c22a4..0a633681b 100644 --- a/libc/sysdeps/linux/bfin/sysdep.h +++ b/libc/sysdeps/linux/bfin/sysdep.h @@ -14,6 +14,7 @@ #ifdef __ASSEMBLER__ #define ENTRY(sym) .global sym; .type sym, STT_FUNC; sym: +#define ENDPROC(sym) .size sym, . - sym #endif |