diff options
| author | David Mosberger <davidm@tiger.hpl.hp.com> | 2003-08-20 22:24:49 -0700 |
|---|---|---|
| committer | David Mosberger <davidm@tiger.hpl.hp.com> | 2003-08-20 22:24:49 -0700 |
| commit | 11d034171b0ef884101137e9d799757dec45cbe6 (patch) | |
| tree | e52a5fc2e16977d4654679945d95eda2b2dc2c61 /include | |
| parent | be974925bc048c419f66e49b3744d98208e54831 (diff) | |
| parent | 8417a5d6208af9e0cc582c69b0e35964443f14d5 (diff) | |
Merge tiger.hpl.hp.com:/data1/bk/vanilla/linux-2.5
into tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-ia64/atomic.h | 8 | ||||
| -rw-r--r-- | include/asm-ia64/bitops.h | 8 | ||||
| -rw-r--r-- | include/asm-ia64/byteorder.h | 3 | ||||
| -rw-r--r-- | include/asm-ia64/current.h | 10 | ||||
| -rw-r--r-- | include/asm-ia64/delay.h | 32 | ||||
| -rw-r--r-- | include/asm-ia64/gcc_intrin.h | 584 | ||||
| -rw-r--r-- | include/asm-ia64/ia64regs.h | 100 | ||||
| -rw-r--r-- | include/asm-ia64/intrinsics.h | 101 | ||||
| -rw-r--r-- | include/asm-ia64/io.h | 3 | ||||
| -rw-r--r-- | include/asm-ia64/machvec.h | 2 | ||||
| -rw-r--r-- | include/asm-ia64/mmu_context.h | 2 | ||||
| -rw-r--r-- | include/asm-ia64/page.h | 3 | ||||
| -rw-r--r-- | include/asm-ia64/pal.h | 4 | ||||
| -rw-r--r-- | include/asm-ia64/processor.h | 422 | ||||
| -rw-r--r-- | include/asm-ia64/rwsem.h | 12 | ||||
| -rw-r--r-- | include/asm-ia64/sal.h | 4 | ||||
| -rw-r--r-- | include/asm-ia64/siginfo.h | 1 | ||||
| -rw-r--r-- | include/asm-ia64/smp.h | 2 | ||||
| -rw-r--r-- | include/asm-ia64/sn/sn2/io.h | 34 | ||||
| -rw-r--r-- | include/asm-ia64/sn/sn_cpuid.h | 6 | ||||
| -rw-r--r-- | include/asm-ia64/spinlock.h | 12 | ||||
| -rw-r--r-- | include/asm-ia64/system.h | 44 | ||||
| -rw-r--r-- | include/asm-ia64/timex.h | 3 | ||||
| -rw-r--r-- | include/asm-ia64/tlbflush.h | 3 | ||||
| -rw-r--r-- | include/asm-ia64/unistd.h | 67 |
25 files changed, 940 insertions, 530 deletions
diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h index 5b88749e54b2..f2e179d4bb76 100644 --- a/include/asm-ia64/atomic.h +++ b/include/asm-ia64/atomic.h @@ -42,7 +42,7 @@ ia64_atomic_add (int i, atomic_t *v) CMPXCHG_BUGCHECK(v); old = atomic_read(v); new = old + i; - } while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old); + } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); return new; } @@ -56,7 +56,7 @@ ia64_atomic64_add (__s64 i, atomic64_t *v) CMPXCHG_BUGCHECK(v); old = atomic_read(v); new = old + i; - } while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old); + } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); return new; } @@ -70,7 +70,7 @@ ia64_atomic_sub (int i, atomic_t *v) CMPXCHG_BUGCHECK(v); old = atomic_read(v); new = old - i; - } while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old); + } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); return new; } @@ -84,7 +84,7 @@ ia64_atomic64_sub (__s64 i, atomic64_t *v) CMPXCHG_BUGCHECK(v); old = atomic_read(v); new = old - i; - } while (ia64_cmpxchg("acq", v, old, new, sizeof(atomic_t)) != old); + } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); return new; } diff --git a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h index af15c6694522..502f51a1a0ee 100644 --- a/include/asm-ia64/bitops.h +++ b/include/asm-ia64/bitops.h @@ -292,7 +292,7 @@ ffz (unsigned long x) { unsigned long result; - __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (x & (~x - 1))); + result = ia64_popcnt(x & (~x - 1)); return result; } @@ -307,7 +307,7 @@ __ffs (unsigned long x) { unsigned long result; - __asm__ ("popcnt %0=%1" : "=r" (result) : "r" ((x - 1) & ~x)); + result = ia64_popcnt((x-1) & ~x); return result; } @@ -323,7 +323,7 @@ ia64_fls (unsigned long x) long double d = x; long exp; - __asm__ ("getf.exp %0=%1" : "=r"(exp) : "f"(d)); + exp = ia64_getf_exp(d); return exp - 0xffff; } @@ -349,7 +349,7 @@ static __inline__ unsigned long hweight64 (unsigned long x) { unsigned long result; - __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (x)); + result = ia64_popcnt(x); return result; } diff --git a/include/asm-ia64/byteorder.h b/include/asm-ia64/byteorder.h index a4e3abfc3477..434686fccb95 100644 --- a/include/asm-ia64/byteorder.h +++ b/include/asm-ia64/byteorder.h @@ -7,13 +7,14 @@ */ #include <asm/types.h> +#include <asm/intrinsics.h> static __inline__ __const__ __u64 __ia64_swab64 (__u64 x) { __u64 result; - __asm__ ("mux1 %0=%1,@rev" : "=r" (result) : "r" (x)); + result = ia64_mux1(x, ia64_mux1_rev); return result; } diff --git a/include/asm-ia64/current.h b/include/asm-ia64/current.h index 73a5edf825b8..8e316f179815 100644 --- a/include/asm-ia64/current.h +++ b/include/asm-ia64/current.h @@ -6,8 +6,12 @@ * David Mosberger-Tang <davidm@hpl.hp.com> */ -/* In kernel mode, thread pointer (r13) is used to point to the - current task structure. */ -register struct task_struct *current asm ("r13"); +#include <asm/intrinsics.h> + +/* + * In kernel mode, thread pointer (r13) is used to point to the current task + * structure. + */ +#define current ((struct task_struct *) ia64_getreg(_IA64_REG_TP)) #endif /* _ASM_IA64_CURRENT_H */ diff --git a/include/asm-ia64/delay.h b/include/asm-ia64/delay.h index da812415f634..74c542acc1e8 100644 --- a/include/asm-ia64/delay.h +++ b/include/asm-ia64/delay.h @@ -5,7 +5,7 @@ * Delay routines using a pre-computed "cycles/usec" value. * * Copyright (C) 1998, 1999 Hewlett-Packard Co - * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> + * David Mosberger-Tang <davidm@hpl.hp.com> * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 Walt Drummond <drummond@valinux.com> * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com> @@ -17,12 +17,14 @@ #include <linux/sched.h> #include <linux/compiler.h> +#include <asm/intrinsics.h> #include <asm/processor.h> static __inline__ void ia64_set_itm (unsigned long val) { - __asm__ __volatile__("mov cr.itm=%0;; srlz.d;;" :: "r"(val) : "memory"); + ia64_setreg(_IA64_REG_CR_ITM, val); + ia64_srlz_d(); } static __inline__ unsigned long @@ -30,20 +32,23 @@ ia64_get_itm (void) { unsigned long result; - __asm__ __volatile__("mov %0=cr.itm;; srlz.d;;" : "=r"(result) :: "memory"); + result = ia64_getreg(_IA64_REG_CR_ITM); + ia64_srlz_d(); return result; } static __inline__ void ia64_set_itv (unsigned long val) { - __asm__ __volatile__("mov cr.itv=%0;; srlz.d;;" :: "r"(val) : "memory"); + ia64_setreg(_IA64_REG_CR_ITV, val); + ia64_srlz_d(); } static __inline__ void ia64_set_itc (unsigned long val) { - __asm__ __volatile__("mov ar.itc=%0;; srlz.d;;" :: "r"(val) : "memory"); + ia64_setreg(_IA64_REG_AR_ITC, val); + ia64_srlz_d(); } static __inline__ unsigned long @@ -51,10 +56,13 @@ ia64_get_itc (void) { unsigned long result; - __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); + result = ia64_getreg(_IA64_REG_AR_ITC); + ia64_barrier(); #ifdef CONFIG_ITANIUM - while (unlikely((__s32) result == -1)) - __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); + while (unlikely((__s32) result == -1)) { + result = ia64_getreg(_IA64_REG_AR_ITC); + ia64_barrier(); + } #endif return result; } @@ -62,15 +70,11 @@ ia64_get_itc (void) static __inline__ void __delay (unsigned long loops) { - unsigned long saved_ar_lc; - if (loops < 1) return; - __asm__ __volatile__("mov %0=ar.lc;;" : "=r"(saved_ar_lc)); - __asm__ __volatile__("mov ar.lc=%0;;" :: "r"(loops - 1)); - __asm__ __volatile__("1:\tbr.cloop.sptk.few 1b;;"); - __asm__ __volatile__("mov ar.lc=%0" :: "r"(saved_ar_lc)); + while (loops--) + ia64_nop(0); } static __inline__ void diff --git a/include/asm-ia64/gcc_intrin.h b/include/asm-ia64/gcc_intrin.h new file mode 100644 index 000000000000..5175f0345555 --- /dev/null +++ b/include/asm-ia64/gcc_intrin.h @@ -0,0 +1,584 @@ +#ifndef _ASM_IA64_GCC_INTRIN_H +#define _ASM_IA64_GCC_INTRIN_H +/* + * + * Copyright (C) 2002,2003 Jun Nakajima <jun.nakajima@intel.com> + * Copyright (C) 2002,2003 Suresh Siddha <suresh.b.siddha@intel.com> + * + */ + +/* define this macro to get some asm stmts included in 'c' files */ +#define ASM_SUPPORTED + +/* Optimization barrier */ +/* The "volatile" is due to gcc bugs */ +#define ia64_barrier() asm volatile ("":::"memory") + +#define ia64_stop() asm volatile (";;"::) + +#define ia64_invala_gr(regnum) asm volatile ("invala.e r%0" :: "i"(regnum)) + +#define ia64_invala_fr(regnum) asm volatile ("invala.e f%0" :: "i"(regnum)) + +extern void ia64_bad_param_for_setreg (void); +extern void ia64_bad_param_for_getreg (void); + +#define ia64_setreg(regnum, val) \ +({ \ + switch (regnum) { \ + case _IA64_REG_PSR_L: \ + asm volatile ("mov psr.l=%0" :: "r"(val) : "memory"); \ + break; \ + case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \ + asm volatile ("mov ar%0=%1" :: \ + "i" (regnum - _IA64_REG_AR_KR0), \ + "r"(val): "memory"); \ + break; \ + case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \ + asm volatile ("mov cr%0=%1" :: \ + "i" (regnum - _IA64_REG_CR_DCR), \ + "r"(val): "memory" ); \ + break; \ + case _IA64_REG_SP: \ + asm volatile ("mov r12=%0" :: \ + "r"(val): "memory"); \ + break; \ + case _IA64_REG_GP: \ + asm volatile ("mov gp=%0" :: "r"(val) : "memory"); \ + break; \ + default: \ + ia64_bad_param_for_setreg(); \ + break; \ + } \ +}) + +#define ia64_getreg(regnum) \ +({ \ + __u64 ia64_intri_res; \ + \ + switch (regnum) { \ + case _IA64_REG_GP: \ + asm volatile ("mov %0=gp" : "=r"(ia64_intri_res)); \ + break; \ + case _IA64_REG_IP: \ + asm volatile ("mov %0=ip" : "=r"(ia64_intri_res)); \ + break; \ + case _IA64_REG_PSR: \ + asm volatile ("mov %0=psr" : "=r"(ia64_intri_res)); \ + break; \ + case _IA64_REG_TP: /* for current() */ \ + { \ + register __u64 ia64_r13 asm ("r13"); \ + ia64_intri_res = ia64_r13; \ + } \ + break; \ + case _IA64_REG_AR_KR0 ... _IA64_REG_AR_EC: \ + asm volatile ("mov %0=ar%1" : "=r" (ia64_intri_res) \ + : "i"(regnum - _IA64_REG_AR_KR0)); \ + break; \ + case _IA64_REG_CR_DCR ... _IA64_REG_CR_LRR1: \ + asm volatile ("mov %0=cr%1" : "=r" (ia64_intri_res) \ + : "i" (regnum - _IA64_REG_CR_DCR)); \ + break; \ + case _IA64_REG_SP: \ + asm volatile ("mov %0=sp" : "=r" (ia64_intri_res)); \ + break; \ + default: \ + ia64_bad_param_for_getreg(); \ + break; \ + } \ + ia64_intri_res; \ +}) + +#define ia64_hint_pause 0 + +#define ia64_hint(mode) \ +({ \ + switch (mode) { \ + case ia64_hint_pause: \ + asm volatile ("hint @pause" ::: "memory"); \ + break; \ + } \ +}) + + +/* Integer values for mux1 instruction */ +#define ia64_mux1_brcst 0 +#define ia64_mux1_mix 8 +#define ia64_mux1_shuf 9 +#define ia64_mux1_alt 10 +#define ia64_mux1_rev 11 + +#define ia64_mux1(x, mode) \ +({ \ + __u64 ia64_intri_res; \ + \ + switch (mode) { \ + case ia64_mux1_brcst: \ + asm ("mux1 %0=%1,@brcst" : "=r" (ia64_intri_res) : "r" (x)); \ + break; \ + case ia64_mux1_mix: \ + asm ("mux1 %0=%1,@mix" : "=r" (ia64_intri_res) : "r" (x)); \ + break; \ + case ia64_mux1_shuf: \ + asm ("mux1 %0=%1,@shuf" : "=r" (ia64_intri_res) : "r" (x)); \ + break; \ + case ia64_mux1_alt: \ + asm ("mux1 %0=%1,@alt" : "=r" (ia64_intri_res) : "r" (x)); \ + break; \ + case ia64_mux1_rev: \ + asm ("mux1 %0=%1,@rev" : "=r" (ia64_intri_res) : "r" (x)); \ + break; \ + } \ + ia64_intri_res; \ +}) + +#define ia64_popcnt(x) \ +({ \ + __u64 ia64_intri_res; \ + asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \ + \ + ia64_intri_res; \ +}) + +#define ia64_getf_exp(x) \ +({ \ + long ia64_intri_res; \ + \ + asm ("getf.exp %0=%1" : "=r"(ia64_intri_res) : "f"(x)); \ + \ + ia64_intri_res; \ +}) + +#define ia64_shrp(a, b, count) \ +({ \ + __u64 ia64_intri_res; \ + asm ("shrp %0=%1,%2,%3" : "=r"(ia64_intri_res) : "r"(a), "r"(b), "i"(count)); \ + ia64_intri_res; \ +}) + +#define ia64_ldfs(regnum, x) \ +({ \ + register double __f__ asm ("f"#regnum); \ + asm volatile ("ldfs %0=[%1]" :"=f"(__f__): "r"(x)); \ +}) + +#define ia64_ldfd(regnum, x) \ +({ \ + register double __f__ asm ("f"#regnum); \ + asm volatile ("ldfd %0=[%1]" :"=f"(__f__): "r"(x)); \ +}) + +#define ia64_ldfe(regnum, x) \ +({ \ + register double __f__ asm ("f"#regnum); \ + asm volatile ("ldfe %0=[%1]" :"=f"(__f__): "r"(x)); \ +}) + +#define ia64_ldf8(regnum, x) \ +({ \ + register double __f__ asm ("f"#regnum); \ + asm volatile ("ldf8 %0=[%1]" :"=f"(__f__): "r"(x)); \ +}) + +#define ia64_ldf_fill(regnum, x) \ +({ \ + register double __f__ asm ("f"#regnum); \ + asm volatile ("ldf.fill %0=[%1]" :"=f"(__f__): "r"(x)); \ +}) + +#define ia64_stfs(x, regnum) \ +({ \ + register double __f__ asm ("f"#regnum); \ + asm volatile ("stfs [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \ +}) + +#define ia64_stfd(x, regnum) \ +({ \ + register double __f__ asm ("f"#regnum); \ + asm volatile ("stfd [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \ +}) + +#define ia64_stfe(x, regnum) \ +({ \ + register double __f__ asm ("f"#regnum); \ + asm volatile ("stfe [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \ +}) + +#define ia64_stf8(x, regnum) \ +({ \ + register double __f__ asm ("f"#regnum); \ + asm volatile ("stf8 [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \ +}) + +#define ia64_stf_spill(x, regnum) \ +({ \ + register double __f__ asm ("f"#regnum); \ + asm volatile ("stf.spill [%0]=%1" :: "r"(x), "f"(__f__) : "memory"); \ +}) + +#define ia64_fetchadd4_acq(p, inc) \ +({ \ + \ + __u64 ia64_intri_res; \ + asm volatile ("fetchadd4.acq %0=[%1],%2" \ + : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \ + : "memory"); \ + \ + ia64_intri_res; \ +}) + +#define ia64_fetchadd4_rel(p, inc) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("fetchadd4.rel %0=[%1],%2" \ + : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \ + : "memory"); \ + \ + ia64_intri_res; \ +}) + +#define ia64_fetchadd8_acq(p, inc) \ +({ \ + \ + __u64 ia64_intri_res; \ + asm volatile ("fetchadd8.acq %0=[%1],%2" \ + : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \ + : "memory"); \ + \ + ia64_intri_res; \ +}) + +#define ia64_fetchadd8_rel(p, inc) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("fetchadd8.rel %0=[%1],%2" \ + : "=r"(ia64_intri_res) : "r"(p), "i" (inc) \ + : "memory"); \ + \ + ia64_intri_res; \ +}) + +#define ia64_xchg1(ptr,x) \ +({ \ + __u64 ia64_intri_res; \ + asm __volatile ("xchg1 %0=[%1],%2" : "=r" (ia64_intri_res) \ + : "r" (ptr), "r" (x) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_xchg2(ptr,x) \ +({ \ + __u64 ia64_intri_res; \ + asm __volatile ("xchg2 %0=[%1],%2" : "=r" (ia64_intri_res) \ + : "r" (ptr), "r" (x) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_xchg4(ptr,x) \ +({ \ + __u64 ia64_intri_res; \ + asm __volatile ("xchg4 %0=[%1],%2" : "=r" (ia64_intri_res) \ + : "r" (ptr), "r" (x) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_xchg8(ptr,x) \ +({ \ + __u64 ia64_intri_res; \ + asm __volatile ("xchg8 %0=[%1],%2" : "=r" (ia64_intri_res) \ + : "r" (ptr), "r" (x) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_cmpxchg1_acq(ptr, new, old) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ + asm volatile ("cmpxchg1.acq %0=[%1],%2,ar.ccv": \ + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_cmpxchg1_rel(ptr, new, old) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ + asm volatile ("cmpxchg1.rel %0=[%1],%2,ar.ccv": \ + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_cmpxchg2_acq(ptr, new, old) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ + asm volatile ("cmpxchg2.acq %0=[%1],%2,ar.ccv": \ + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_cmpxchg2_rel(ptr, new, old) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ + \ + asm volatile ("cmpxchg2.rel %0=[%1],%2,ar.ccv": \ + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_cmpxchg4_acq(ptr, new, old) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ + asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv": \ + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_cmpxchg4_rel(ptr, new, old) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ + asm volatile ("cmpxchg4.rel %0=[%1],%2,ar.ccv": \ + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_cmpxchg8_acq(ptr, new, old) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ + asm volatile ("cmpxchg8.acq %0=[%1],%2,ar.ccv": \ + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_cmpxchg8_rel(ptr, new, old) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ + \ + asm volatile ("cmpxchg8.rel %0=[%1],%2,ar.ccv": \ + "=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ + ia64_intri_res; \ +}) + +#define ia64_mf() asm volatile ("mf" ::: "memory") +#define ia64_mfa() asm volatile ("mf.a" ::: "memory") + +#define ia64_invala() asm volatile ("invala" ::: "memory") + +#define ia64_thash(addr) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("thash %0=%1" : "=r"(ia64_intri_res) : "r" (addr)); \ + ia64_intri_res; \ +}) + +#define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory") + +#define ia64_srlz_d() asm volatile (";; srlz.d" ::: "memory"); + +#define ia64_nop(x) asm volatile ("nop %0"::"i"(x)); + +#define ia64_itci(addr) asm volatile ("itc.i %0;;" :: "r"(addr) : "memory") + +#define ia64_itcd(addr) asm volatile ("itc.d %0;;" :: "r"(addr) : "memory") + + +#define ia64_itri(trnum, addr) asm volatile ("itr.i itr[%0]=%1" \ + :: "r"(trnum), "r"(addr) : "memory") + +#define ia64_itrd(trnum, addr) asm volatile ("itr.d dtr[%0]=%1" \ + :: "r"(trnum), "r"(addr) : "memory") + +#define ia64_tpa(addr) \ +({ \ + __u64 ia64_pa; \ + asm volatile ("tpa %0 = %1" : "=r"(ia64_pa) : "r"(addr) : "memory"); \ + ia64_pa; \ +}) + +#define __ia64_set_dbr(index, val) \ + asm volatile ("mov dbr[%0]=%1" :: "r"(index), "r"(val) : "memory") + +#define ia64_set_ibr(index, val) \ + asm volatile ("mov ibr[%0]=%1" :: "r"(index), "r"(val) : "memory") + +#define ia64_set_pkr(index, val) \ + asm volatile ("mov pkr[%0]=%1" :: "r"(index), "r"(val) : "memory") + +#define ia64_set_pmc(index, val) \ + asm volatile ("mov pmc[%0]=%1" :: "r"(index), "r"(val) : "memory") + +#define ia64_set_pmd(index, val) \ + asm volatile ("mov pmd[%0]=%1" :: "r"(index), "r"(val) : "memory") + +#define ia64_set_rr(index, val) \ + asm volatile ("mov rr[%0]=%1" :: "r"(index), "r"(val) : "memory"); + +#define ia64_get_cpuid(index) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov %0=cpuid[%r1]" : "=r"(ia64_intri_res) : "rO"(index)); \ + ia64_intri_res; \ +}) + +#define __ia64_get_dbr(index) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov %0=dbr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ + ia64_intri_res; \ +}) + +#define ia64_get_ibr(index) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov %0=ibr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ + ia64_intri_res; \ +}) + +#define ia64_get_pkr(index) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov %0=pkr[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ + ia64_intri_res; \ +}) + +#define ia64_get_pmc(index) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov %0=pmc[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ + ia64_intri_res; \ +}) + + +#define ia64_get_pmd(index) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov %0=pmd[%1]" : "=r"(ia64_intri_res) : "r"(index)); \ + ia64_intri_res; \ +}) + +#define ia64_get_rr(index) \ +({ \ + __u64 ia64_intri_res; \ + asm volatile ("mov %0=rr[%1]" : "=r"(ia64_intri_res) : "r" (index)); \ + ia64_intri_res; \ +}) + +#define ia64_fc(addr) asm volatile ("fc %0" :: "r"(addr) : "memory") + + +#define ia64_sync_i() asm volatile (";; sync.i" ::: "memory") + +#define ia64_ssm(mask) asm volatile ("ssm %0":: "i"((mask)) : "memory") +#define ia64_rsm(mask) asm volatile ("rsm %0":: "i"((mask)) : "memory") +#define ia64_sum(mask) asm volatile ("sum %0":: "i"((mask)) : "memory") +#define ia64_rum(mask) asm volatile ("rum %0":: "i"((mask)) : "memory") + +#define ia64_ptce(addr) asm volatile ("ptc.e %0" :: "r"(addr)) + +#define ia64_ptcga(addr, size) \ + asm volatile ("ptc.ga %0,%1" :: "r"(addr), "r"(size) : "memory") + +#define ia64_ptcl(addr, size) \ + asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(size) : "memory") + +#define ia64_ptri(addr, size) \ + asm volatile ("ptr.i %0,%1" :: "r"(addr), "r"(size) : "memory") + +#define ia64_ptrd(addr, size) \ + asm volatile ("ptr.d %0,%1" :: "r"(addr), "r"(size) : "memory") + +/* Values for lfhint in ia64_lfetch and ia64_lfetch_fault */ + +#define ia64_lfhint_none 0 +#define ia64_lfhint_nt1 1 +#define ia64_lfhint_nt2 2 +#define ia64_lfhint_nta 3 + +#define ia64_lfetch(lfhint, y) \ +({ \ + switch (lfhint) { \ + case ia64_lfhint_none: \ + asm volatile ("lfetch [%0]" : : "r"(y)); \ + break; \ + case ia64_lfhint_nt1: \ + asm volatile ("lfetch.nt1 [%0]" : : "r"(y)); \ + break; \ + case ia64_lfhint_nt2: \ + asm volatile ("lfetch.nt2 [%0]" : : "r"(y)); \ + break; \ + case ia64_lfhint_nta: \ + asm volatile ("lfetch.nta [%0]" : : "r"(y)); \ + break; \ + } \ +}) + +#define ia64_lfetch_excl(lfhint, y) \ +({ \ + switch (lfhint) { \ + case ia64_lfhint_none: \ + asm volatile ("lfetch.excl [%0]" :: "r"(y)); \ + break; \ + case ia64_lfhint_nt1: \ + asm volatile ("lfetch.excl.nt1 [%0]" :: "r"(y)); \ + break; \ + case ia64_lfhint_nt2: \ + asm volatile ("lfetch.excl.nt2 [%0]" :: "r"(y)); \ + break; \ + case ia64_lfhint_nta: \ + asm volatile ("lfetch.excl.nta [%0]" :: "r"(y)); \ + break; \ + } \ +}) + +#define ia64_lfetch_fault(lfhint, y) \ +({ \ + switch (lfhint) { \ + case ia64_lfhint_none: \ + asm volatile ("lfetch.fault [%0]" : : "r"(y)); \ + break; \ + case ia64_lfhint_nt1: \ + asm volatile ("lfetch.fault.nt1 [%0]" : : "r"(y)); \ + break; \ + case ia64_lfhint_nt2: \ + asm volatile ("lfetch.fault.nt2 [%0]" : : "r"(y)); \ + break; \ + case ia64_lfhint_nta: \ + asm volatile ("lfetch.fault.nta [%0]" : : "r"(y)); \ + break; \ + } \ +}) + +#define ia64_lfetch_fault_excl(lfhint, y) \ +({ \ + switch (lfhint) { \ + case ia64_lfhint_none: \ + asm volatile ("lfetch.fault.excl [%0]" :: "r"(y)); \ + break; \ + case ia64_lfhint_nt1: \ + asm volatile ("lfetch.fault.excl.nt1 [%0]" :: "r"(y)); \ + break; \ + case ia64_lfhint_nt2: \ + asm volatile ("lfetch.fault.excl.nt2 [%0]" :: "r"(y)); \ + break; \ + case ia64_lfhint_nta: \ + asm volatile ("lfetch.fault.excl.nta [%0]" :: "r"(y)); \ + break; \ + } \ +}) + +#define ia64_intrin_local_irq_restore(x) \ +do { \ + asm volatile (" cmp.ne p6,p7=%0,r0;;" \ + "(p6) ssm psr.i;" \ + "(p7) rsm psr.i;;" \ + "(p6) srlz.d" \ + :: "r"((x)) : "p6", "p7", "memory"); \ +} while (0) + +#endif /* _ASM_IA64_GCC_INTRIN_H */ diff --git a/include/asm-ia64/ia64regs.h b/include/asm-ia64/ia64regs.h new file mode 100644 index 000000000000..1757f1c11ad4 --- /dev/null +++ b/include/asm-ia64/ia64regs.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2002,2003 Intel Corp. + * Jun Nakajima <jun.nakajima@intel.com> + * Suresh Siddha <suresh.b.siddha@intel.com> + */ + +#ifndef _ASM_IA64_IA64REGS_H +#define _ASM_IA64_IA64REGS_H + +/* + * Register Names for getreg() and setreg(). + * + * The "magic" numbers happen to match the values used by the Intel compiler's + * getreg()/setreg() intrinsics. + */ + +/* Special Registers */ + +#define _IA64_REG_IP 1016 /* getreg only */ +#define _IA64_REG_PSR 1019 +#define _IA64_REG_PSR_L 1019 + +/* General Integer Registers */ + +#define _IA64_REG_GP 1025 /* R1 */ +#define _IA64_REG_R8 1032 /* R8 */ +#define _IA64_REG_R9 1033 /* R9 */ +#define _IA64_REG_SP 1036 /* R12 */ +#define _IA64_REG_TP 1037 /* R13 */ + +/* Application Registers */ + +#define _IA64_REG_AR_KR0 3072 +#define _IA64_REG_AR_KR1 3073 +#define _IA64_REG_AR_KR2 3074 +#define _IA64_REG_AR_KR3 3075 +#define _IA64_REG_AR_KR4 3076 +#define _IA64_REG_AR_KR5 3077 +#define _IA64_REG_AR_KR6 3078 +#define _IA64_REG_AR_KR7 3079 +#define _IA64_REG_AR_RSC 3088 +#define _IA64_REG_AR_BSP 3089 +#define _IA64_REG_AR_BSPSTORE 3090 +#define _IA64_REG_AR_RNAT 3091 +#define _IA64_REG_AR_FCR 3093 +#define _IA64_REG_AR_EFLAG 3096 +#define _IA64_REG_AR_CSD 3097 +#define _IA64_REG_AR_SSD 3098 +#define _IA64_REG_AR_CFLAG 3099 +#define _IA64_REG_AR_FSR 3100 +#define _IA64_REG_AR_FIR 3101 +#define _IA64_REG_AR_FDR 3102 +#define _IA64_REG_AR_CCV 3104 +#define _IA64_REG_AR_UNAT 3108 +#define _IA64_REG_AR_FPSR 3112 +#define _IA64_REG_AR_ITC 3116 +#define _IA64_REG_AR_PFS 3136 +#define _IA64_REG_AR_LC 3137 +#define _IA64_REG_AR_EC 3138 + +/* Control Registers */ + +#define _IA64_REG_CR_DCR 4096 +#define _IA64_REG_CR_ITM 4097 +#define _IA64_REG_CR_IVA 4098 +#define _IA64_REG_CR_PTA 4104 +#define _IA64_REG_CR_IPSR 4112 +#define _IA64_REG_CR_ISR 4113 +#define _IA64_REG_CR_IIP 4115 +#define _IA64_REG_CR_IFA 4116 +#define _IA64_REG_CR_ITIR 4117 +#define _IA64_REG_CR_IIPA 4118 +#define _IA64_REG_CR_IFS 4119 +#define _IA64_REG_CR_IIM 4120 +#define _IA64_REG_CR_IHA 4121 +#define _IA64_REG_CR_LID 4160 +#define _IA64_REG_CR_IVR 4161 /* getreg only */ +#define _IA64_REG_CR_TPR 4162 +#define _IA64_REG_CR_EOI 4163 +#define _IA64_REG_CR_IRR0 4164 /* getreg only */ +#define _IA64_REG_CR_IRR1 4165 /* getreg only */ +#define _IA64_REG_CR_IRR2 4166 /* getreg only */ +#define _IA64_REG_CR_IRR3 4167 /* getreg only */ +#define _IA64_REG_CR_ITV 4168 +#define _IA64_REG_CR_PMV 4169 +#define _IA64_REG_CR_CMCV 4170 +#define _IA64_REG_CR_LRR0 4176 +#define _IA64_REG_CR_LRR1 4177 + +/* Indirect Registers for getindreg() and setindreg() */ + +#define _IA64_REG_INDR_CPUID 9000 /* getindreg only */ +#define _IA64_REG_INDR_DBR 9001 +#define _IA64_REG_INDR_IBR 9002 +#define _IA64_REG_INDR_PKR 9003 +#define _IA64_REG_INDR_PMC 9004 +#define _IA64_REG_INDR_PMD 9005 +#define _IA64_REG_INDR_RR 9006 + +#endif /* _ASM_IA64_IA64REGS_H */ diff --git a/include/asm-ia64/intrinsics.h b/include/asm-ia64/intrinsics.h index 19408747bd17..743049ca0851 100644 --- a/include/asm-ia64/intrinsics.h +++ b/include/asm-ia64/intrinsics.h @@ -8,8 +8,17 @@ * David Mosberger-Tang <davidm@hpl.hp.com> */ +#ifndef __ASSEMBLY__ #include <linux/config.h> +/* include compiler specific intrinsics */ +#include <asm/ia64regs.h> +#ifdef __INTEL_COMPILER +# include <asm/intel_intrin.h> +#else +# include <asm/gcc_intrin.h> +#endif + /* * Force an unresolved reference if someone tries to use * ia64_fetch_and_add() with a bad value. @@ -21,13 +30,11 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void); ({ \ switch (sz) { \ case 4: \ - __asm__ __volatile__ ("fetchadd4."sem" %0=[%1],%2" \ - : "=r"(tmp) : "r"(v), "i"(n) : "memory"); \ + tmp = ia64_fetchadd4_##sem((unsigned int *) v, n); \ break; \ \ case 8: \ - __asm__ __volatile__ ("fetchadd8."sem" %0=[%1],%2" \ - : "=r"(tmp) : "r"(v), "i"(n) : "memory"); \ + tmp = ia64_fetchadd8_##sem((unsigned long *) v, n); \ break; \ \ default: \ @@ -61,43 +68,39 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void); (__typeof__(*(v))) (_tmp); /* return old value */ \ }) -#define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, "rel") + (i)) /* return new value */ +#define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */ /* * This function doesn't exist, so you'll get a linker error if * something tries to do an invalid xchg(). */ -extern void __xchg_called_with_bad_pointer (void); - -static __inline__ unsigned long -__xchg (unsigned long x, volatile void *ptr, int size) -{ - unsigned long result; - - switch (size) { - case 1: - __asm__ __volatile ("xchg1 %0=[%1],%2" : "=r" (result) - : "r" (ptr), "r" (x) : "memory"); - return result; - - case 2: - __asm__ __volatile ("xchg2 %0=[%1],%2" : "=r" (result) - : "r" (ptr), "r" (x) : "memory"); - return result; - - case 4: - __asm__ __volatile ("xchg4 %0=[%1],%2" : "=r" (result) - : "r" (ptr), "r" (x) : "memory"); - return result; - - case 8: - __asm__ __volatile ("xchg8 %0=[%1],%2" : "=r" (result) - : "r" (ptr), "r" (x) : "memory"); - return result; - } - __xchg_called_with_bad_pointer(); - return x; -} +extern void ia64_xchg_called_with_bad_pointer (void); + +#define __xchg(x,ptr,size) \ +({ \ + unsigned long __xchg_result; \ + \ + switch (size) { \ + case 1: \ + __xchg_result = ia64_xchg1((__u8 *)ptr, x); \ + break; \ + \ + case 2: \ + __xchg_result = ia64_xchg2((__u16 *)ptr, x); \ + break; \ + \ + case 4: \ + __xchg_result = ia64_xchg4((__u32 *)ptr, x); \ + break; \ + \ + case 8: \ + __xchg_result = ia64_xchg8((__u64 *)ptr, x); \ + break; \ + default: \ + ia64_xchg_called_with_bad_pointer(); \ + } \ + __xchg_result; \ +}) #define xchg(ptr,x) \ ((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr)))) @@ -114,12 +117,10 @@ __xchg (unsigned long x, volatile void *ptr, int size) * This function doesn't exist, so you'll get a linker error * if something tries to do an invalid cmpxchg(). */ -extern long __cmpxchg_called_with_bad_pointer(void); +extern long ia64_cmpxchg_called_with_bad_pointer (void); #define ia64_cmpxchg(sem,ptr,old,new,size) \ ({ \ - __typeof__(ptr) _p_ = (ptr); \ - __typeof__(new) _n_ = (new); \ __u64 _o_, _r_; \ \ switch (size) { \ @@ -129,37 +130,32 @@ extern long __cmpxchg_called_with_bad_pointer(void); case 8: _o_ = (__u64) (long) (old); break; \ default: break; \ } \ - __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO"(_o_)); \ switch (size) { \ case 1: \ - __asm__ __volatile__ ("cmpxchg1."sem" %0=[%1],%2,ar.ccv" \ - : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ + _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_); \ break; \ \ case 2: \ - __asm__ __volatile__ ("cmpxchg2."sem" %0=[%1],%2,ar.ccv" \ - : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ + _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_); \ break; \ \ case 4: \ - __asm__ __volatile__ ("cmpxchg4."sem" %0=[%1],%2,ar.ccv" \ - : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ + _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_); \ break; \ \ case 8: \ - __asm__ __volatile__ ("cmpxchg8."sem" %0=[%1],%2,ar.ccv" \ - : "=r"(_r_) : "r"(_p_), "r"(_n_) : "memory"); \ + _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_); \ break; \ \ default: \ - _r_ = __cmpxchg_called_with_bad_pointer(); \ + _r_ = ia64_cmpxchg_called_with_bad_pointer(); \ break; \ } \ (__typeof__(old)) _r_; \ }) -#define cmpxchg_acq(ptr,o,n) ia64_cmpxchg("acq", (ptr), (o), (n), sizeof(*(ptr))) -#define cmpxchg_rel(ptr,o,n) ia64_cmpxchg("rel", (ptr), (o), (n), sizeof(*(ptr))) +#define cmpxchg_acq(ptr,o,n) ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr))) +#define cmpxchg_rel(ptr,o,n) ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr))) /* for compatibility with other platforms: */ #define cmpxchg(ptr,o,n) cmpxchg_acq(ptr,o,n) @@ -171,7 +167,7 @@ extern long __cmpxchg_called_with_bad_pointer(void); if (_cmpxchg_bugcheck_count-- <= 0) { \ void *ip; \ extern int printk(const char *fmt, ...); \ - asm ("mov %0=ip" : "=r"(ip)); \ + ip = ia64_getreg(_IA64_REG_IP); \ printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v)); \ break; \ } \ @@ -181,4 +177,5 @@ extern long __cmpxchg_called_with_bad_pointer(void); # define CMPXCHG_BUGCHECK(v) #endif /* !CONFIG_IA64_DEBUG_CMPXCHG */ +#endif #endif /* _ASM_IA64_INTRINSICS_H */ diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h index 1297c6bba42b..297efb06c347 100644 --- a/include/asm-ia64/io.h +++ b/include/asm-ia64/io.h @@ -52,6 +52,7 @@ extern unsigned int num_io_spaces; # ifdef __KERNEL__ +#include <asm/intrinsics.h> #include <asm/machvec.h> #include <asm/page.h> #include <asm/system.h> @@ -85,7 +86,7 @@ phys_to_virt (unsigned long address) * Memory fence w/accept. This should never be used in code that is * not IA-64 specific. */ -#define __ia64_mf_a() __asm__ __volatile__ ("mf.a" ::: "memory") +#define __ia64_mf_a() ia64_mfa() static inline const unsigned long __ia64_get_io_port_base (void) diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h index a277c8ff9595..471a2c91cd29 100644 --- a/include/asm-ia64/machvec.h +++ b/include/asm-ia64/machvec.h @@ -155,7 +155,7 @@ struct ia64_machine_vector { ia64_mv_readw_t *readw; ia64_mv_readl_t *readl; ia64_mv_readq_t *readq; -}; +} __attribute__((__aligned__(16))); /* align attrib? see above comment */ #define MACHVEC_INIT(name) \ { \ diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h index 95e786212982..0255260f61bc 100644 --- a/include/asm-ia64/mmu_context.h +++ b/include/asm-ia64/mmu_context.h @@ -158,9 +158,7 @@ reload_context (mm_context_t context) ia64_set_rr(0x4000000000000000, rr2); ia64_set_rr(0x6000000000000000, rr3); ia64_set_rr(0x8000000000000000, rr4); - ia64_insn_group_barrier(); ia64_srlz_i(); /* srlz.i implies srlz.d */ - ia64_insn_group_barrier(); } static inline void diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h index 44b3f419c854..56f5c49a4e95 100644 --- a/include/asm-ia64/page.h +++ b/include/asm-ia64/page.h @@ -9,6 +9,7 @@ #include <linux/config.h> +#include <asm/intrinsics.h> #include <asm/types.h> /* @@ -143,7 +144,7 @@ get_order (unsigned long size) double d = size - 1; long order; - __asm__ ("getf.exp %0=%1" : "=r"(order) : "f"(d)); + order = ia64_getf_exp(d); order = order - PAGE_SHIFT - 0xffff + 1; if (order < 0) order = 0; diff --git a/include/asm-ia64/pal.h b/include/asm-ia64/pal.h index 5640226e8a15..e3152bc4fb39 100644 --- a/include/asm-ia64/pal.h +++ b/include/asm-ia64/pal.h @@ -822,10 +822,10 @@ ia64_pal_cache_flush (u64 cache_type, u64 invalidate, u64 *progress, u64 *vector /* Initialize the processor controlled caches */ static inline s64 -ia64_pal_cache_init (u64 level, u64 cache_type, u64 restrict) +ia64_pal_cache_init (u64 level, u64 cache_type, u64 rest) { struct ia64_pal_retval iprv; - PAL_CALL(iprv, PAL_CACHE_INIT, level, cache_type, restrict); + PAL_CALL(iprv, PAL_CACHE_INIT, level, cache_type, rest); return iprv.status; } diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 669e44bf8012..c6b4af2b3643 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h @@ -15,8 +15,9 @@ #include <linux/config.h> -#include <asm/ptrace.h> +#include <asm/intrinsics.h> #include <asm/kregs.h> +#include <asm/ptrace.h> #include <asm/ustack.h> #define IA64_NUM_DBG_REGS 8 @@ -356,38 +357,41 @@ extern unsigned long get_wchan (struct task_struct *p); /* Return stack pointer of blocked task TSK. */ #define KSTK_ESP(tsk) ((tsk)->thread.ksp) -static inline unsigned long -ia64_get_kr (unsigned long regnum) -{ - unsigned long r = 0; - - switch (regnum) { - case 0: asm volatile ("mov %0=ar.k0" : "=r"(r)); break; - case 1: asm volatile ("mov %0=ar.k1" : "=r"(r)); break; - case 2: asm volatile ("mov %0=ar.k2" : "=r"(r)); break; - case 3: asm volatile ("mov %0=ar.k3" : "=r"(r)); break; - case 4: asm volatile ("mov %0=ar.k4" : "=r"(r)); break; - case 5: asm volatile ("mov %0=ar.k5" : "=r"(r)); break; - case 6: asm volatile ("mov %0=ar.k6" : "=r"(r)); break; - case 7: asm volatile ("mov %0=ar.k7" : "=r"(r)); break; - } - return r; -} +extern void ia64_getreg_unknown_kr (void); +extern void ia64_setreg_unknown_kr (void); + +#define ia64_get_kr(regnum) \ +({ \ + unsigned long r = 0; \ + \ + switch (regnum) { \ + case 0: r = ia64_getreg(_IA64_REG_AR_KR0); break; \ + case 1: r = ia64_getreg(_IA64_REG_AR_KR1); break; \ + case 2: r = ia64_getreg(_IA64_REG_AR_KR2); break; \ + case 3: r = ia64_getreg(_IA64_REG_AR_KR3); break; \ + case 4: r = ia64_getreg(_IA64_REG_AR_KR4); break; \ + case 5: r = ia64_getreg(_IA64_REG_AR_KR5); break; \ + case 6: r = ia64_getreg(_IA64_REG_AR_KR6); break; \ + case 7: r = ia64_getreg(_IA64_REG_AR_KR7); break; \ + default: ia64_getreg_unknown_kr(); break; \ + } \ + r; \ +}) -static inline void -ia64_set_kr (unsigned long regnum, unsigned long r) -{ - switch (regnum) { - case 0: asm volatile ("mov ar.k0=%0" :: "r"(r)); break; - case 1: asm volatile ("mov ar.k1=%0" :: "r"(r)); break; - case 2: asm volatile ("mov ar.k2=%0" :: "r"(r)); break; - case 3: asm volatile ("mov ar.k3=%0" :: "r"(r)); break; - case 4: asm volatile ("mov ar.k4=%0" :: "r"(r)); break; - case 5: asm volatile ("mov ar.k5=%0" :: "r"(r)); break; - case 6: asm volatile ("mov ar.k6=%0" :: "r"(r)); break; - case 7: asm volatile ("mov ar.k7=%0" :: "r"(r)); break; - } -} +#define ia64_set_kr(regnum, r) \ +({ \ + switch (regnum) { \ + case 0: ia64_setreg(_IA64_REG_AR_KR0, r); break; \ + case 1: ia64_setreg(_IA64_REG_AR_KR1, r); break; \ + case 2: ia64_setreg(_IA64_REG_AR_KR2, r); break; \ + case 3: ia64_setreg(_IA64_REG_AR_KR3, r); break; \ + case 4: ia64_setreg(_IA64_REG_AR_KR4, r); break; \ + case 5: ia64_setreg(_IA64_REG_AR_KR5, r); break; \ + case 6: ia64_setreg(_IA64_REG_AR_KR6, r); break; \ + case 7: ia64_setreg(_IA64_REG_AR_KR7, r); break; \ + default: ia64_setreg_unknown_kr(); break; \ + } \ +}) /* * The following three macros can't be inline functions because we don't have struct @@ -423,8 +427,8 @@ extern void ia32_save_state (struct task_struct *task); extern void ia32_load_state (struct task_struct *task); #endif -#define ia64_fph_enable() asm volatile (";; rsm psr.dfh;; srlz.d;;" ::: "memory"); -#define ia64_fph_disable() asm volatile (";; ssm psr.dfh;; srlz.d;;" ::: "memory"); +#define ia64_fph_enable() do { ia64_rsm(IA64_PSR_DFH); ia64_srlz_d(); } while (0) +#define ia64_fph_disable() do { ia64_ssm(IA64_PSR_DFH); ia64_srlz_d(); } while (0) /* load fp 0.0 into fph */ static inline void @@ -450,78 +454,14 @@ ia64_load_fpu (struct ia64_fpreg *fph) { ia64_fph_disable(); } -static inline void -ia64_fc (void *addr) -{ - asm volatile ("fc %0" :: "r"(addr) : "memory"); -} - -static inline void -ia64_sync_i (void) -{ - asm volatile (";; sync.i" ::: "memory"); -} - -static inline void -ia64_srlz_i (void) -{ - asm volatile (";; srlz.i ;;" ::: "memory"); -} - -static inline void -ia64_srlz_d (void) -{ - asm volatile (";; srlz.d" ::: "memory"); -} - -static inline __u64 -ia64_get_rr (__u64 reg_bits) -{ - __u64 r; - asm volatile ("mov %0=rr[%1]" : "=r"(r) : "r"(reg_bits) : "memory"); - return r; -} - -static inline void -ia64_set_rr (__u64 reg_bits, __u64 rr_val) -{ - asm volatile ("mov rr[%0]=%1" :: "r"(reg_bits), "r"(rr_val) : "memory"); -} - -static inline __u64 -ia64_get_dcr (void) -{ - __u64 r; - asm volatile ("mov %0=cr.dcr" : "=r"(r)); - return r; -} - -static inline void -ia64_set_dcr (__u64 val) -{ - asm volatile ("mov cr.dcr=%0;;" :: "r"(val) : "memory"); - ia64_srlz_d(); -} - -static inline __u64 -ia64_get_lid (void) -{ - __u64 r; - asm volatile ("mov %0=cr.lid" : "=r"(r)); - return r; -} - -static inline void -ia64_invala (void) -{ - asm volatile ("invala" ::: "memory"); -} - static inline __u64 ia64_clear_ic (void) { __u64 psr; - asm volatile ("mov %0=psr;; rsm psr.i | psr.ic;; srlz.i;;" : "=r"(psr) :: "memory"); + psr = ia64_getreg(_IA64_REG_PSR); + ia64_stop(); + ia64_rsm(IA64_PSR_I | IA64_PSR_IC); + ia64_srlz_i(); return psr; } @@ -531,7 +471,9 @@ ia64_clear_ic (void) static inline void ia64_set_psr (__u64 psr) { - asm volatile (";; mov psr.l=%0;; srlz.d" :: "r" (psr) : "memory"); + ia64_stop(); + ia64_setreg(_IA64_REG_PSR_L, psr); + ia64_srlz_d(); } /* @@ -543,14 +485,13 @@ ia64_itr (__u64 target_mask, __u64 tr_num, __u64 vmaddr, __u64 pte, __u64 log_page_size) { - asm volatile ("mov cr.itir=%0" :: "r"(log_page_size << 2) : "memory"); - asm volatile ("mov cr.ifa=%0;;" :: "r"(vmaddr) : "memory"); + ia64_setreg(_IA64_REG_CR_ITIR, (log_page_size << 2)); + ia64_setreg(_IA64_REG_CR_IFA, vmaddr); + ia64_stop(); if (target_mask & 0x1) - asm volatile ("itr.i itr[%0]=%1" - :: "r"(tr_num), "r"(pte) : "memory"); + ia64_itri(tr_num, pte); if (target_mask & 0x2) - asm volatile (";;itr.d dtr[%0]=%1" - :: "r"(tr_num), "r"(pte) : "memory"); + ia64_itrd(tr_num, pte); } /* @@ -561,13 +502,14 @@ static inline void ia64_itc (__u64 target_mask, __u64 vmaddr, __u64 pte, __u64 log_page_size) { - asm volatile ("mov cr.itir=%0" :: "r"(log_page_size << 2) : "memory"); - asm volatile ("mov cr.ifa=%0;;" :: "r"(vmaddr) : "memory"); + ia64_setreg(_IA64_REG_CR_ITIR, (log_page_size << 2)); + ia64_setreg(_IA64_REG_CR_IFA, vmaddr); + ia64_stop(); /* as per EAS2.6, itc must be the last instruction in an instruction group */ if (target_mask & 0x1) - asm volatile ("itc.i %0;;" :: "r"(pte) : "memory"); + ia64_itci(pte); if (target_mask & 0x2) - asm volatile (";;itc.d %0;;" :: "r"(pte) : "memory"); + ia64_itcd(pte); } /* @@ -578,16 +520,17 @@ static inline void ia64_ptr (__u64 target_mask, __u64 vmaddr, __u64 log_size) { if (target_mask & 0x1) - asm volatile ("ptr.i %0,%1" :: "r"(vmaddr), "r"(log_size << 2)); + ia64_ptri(vmaddr, (log_size << 2)); if (target_mask & 0x2) - asm volatile ("ptr.d %0,%1" :: "r"(vmaddr), "r"(log_size << 2)); + ia64_ptrd(vmaddr, (log_size << 2)); } /* Set the interrupt vector address. The address must be suitably aligned (32KB). */ static inline void ia64_set_iva (void *ivt_addr) { - asm volatile ("mov cr.iva=%0;; srlz.i;;" :: "r"(ivt_addr) : "memory"); + ia64_setreg(_IA64_REG_CR_IVA, (__u64) ivt_addr); + ia64_srlz_i(); } /* Set the page table address and control bits. */ @@ -595,79 +538,33 @@ static inline void ia64_set_pta (__u64 pta) { /* Note: srlz.i implies srlz.d */ - asm volatile ("mov cr.pta=%0;; srlz.i;;" :: "r"(pta) : "memory"); -} - -static inline __u64 -ia64_get_cpuid (__u64 regnum) -{ - __u64 r; - - asm ("mov %0=cpuid[%r1]" : "=r"(r) : "rO"(regnum)); - return r; + ia64_setreg(_IA64_REG_CR_PTA, pta); + ia64_srlz_i(); } static inline void ia64_eoi (void) { - asm ("mov cr.eoi=r0;; srlz.d;;" ::: "memory"); + ia64_setreg(_IA64_REG_CR_EOI, 0); + ia64_srlz_d(); } -static inline void -ia64_set_lrr0 (unsigned long val) -{ - asm volatile ("mov cr.lrr0=%0;; srlz.d" :: "r"(val) : "memory"); -} +#define cpu_relax() ia64_hint(ia64_hint_pause) static inline void -ia64_hint_pause (void) +ia64_set_lrr0 (unsigned long val) { - asm volatile ("hint @pause" ::: "memory"); + ia64_setreg(_IA64_REG_CR_LRR0, val); + ia64_srlz_d(); } -#define cpu_relax() ia64_hint_pause() - static inline void ia64_set_lrr1 (unsigned long val) { - asm volatile ("mov cr.lrr1=%0;; srlz.d" :: "r"(val) : "memory"); -} - -static inline void -ia64_set_pmv (__u64 val) -{ - asm volatile ("mov cr.pmv=%0" :: "r"(val) : "memory"); -} - -static inline __u64 -ia64_get_pmc (__u64 regnum) -{ - __u64 retval; - - asm volatile ("mov %0=pmc[%1]" : "=r"(retval) : "r"(regnum)); - return retval; -} - -static inline void -ia64_set_pmc (__u64 regnum, __u64 value) -{ - asm volatile ("mov pmc[%0]=%1" :: "r"(regnum), "r"(value)); -} - -static inline __u64 -ia64_get_pmd (__u64 regnum) -{ - __u64 retval; - - asm volatile ("mov %0=pmd[%1]" : "=r"(retval) : "r"(regnum)); - return retval; + ia64_setreg(_IA64_REG_CR_LRR1, val); + ia64_srlz_d(); } -static inline void -ia64_set_pmd (__u64 regnum, __u64 value) -{ - asm volatile ("mov pmd[%0]=%1" :: "r"(regnum), "r"(value)); -} /* * Given the address to which a spill occurred, return the unat bit @@ -713,199 +610,58 @@ thread_saved_pc (struct task_struct *t) * Get the current instruction/program counter value. */ #define current_text_addr() \ - ({ void *_pc; asm volatile ("mov %0=ip" : "=r" (_pc)); _pc; }) - -/* - * Set the correctable machine check vector register - */ -static inline void -ia64_set_cmcv (__u64 val) -{ - asm volatile ("mov cr.cmcv=%0" :: "r"(val) : "memory"); -} - -/* - * Read the correctable machine check vector register - */ -static inline __u64 -ia64_get_cmcv (void) -{ - __u64 val; - - asm volatile ("mov %0=cr.cmcv" : "=r"(val) :: "memory"); - return val; -} + ({ void *_pc; _pc = (void *)ia64_getreg(_IA64_REG_IP); _pc; }) static inline __u64 ia64_get_ivr (void) { __u64 r; - asm volatile ("srlz.d;; mov %0=cr.ivr;; srlz.d;;" : "=r"(r)); - return r; -} - -static inline void -ia64_set_tpr (__u64 val) -{ - asm volatile ("mov cr.tpr=%0" :: "r"(val)); -} - -static inline __u64 -ia64_get_tpr (void) -{ - __u64 r; - asm volatile ("mov %0=cr.tpr" : "=r"(r)); - return r; -} - -static inline void -ia64_set_irr0 (__u64 val) -{ - asm volatile("mov cr.irr0=%0;;" :: "r"(val) : "memory"); ia64_srlz_d(); -} - -static inline __u64 -ia64_get_irr0 (void) -{ - __u64 val; - - /* this is volatile because irr may change unbeknownst to gcc... */ - asm volatile("mov %0=cr.irr0" : "=r"(val)); - return val; -} - -static inline void -ia64_set_irr1 (__u64 val) -{ - asm volatile("mov cr.irr1=%0;;" :: "r"(val) : "memory"); + r = ia64_getreg(_IA64_REG_CR_IVR); ia64_srlz_d(); -} - -static inline __u64 -ia64_get_irr1 (void) -{ - __u64 val; - - /* this is volatile because irr may change unbeknownst to gcc... */ - asm volatile("mov %0=cr.irr1" : "=r"(val)); - return val; -} - -static inline void -ia64_set_irr2 (__u64 val) -{ - asm volatile("mov cr.irr2=%0;;" :: "r"(val) : "memory"); - ia64_srlz_d(); -} - -static inline __u64 -ia64_get_irr2 (void) -{ - __u64 val; - - /* this is volatile because irr may change unbeknownst to gcc... */ - asm volatile("mov %0=cr.irr2" : "=r"(val)); - return val; -} - -static inline void -ia64_set_irr3 (__u64 val) -{ - asm volatile("mov cr.irr3=%0;;" :: "r"(val) : "memory"); - ia64_srlz_d(); -} - -static inline __u64 -ia64_get_irr3 (void) -{ - __u64 val; - - /* this is volatile because irr may change unbeknownst to gcc... */ - asm volatile ("mov %0=cr.irr3" : "=r"(val)); - return val; -} - -static inline __u64 -ia64_get_gp(void) -{ - __u64 val; - - asm ("mov %0=gp" : "=r"(val)); - return val; -} - -static inline void -ia64_set_ibr (__u64 regnum, __u64 value) -{ - asm volatile ("mov ibr[%0]=%1" :: "r"(regnum), "r"(value)); + return r; } static inline void ia64_set_dbr (__u64 regnum, __u64 value) { - asm volatile ("mov dbr[%0]=%1" :: "r"(regnum), "r"(value)); + __ia64_set_dbr(regnum, value); #ifdef CONFIG_ITANIUM - asm volatile (";; srlz.d"); + ia64_srlz_d(); #endif } static inline __u64 -ia64_get_ibr (__u64 regnum) -{ - __u64 retval; - - asm volatile ("mov %0=ibr[%1]" : "=r"(retval) : "r"(regnum)); - return retval; -} - -static inline __u64 ia64_get_dbr (__u64 regnum) { __u64 retval; - asm volatile ("mov %0=dbr[%1]" : "=r"(retval) : "r"(regnum)); + retval = __ia64_get_dbr(regnum); #ifdef CONFIG_ITANIUM - asm volatile (";; srlz.d"); + ia64_srlz_d(); #endif return retval; } /* XXX remove the handcoded version once we have a sufficiently clever compiler... */ #ifdef SMART_COMPILER -# define ia64_rotr(w,n) \ - ({ \ - __u64 _w = (w), _n = (n); \ - \ - (_w >> _n) | (_w << (64 - _n)); \ +# define ia64_rotr(w,n) \ + ({ \ + __u64 __ia64_rotr_w = (w), _n = (n); \ + \ + (__ia64_rotr_w >> _n) | (__ia64_rotr_w << (64 - _n)); \ }) #else -# define ia64_rotr(w,n) \ - ({ \ - __u64 result; \ - asm ("shrp %0=%1,%1,%2" : "=r"(result) : "r"(w), "i"(n)); \ - result; \ +# define ia64_rotr(w,n) \ + ({ \ + __u64 __ia64_rotr_w; \ + __ia64_rotr_w = ia64_shrp((w), (w), (n)); \ + __ia64_rotr_w; \ }) #endif #define ia64_rotl(w,n) ia64_rotr((w),(64)-(n)) -static inline __u64 -ia64_thash (__u64 addr) -{ - __u64 result; - asm ("thash %0=%1" : "=r"(result) : "r" (addr)); - return result; -} - -static inline __u64 -ia64_tpa (__u64 addr) -{ - __u64 result; - asm ("tpa %0=%1" : "=r"(result) : "r"(addr)); - return result; -} - /* * Take a mapped kernel address and return the equivalent address * in the region 7 identity mapped virtual area. @@ -914,7 +670,7 @@ static inline void * ia64_imva (void *addr) { void *result; - asm ("tpa %0=%1" : "=r"(result) : "r"(addr)); + result = (void *) ia64_tpa(addr); return __va(result); } @@ -926,13 +682,13 @@ ia64_imva (void *addr) static inline void prefetch (const void *x) { - __asm__ __volatile__ ("lfetch [%0]" : : "r"(x)); + ia64_lfetch(ia64_lfhint_none, x); } static inline void prefetchw (const void *x) { - __asm__ __volatile__ ("lfetch.excl [%0]" : : "r"(x)); + ia64_lfetch_excl(ia64_lfhint_none, x); } #define spin_lock_prefetch(x) prefetchw(x) diff --git a/include/asm-ia64/rwsem.h b/include/asm-ia64/rwsem.h index b0427fa5bccf..6ece5061dc19 100644 --- a/include/asm-ia64/rwsem.h +++ b/include/asm-ia64/rwsem.h @@ -23,6 +23,8 @@ #include <linux/list.h> #include <linux/spinlock.h> +#include <asm/intrinsics.h> + /* * the semaphore definition */ @@ -81,9 +83,8 @@ init_rwsem (struct rw_semaphore *sem) static inline void __down_read (struct rw_semaphore *sem) { - int result; - __asm__ __volatile__ ("fetchadd4.acq %0=[%1],1" : - "=r"(result) : "r"(&sem->count) : "memory"); + int result = ia64_fetchadd4_acq((unsigned int *)&sem->count, 1); + if (result < 0) rwsem_down_read_failed(sem); } @@ -111,9 +112,8 @@ __down_write (struct rw_semaphore *sem) static inline void __up_read (struct rw_semaphore *sem) { - int result; - __asm__ __volatile__ ("fetchadd4.rel %0=[%1],-1" : - "=r"(result) : "r"(&sem->count) : "memory"); + int result = ia64_fetchadd4_rel((unsigned int *)&sem->count, -1); + if (result < 0 && (--result & RWSEM_ACTIVE_MASK) == 0) rwsem_wake(sem); } diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h index a2c7f1c09050..855c24712736 100644 --- a/include/asm-ia64/sal.h +++ b/include/asm-ia64/sal.h @@ -804,6 +804,10 @@ ia64_sal_update_pal (u64 param_buf, u64 scratch_buf, u64 scratch_buf_size, extern unsigned long sal_platform_features; +struct sal_ret_values { + long r8; long r9; long r10; long r11; +}; + #endif /* __ASSEMBLY__ */ #endif /* _ASM_IA64_PAL_H */ diff --git a/include/asm-ia64/siginfo.h b/include/asm-ia64/siginfo.h index 16de6f10c1e1..eca7d714a8fb 100644 --- a/include/asm-ia64/siginfo.h +++ b/include/asm-ia64/siginfo.h @@ -79,7 +79,6 @@ typedef struct siginfo { * si_code is non-zero and __ISR_VALID is set in si_flags. */ #define si_isr _sifields._sigfault._isr -#define si_pfm_ovfl _sifields._sigprof._pfm_ovfl_counters /* * Flag values for si_flags: diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h index 0f114d98c2ee..adb4716f352c 100644 --- a/include/asm-ia64/smp.h +++ b/include/asm-ia64/smp.h @@ -106,7 +106,7 @@ hard_smp_processor_id (void) unsigned long bits; } lid; - lid.bits = ia64_get_lid(); + lid.bits = ia64_getreg(_IA64_REG_CR_LID); return lid.f.id << 8 | lid.f.eid; } diff --git a/include/asm-ia64/sn/sn2/io.h b/include/asm-ia64/sn/sn2/io.h index fc30f1f4c5c8..3a3b1e214164 100644 --- a/include/asm-ia64/sn/sn2/io.h +++ b/include/asm-ia64/sn/sn2/io.h @@ -11,11 +11,23 @@ extern void * sn_io_addr(unsigned long port); /* Forward definition */ extern void sn_mmiob(void); /* Forward definition */ +#include <asm/intrinsics.h> -#define __sn_mf_a() __asm__ __volatile__ ("mf.a" ::: "memory") +#define __sn_mf_a() ia64_mfa() extern void sn_dma_flush(unsigned long); +#define __sn_inb ___sn_inb +#define __sn_inw ___sn_inw +#define __sn_inl ___sn_inl +#define __sn_outb ___sn_outb +#define __sn_outw ___sn_outw +#define __sn_outl ___sn_outl +#define __sn_readb ___sn_readb +#define __sn_readw ___sn_readw +#define __sn_readl ___sn_readl +#define __sn_readq ___sn_readq + /* * The following routines are SN Platform specific, called when * a reference is made to inX/outX set macros. SN Platform @@ -26,7 +38,7 @@ extern void sn_dma_flush(unsigned long); */ static inline unsigned int -__sn_inb (unsigned long port) +___sn_inb (unsigned long port) { volatile unsigned char *addr; unsigned char ret = -1; @@ -40,7 +52,7 @@ __sn_inb (unsigned long port) } static inline unsigned int -__sn_inw (unsigned long port) +___sn_inw (unsigned long port) { volatile unsigned short *addr; unsigned short ret = -1; @@ -54,7 +66,7 @@ __sn_inw (unsigned long port) } static inline unsigned int -__sn_inl (unsigned long port) +___sn_inl (unsigned long port) { volatile unsigned int *addr; unsigned int ret = -1; @@ -68,7 +80,7 @@ __sn_inl (unsigned long port) } static inline void -__sn_outb (unsigned char val, unsigned long port) +___sn_outb (unsigned char val, unsigned long port) { volatile unsigned char *addr; @@ -79,7 +91,7 @@ __sn_outb (unsigned char val, unsigned long port) } static inline void -__sn_outw (unsigned short val, unsigned long port) +___sn_outw (unsigned short val, unsigned long port) { volatile unsigned short *addr; @@ -90,7 +102,7 @@ __sn_outw (unsigned short val, unsigned long port) } static inline void -__sn_outl (unsigned int val, unsigned long port) +___sn_outl (unsigned int val, unsigned long port) { volatile unsigned int *addr; @@ -110,7 +122,7 @@ __sn_outl (unsigned int val, unsigned long port) */ static inline unsigned char -__sn_readb (void *addr) +___sn_readb (void *addr) { unsigned char val; @@ -121,7 +133,7 @@ __sn_readb (void *addr) } static inline unsigned short -__sn_readw (void *addr) +___sn_readw (void *addr) { unsigned short val; @@ -132,7 +144,7 @@ __sn_readw (void *addr) } static inline unsigned int -__sn_readl (void *addr) +___sn_readl (void *addr) { unsigned int val; @@ -143,7 +155,7 @@ __sn_readl (void *addr) } static inline unsigned long -__sn_readq (void *addr) +___sn_readq (void *addr) { unsigned long val; diff --git a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h index 74dd5a6d2460..a2831ceb16a8 100644 --- a/include/asm-ia64/sn/sn_cpuid.h +++ b/include/asm-ia64/sn/sn_cpuid.h @@ -89,7 +89,7 @@ #ifndef CONFIG_SMP #define cpu_logical_id(cpu) 0 -#define cpu_physical_id(cpuid) ((ia64_get_lid() >> 16) & 0xffff) +#define cpu_physical_id(cpuid) ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff) #endif /* @@ -98,8 +98,8 @@ */ #define cpu_physical_id_to_nasid(cpi) ((cpi) &0xfff) #define cpu_physical_id_to_slice(cpi) ((cpi>>12) & 3) -#define get_nasid() ((ia64_get_lid() >> 16) & 0xfff) -#define get_slice() ((ia64_get_lid() >> 28) & 0xf) +#define get_nasid() ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xfff) +#define get_slice() ((ia64_getreg(_IA64_REG_CR_LID) >> 28) & 0xf) #define get_node_number(addr) (((unsigned long)(addr)>>38) & 0x7ff) /* diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h index 3c0d89837b02..3a5f08f4c6f2 100644 --- a/include/asm-ia64/spinlock.h +++ b/include/asm-ia64/spinlock.h @@ -9,11 +9,13 @@ * This file is used for SMP configurations only. */ +#include <linux/compiler.h> #include <linux/kernel.h> -#include <asm/system.h> -#include <asm/bitops.h> #include <asm/atomic.h> +#include <asm/bitops.h> +#include <asm/intrinsics.h> +#include <asm/system.h> typedef struct { volatile unsigned int lock; @@ -102,8 +104,8 @@ typedef struct { do { \ rwlock_t *__read_lock_ptr = (rw); \ \ - while (unlikely(ia64_fetchadd(1, (int *) __read_lock_ptr, "acq") < 0)) { \ - ia64_fetchadd(-1, (int *) __read_lock_ptr, "rel"); \ + while (unlikely(ia64_fetchadd(1, (int *) __read_lock_ptr, acq) < 0)) { \ + ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \ while (*(volatile int *)__read_lock_ptr < 0) \ cpu_relax(); \ } \ @@ -112,7 +114,7 @@ do { \ #define _raw_read_unlock(rw) \ do { \ rwlock_t *__read_lock_ptr = (rw); \ - ia64_fetchadd(-1, (int *) __read_lock_ptr, "rel"); \ + ia64_fetchadd(-1, (int *) __read_lock_ptr, rel); \ } while (0) #define _raw_write_lock(rw) \ diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h index f4951838e69d..c0a638402858 100644 --- a/include/asm-ia64/system.h +++ b/include/asm-ia64/system.h @@ -55,12 +55,6 @@ extern struct ia64_boot_param { __u64 initrd_size; } *ia64_boot_param; -static inline void -ia64_insn_group_barrier (void) -{ - __asm__ __volatile__ (";;" ::: "memory"); -} - /* * Macros to force memory ordering. In these descriptions, "previous" * and "subsequent" refer to program order; "visible" means that all @@ -83,7 +77,7 @@ ia64_insn_group_barrier (void) * it's (presumably) much slower than mf and (b) mf.a is supported for * sequential memory pages only. */ -#define mb() __asm__ __volatile__ ("mf" ::: "memory") +#define mb() ia64_mf() #define rmb() mb() #define wmb() mb() #define read_barrier_depends() do { } while(0) @@ -119,22 +113,26 @@ ia64_insn_group_barrier (void) /* clearing psr.i is implicitly serialized (visible by next insn) */ /* setting psr.i requires data serialization */ -#define __local_irq_save(x) __asm__ __volatile__ ("mov %0=psr;;" \ - "rsm psr.i;;" \ - : "=r" (x) :: "memory") -#define __local_irq_disable() __asm__ __volatile__ (";; rsm psr.i;;" ::: "memory") -#define __local_irq_restore(x) __asm__ __volatile__ ("cmp.ne p6,p7=%0,r0;;" \ - "(p6) ssm psr.i;" \ - "(p7) rsm psr.i;;" \ - "(p6) srlz.d" \ - :: "r" ((x) & IA64_PSR_I) \ - : "p6", "p7", "memory") +#define __local_irq_save(x) \ +do { \ + (x) = ia64_getreg(_IA64_REG_PSR); \ + ia64_stop(); \ + ia64_rsm(IA64_PSR_I); \ +} while (0) + +#define __local_irq_disable() \ +do { \ + ia64_stop(); \ + ia64_rsm(IA64_PSR_I); \ +} while (0) + +#define __local_irq_restore(x) ia64_intrin_local_irq_restore((x) & IA64_PSR_I) #ifdef CONFIG_IA64_DEBUG_IRQ extern unsigned long last_cli_ip; -# define __save_ip() __asm__ ("mov %0=ip" : "=r" (last_cli_ip)) +# define __save_ip() last_cli_ip = ia64_getreg(_IA64_REG_IP) # define local_irq_save(x) \ do { \ @@ -164,14 +162,14 @@ do { \ # define local_irq_restore(x) __local_irq_restore(x) #endif /* !CONFIG_IA64_DEBUG_IRQ */ -#define local_irq_enable() __asm__ __volatile__ (";; ssm psr.i;; srlz.d" ::: "memory") -#define local_save_flags(flags) __asm__ __volatile__ ("mov %0=psr" : "=r" (flags) :: "memory") +#define local_irq_enable() ({ ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) +#define local_save_flags(flags) ((flags) = ia64_getreg(_IA64_REG_PSR)) #define irqs_disabled() \ ({ \ - unsigned long flags; \ - local_save_flags(flags); \ - (flags & IA64_PSR_I) == 0; \ + unsigned long __ia64_id_flags; \ + local_save_flags(__ia64_id_flags); \ + (__ia64_id_flags & IA64_PSR_I) == 0; \ }) #ifdef __KERNEL__ diff --git a/include/asm-ia64/timex.h b/include/asm-ia64/timex.h index 5bf5bd8f148e..414aae060440 100644 --- a/include/asm-ia64/timex.h +++ b/include/asm-ia64/timex.h @@ -10,6 +10,7 @@ * Also removed cacheflush_time as it's entirely unused. */ +#include <asm/intrinsics.h> #include <asm/processor.h> typedef unsigned long cycles_t; @@ -32,7 +33,7 @@ get_cycles (void) { cycles_t ret; - __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(ret)); + ret = ia64_getreg(_IA64_REG_AR_ITC); return ret; } diff --git a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h index dd49222e8f08..049c69845b23 100644 --- a/include/asm-ia64/tlbflush.h +++ b/include/asm-ia64/tlbflush.h @@ -10,6 +10,7 @@ #include <linux/mm.h> +#include <asm/intrinsics.h> #include <asm/mmu_context.h> #include <asm/page.h> @@ -77,7 +78,7 @@ flush_tlb_page (struct vm_area_struct *vma, unsigned long addr) flush_tlb_range(vma, (addr & PAGE_MASK), (addr & PAGE_MASK) + PAGE_SIZE); #else if (vma->vm_mm == current->active_mm) - asm volatile ("ptc.l %0,%1" :: "r"(addr), "r"(PAGE_SHIFT << 2) : "memory"); + ia64_ptcl(addr, (PAGE_SHIFT << 2)); else vma->vm_mm->context = 0; #endif diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h index 09325eb6503d..f65623c70fb1 100644 --- a/include/asm-ia64/unistd.h +++ b/include/asm-ia64/unistd.h @@ -334,73 +334,20 @@ waitpid (int pid, int * wait_stat, int flags) } -static inline int -execve (const char *filename, char *const av[], char *const ep[]) -{ - register long r8 asm("r8"); - register long r10 asm("r10"); - register long r15 asm("r15") = __NR_execve; - register long out0 asm("out0") = (long)filename; - register long out1 asm("out1") = (long)av; - register long out2 asm("out2") = (long)ep; - - asm volatile ("break " __stringify(__BREAK_SYSCALL) ";;\n\t" - : "=r" (r8), "=r" (r10), "=r" (r15), "=r" (out0), "=r" (out1), "=r" (out2) - : "2" (r15), "3" (out0), "4" (out1), "5" (out2) - : "memory", "out3", "out4", "out5", "out6", "out7", - /* Non-stacked integer registers, minus r8, r10, r15, r13 */ - "r2", "r3", "r9", "r11", "r12", "r14", "r16", "r17", "r18", - "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", - "r28", "r29", "r30", "r31", - /* Predicate registers. */ - "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", - /* Non-rotating fp registers. */ - "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - /* Branch registers. */ - "b6", "b7" ); - return r8; -} - -static inline pid_t -clone (unsigned long flags, void *sp) -{ - register long r8 asm("r8"); - register long r10 asm("r10"); - register long r15 asm("r15") = __NR_clone; - register long out0 asm("out0") = (long)flags; - register long out1 asm("out1") = (long)sp; - long retval; - - /* clone clobbers current, hence the "r13" in the clobbers list */ - asm volatile ( "break " __stringify(__BREAK_SYSCALL) ";;\n\t" - : "=r" (r8), "=r" (r10), "=r" (r15), "=r" (out0), "=r" (out1) - : "2" (r15), "3" (out0), "4" (out1) - : "memory", "out2", "out3", "out4", "out5", "out6", "out7", "r13", - /* Non-stacked integer registers, minus r8, r10, r15, r13 */ - "r2", "r3", "r9", "r11", "r12", "r14", "r16", "r17", "r18", - "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", - "r28", "r29", "r30", "r31", - /* Predicate registers. */ - "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", - /* Non-rotating fp registers. */ - "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - /* Branch registers. */ - "b6", "b7" ); - retval = r8; - return retval;; - -} +extern int execve (const char *filename, char *const av[], char *const ep[]); +extern pid_t clone (unsigned long flags, void *sp); #endif /* __KERNEL_SYSCALLS__ */ /* * "Conditional" syscalls * - * What we want is __attribute__((weak,alias("sys_ni_syscall"))), but it doesn't work on - * all toolchains, so we just do it by hand. Note, this macro can only be used in the - * file which defines sys_ni_syscall, i.e., in kernel/sys.c. + * Note, this macro can only be used in the file which defines sys_ni_syscall, i.e., in + * kernel/sys.c. This version causes warnings because the declaration isn't a + * proper prototype, but we can't use __typeof__ either, because not all cond_syscall() + * declarations have prototypes at the moment. */ -#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); +#define cond_syscall(x) asmlinkage long x() __attribute__((weak,alias("sys_ni_syscall"))); #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ |
