From aee3ff1b413cff44e7d91dd1901cacd8988ce9cf Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 30 Jun 2009 22:24:54 +0100 Subject: FRV: Wire up new syscalls Wire up new syscalls rt_tgsigqueueinfo and perf_counter_open. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/frv/include/asm/unistd.h | 4 +++- arch/frv/kernel/entry.S | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'arch/frv') diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h index 96d78d5d2c4..4a8fb427ce0 100644 --- a/arch/frv/include/asm/unistd.h +++ b/arch/frv/include/asm/unistd.h @@ -341,10 +341,12 @@ #define __NR_inotify_init1 332 #define __NR_preadv 333 #define __NR_pwritev 334 +#define __NR_rt_tgsigqueueinfo 335 +#define __NR_perf_counter_open 336 #ifdef __KERNEL__ -#define NR_syscalls 335 +#define NR_syscalls 337 #define __ARCH_WANT_IPC_PARSE_VERSION /* #define __ARCH_WANT_OLD_READDIR */ diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 356e0e327a8..fde1e446b44 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S @@ -1524,5 +1524,7 @@ sys_call_table: .long sys_inotify_init1 .long sys_preadv .long sys_pwritev + .long sys_rt_tgsigqueueinfo /* 335 */ + .long sys_perf_counter_open syscall_table_size = (. - sys_call_table) -- cgit v1.2.3 From 00460f41fffc0435dbb6ab4b058a190163d57ce6 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 2 Jul 2009 00:46:16 +0100 Subject: FRV: Implement atomic64_t Implement atomic64_t and its ops for FRV. Tested with the following patch: diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index 55e4fab..086d50d 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c @@ -746,6 +746,52 @@ static void __init parse_cmdline_early(char *cmdline) } /* end parse_cmdline_early() */ +static atomic64_t xxx; + +static void test_atomic64(void) +{ + atomic64_set(&xxx, 0x12300000023LL); + + mb(); + BUG_ON(atomic64_read(&xxx) != 0x12300000023LL); + mb(); + if (atomic64_inc_return(&xxx) != 0x12300000024LL) + BUG(); + mb(); + BUG_ON(atomic64_read(&xxx) != 0x12300000024LL); + mb(); + if (atomic64_sub_return(0x36900000050LL, &xxx) != -0x2460000002cLL) + BUG(); + mb(); + BUG_ON(atomic64_read(&xxx) != -0x2460000002cLL); + mb(); + if (atomic64_dec_return(&xxx) != -0x2460000002dLL) + BUG(); + mb(); + BUG_ON(atomic64_read(&xxx) != -0x2460000002dLL); + mb(); + if (atomic64_add_return(0x36800000001LL, &xxx) != 0x121ffffffd4LL) + BUG(); + mb(); + BUG_ON(atomic64_read(&xxx) != 0x121ffffffd4LL); + mb(); + if (atomic64_cmpxchg(&xxx, 0x123456789abcdefLL, 0x121ffffffd4LL) != 0x121ffffffd4LL) + BUG(); + mb(); + BUG_ON(atomic64_read(&xxx) != 0x121ffffffd4LL); + mb(); + if (atomic64_cmpxchg(&xxx, 0x121ffffffd4LL, 0x123456789abcdefLL) != 0x121ffffffd4LL) + BUG(); + mb(); + BUG_ON(atomic64_read(&xxx) != 0x123456789abcdefLL); + mb(); + if (atomic64_xchg(&xxx, 0xabcdef123456789LL) != 0x123456789abcdefLL) + BUG(); + mb(); + BUG_ON(atomic64_read(&xxx) != 0xabcdef123456789LL); + mb(); +} + /*****************************************************************************/ /* * @@ -845,6 +891,8 @@ void __init setup_arch(char **cmdline_p) // asm volatile("movgs %0,timerd" :: "r"(10000000)); // __set_HSR(0, __get_HSR(0) | HSR0_ETMD); + test_atomic64(); + } /* end setup_arch() */ #if 0 Note that this doesn't cover all the trivial wrappers, but does cover all the substantial implementations. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/frv/include/asm/atomic.h | 68 +++++++++++++++++- arch/frv/include/asm/system.h | 2 + arch/frv/kernel/frv_ksyms.c | 4 ++ arch/frv/lib/Makefile | 2 +- arch/frv/lib/atomic-ops.S | 3 +- arch/frv/lib/atomic64-ops.S | 162 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 236 insertions(+), 5 deletions(-) create mode 100644 arch/frv/lib/atomic64-ops.S (limited to 'arch/frv') diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h index 0409d981fd3..00a57af79af 100644 --- a/arch/frv/include/asm/atomic.h +++ b/arch/frv/include/asm/atomic.h @@ -121,10 +121,72 @@ static inline void atomic_dec(atomic_t *v) #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) +/* + * 64-bit atomic ops + */ +typedef struct { + volatile long long counter; +} atomic64_t; + +#define ATOMIC64_INIT(i) { (i) } + +static inline long long atomic64_read(atomic64_t *v) +{ + long long counter; + + asm("ldd%I1 %M1,%0" + : "=e"(counter) + : "m"(v->counter)); + return counter; +} + +static inline void atomic64_set(atomic64_t *v, long long i) +{ + asm volatile("std%I0 %1,%M0" + : "=m"(v->counter) + : "e"(i)); +} + +extern long long atomic64_inc_return(atomic64_t *v); +extern long long atomic64_dec_return(atomic64_t *v); +extern long long atomic64_add_return(long long i, atomic64_t *v); +extern long long atomic64_sub_return(long long i, atomic64_t *v); + +static inline long long atomic64_add_negative(long long i, atomic64_t *v) +{ + return atomic64_add_return(i, v) < 0; +} + +static inline void atomic64_add(long long i, atomic64_t *v) +{ + atomic64_add_return(i, v); +} + +static inline void atomic64_sub(long long i, atomic64_t *v) +{ + atomic64_sub_return(i, v); +} + +static inline void atomic64_inc(atomic64_t *v) +{ + atomic64_inc_return(v); +} + +static inline void atomic64_dec(atomic64_t *v) +{ + atomic64_dec_return(v); +} + +#define atomic64_sub_and_test(i,v) (atomic64_sub_return((i), (v)) == 0) +#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) +#define atomic64_inc_and_test(v) (atomic64_inc_return((v)) == 0) + /*****************************************************************************/ /* * exchange value with memory */ +extern uint64_t __xchg_64(uint64_t i, volatile void *v); + #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS #define xchg(ptr, x) \ @@ -174,8 +236,10 @@ extern uint32_t __xchg_32(uint32_t i, volatile void *v); #define tas(ptr) (xchg((ptr), 1)) -#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) -#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) +#define atomic_cmpxchg(v, old, new) (cmpxchg(&(v)->counter, old, new)) +#define atomic_xchg(v, new) (xchg(&(v)->counter, new)) +#define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter)) +#define atomic64_xchg(v, new) (__xchg_64(new, &(v)->counter)) static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) { diff --git a/arch/frv/include/asm/system.h b/arch/frv/include/asm/system.h index 7742ec000cc..efd22d9077a 100644 --- a/arch/frv/include/asm/system.h +++ b/arch/frv/include/asm/system.h @@ -208,6 +208,8 @@ extern void free_initmem(void); * - if (*ptr == test) then orig = *ptr; *ptr = test; * - if (*ptr != test) then orig = *ptr; */ +extern uint64_t __cmpxchg_64(uint64_t test, uint64_t new, volatile uint64_t *v); + #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS #define cmpxchg(ptr, test, new) \ diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c index 0316b3c50ef..a89803b58b9 100644 --- a/arch/frv/kernel/frv_ksyms.c +++ b/arch/frv/kernel/frv_ksyms.c @@ -67,6 +67,10 @@ EXPORT_SYMBOL(atomic_sub_return); EXPORT_SYMBOL(__xchg_32); EXPORT_SYMBOL(__cmpxchg_32); #endif +EXPORT_SYMBOL(atomic64_add_return); +EXPORT_SYMBOL(atomic64_sub_return); +EXPORT_SYMBOL(__xchg_64); +EXPORT_SYMBOL(__cmpxchg_64); EXPORT_SYMBOL(__debug_bug_printk); EXPORT_SYMBOL(__delay_loops_MHz); diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile index 08be305c9f4..4ff2fb1e6b1 100644 --- a/arch/frv/lib/Makefile +++ b/arch/frv/lib/Makefile @@ -4,5 +4,5 @@ lib-y := \ __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \ - checksum.o memcpy.o memset.o atomic-ops.o \ + checksum.o memcpy.o memset.o atomic-ops.o atomic64-ops.o \ outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o diff --git a/arch/frv/lib/atomic-ops.S b/arch/frv/lib/atomic-ops.S index ee0ac905fb0..5e9e6ab5dd0 100644 --- a/arch/frv/lib/atomic-ops.S +++ b/arch/frv/lib/atomic-ops.S @@ -163,11 +163,10 @@ __cmpxchg_32: ld.p @(gr11,gr0),gr8 orcr cc7,cc7,cc3 subcc gr8,gr9,gr7,icc0 - bne icc0,#0,1f + bnelr icc0,#0 cst.p gr10,@(gr11,gr0) ,cc3,#1 corcc gr29,gr29,gr0 ,cc3,#1 beq icc3,#0,0b -1: bralr .size __cmpxchg_32, .-__cmpxchg_32 diff --git a/arch/frv/lib/atomic64-ops.S b/arch/frv/lib/atomic64-ops.S new file mode 100644 index 00000000000..b6194eeac12 --- /dev/null +++ b/arch/frv/lib/atomic64-ops.S @@ -0,0 +1,162 @@ +/* kernel atomic64 operations + * + * For an explanation of how atomic ops work in this arch, see: + * Documentation/frv/atomic-ops.txt + * + * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include + + .text + .balign 4 + + +############################################################################### +# +# long long atomic64_inc_return(atomic64_t *v) +# +############################################################################### + .globl atomic64_inc_return + .type atomic64_inc_return,@function +atomic64_inc_return: + or.p gr8,gr8,gr10 +0: + orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ + ckeq icc3,cc7 + ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ + orcr cc7,cc7,cc3 /* set CC3 to true */ + addicc gr9,#1,gr9,icc0 + addxi gr8,#0,gr8,icc0 + cstd.p gr8,@(gr10,gr0) ,cc3,#1 + corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ + beq icc3,#0,0b + bralr + + .size atomic64_inc_return, .-atomic64_inc_return + +############################################################################### +# +# long long atomic64_dec_return(atomic64_t *v) +# +############################################################################### + .globl atomic64_dec_return + .type atomic64_dec_return,@function +atomic64_dec_return: + or.p gr8,gr8,gr10 +0: + orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ + ckeq icc3,cc7 + ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ + orcr cc7,cc7,cc3 /* set CC3 to true */ + subicc gr9,#1,gr9,icc0 + subxi gr8,#0,gr8,icc0 + cstd.p gr8,@(gr10,gr0) ,cc3,#1 + corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ + beq icc3,#0,0b + bralr + + .size atomic64_dec_return, .-atomic64_dec_return + +############################################################################### +# +# long long atomic64_add_return(long long i, atomic64_t *v) +# +############################################################################### + .globl atomic64_add_return + .type atomic64_add_return,@function +atomic64_add_return: + or.p gr8,gr8,gr4 + or gr9,gr9,gr5 +0: + orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ + ckeq icc3,cc7 + ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ + orcr cc7,cc7,cc3 /* set CC3 to true */ + addcc gr9,gr5,gr9,icc0 + addx gr8,gr4,gr8,icc0 + cstd.p gr8,@(gr10,gr0) ,cc3,#1 + corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ + beq icc3,#0,0b + bralr + + .size atomic64_add_return, .-atomic64_add_return + +############################################################################### +# +# long long atomic64_sub_return(long long i, atomic64_t *v) +# +############################################################################### + .globl atomic64_sub_return + .type atomic64_sub_return,@function +atomic64_sub_return: + or.p gr8,gr8,gr4 + or gr9,gr9,gr5 +0: + orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ + ckeq icc3,cc7 + ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ + orcr cc7,cc7,cc3 /* set CC3 to true */ + subcc gr9,gr5,gr9,icc0 + subx gr8,gr4,gr8,icc0 + cstd.p gr8,@(gr10,gr0) ,cc3,#1 + corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ + beq icc3,#0,0b + bralr + + .size atomic64_sub_return, .-atomic64_sub_return + +############################################################################### +# +# uint64_t __xchg_64(uint64_t i, uint64_t *v) +# +############################################################################### + .globl __xchg_64 + .type __xchg_64,@function +__xchg_64: + or.p gr8,gr8,gr4 + or gr9,gr9,gr5 +0: + orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ + ckeq icc3,cc7 + ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */ + orcr cc7,cc7,cc3 /* set CC3 to true */ + cstd.p gr4,@(gr10,gr0) ,cc3,#1 + corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ + beq icc3,#0,0b + bralr + + .size __xchg_64, .-__xchg_64 + +############################################################################### +# +# uint64_t __cmpxchg_64(uint64_t test, uint64_t new, uint64_t *v) +# +############################################################################### + .globl __cmpxchg_64 + .type __cmpxchg_64,@function +__cmpxchg_64: + or.p gr8,gr8,gr4 + or gr9,gr9,gr5 +0: + orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ + ckeq icc3,cc7 + ldd.p @(gr12,gr0),gr8 /* LDD.P/ORCR must be atomic */ + orcr cc7,cc7,cc3 + subcc gr8,gr4,gr0,icc0 + subcc.p gr9,gr5,gr0,icc1 + bnelr icc0,#0 + bnelr icc1,#0 + cstd.p gr10,@(gr12,gr0) ,cc3,#1 + corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ + beq icc3,#0,0b + bralr + + .size __cmpxchg_64, .-__cmpxchg_64 + -- cgit v1.2.3 From 42ca4fb69126dd9d0e25112edca1cacf846aa5c3 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 2 Jul 2009 00:46:21 +0100 Subject: FRV: Add basic performance counter support Add basic performance counter support to the FRV arch. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/frv/Kconfig | 1 + arch/frv/include/asm/perf_counter.h | 17 +++++++++++++++++ arch/frv/lib/Makefile | 2 +- arch/frv/lib/perf_counter.c | 19 +++++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 arch/frv/include/asm/perf_counter.h create mode 100644 arch/frv/lib/perf_counter.c (limited to 'arch/frv') diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index 8a5bd7a9c6f..b86e19c9b5b 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -7,6 +7,7 @@ config FRV default y select HAVE_IDE select HAVE_ARCH_TRACEHOOK + select HAVE_PERF_COUNTERS config ZONE_DMA bool diff --git a/arch/frv/include/asm/perf_counter.h b/arch/frv/include/asm/perf_counter.h new file mode 100644 index 00000000000..ccf726e61b2 --- /dev/null +++ b/arch/frv/include/asm/perf_counter.h @@ -0,0 +1,17 @@ +/* FRV performance counter support + * + * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_PERF_COUNTER_H +#define _ASM_PERF_COUNTER_H + +#define PERF_COUNTER_INDEX_OFFSET 0 + +#endif /* _ASM_PERF_COUNTER_H */ diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile index 4ff2fb1e6b1..0a377210c89 100644 --- a/arch/frv/lib/Makefile +++ b/arch/frv/lib/Makefile @@ -5,4 +5,4 @@ lib-y := \ __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \ checksum.o memcpy.o memset.o atomic-ops.o atomic64-ops.o \ - outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o + outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o perf_counter.o diff --git a/arch/frv/lib/perf_counter.c b/arch/frv/lib/perf_counter.c new file mode 100644 index 00000000000..2000feecd57 --- /dev/null +++ b/arch/frv/lib/perf_counter.c @@ -0,0 +1,19 @@ +/* Performance counter handling + * + * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#include + +/* + * mark the performance counter as pending + */ +void set_perf_counter_pending(void) +{ +} -- cgit v1.2.3