diff options
Diffstat (limited to 'arch')
732 files changed, 6563 insertions, 34949 deletions
diff --git a/arch/alpha/include/asm/extable.h b/arch/alpha/include/asm/extable.h new file mode 100644 index 000000000000..048e209e524c --- /dev/null +++ b/arch/alpha/include/asm/extable.h @@ -0,0 +1,55 @@ +#ifndef _ASM_EXTABLE_H +#define _ASM_EXTABLE_H + +/* + * About the exception table: + * + * - insn is a 32-bit pc-relative offset from the faulting insn. + * - nextinsn is a 16-bit offset off of the faulting instruction + * (not off of the *next* instruction as branches are). + * - errreg is the register in which to place -EFAULT. + * - valreg is the final target register for the load sequence + * and will be zeroed. + * + * Either errreg or valreg may be $31, in which case nothing happens. + * + * The exception fixup information "just so happens" to be arranged + * as in a MEM format instruction. This lets us emit our three + * values like so: + * + * lda valreg, nextinsn(errreg) + * + */ + +struct exception_table_entry +{ + signed int insn; + union exception_fixup { + unsigned unit; + struct { + signed int nextinsn : 16; + unsigned int errreg : 5; + unsigned int valreg : 5; + } bits; + } fixup; +}; + +/* Returns the new pc */ +#define fixup_exception(map_reg, _fixup, pc) \ +({ \ + if ((_fixup)->fixup.bits.valreg != 31) \ + map_reg((_fixup)->fixup.bits.valreg) = 0; \ + if ((_fixup)->fixup.bits.errreg != 31) \ + map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \ + (pc) + (_fixup)->fixup.bits.nextinsn; \ +}) + +#define ARCH_HAS_RELATIVE_EXTABLE + +#define swap_ex_entry_fixup(a, b, tmp, delta) \ + do { \ + (a)->fixup.unit = (b)->fixup.unit; \ + (b)->fixup.unit = (tmp).fixup.unit; \ + } while (0) + +#endif diff --git a/arch/alpha/include/asm/futex.h b/arch/alpha/include/asm/futex.h index f939794363ac..fb01dfb760c2 100644 --- a/arch/alpha/include/asm/futex.h +++ b/arch/alpha/include/asm/futex.h @@ -19,12 +19,8 @@ "3: .subsection 2\n" \ "4: br 1b\n" \ " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .long 1b-.\n" \ - " lda $31,3b-1b(%1)\n" \ - " .long 2b-.\n" \ - " lda $31,3b-2b(%1)\n" \ - " .previous\n" \ + EXC(1b,3b,%1,$31) \ + EXC(2b,3b,%1,$31) \ : "=&r" (oldval), "=&r"(ret) \ : "r" (uaddr), "r"(oparg) \ : "memory") @@ -101,12 +97,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, "3: .subsection 2\n" "4: br 1b\n" " .previous\n" - " .section __ex_table,\"a\"\n" - " .long 1b-.\n" - " lda $31,3b-1b(%0)\n" - " .long 2b-.\n" - " lda $31,3b-2b(%0)\n" - " .previous\n" + EXC(1b,3b,%0,$31) + EXC(2b,3b,%0,$31) : "+r"(ret), "=&r"(prev), "=&r"(cmp) : "r"(uaddr), "r"((long)(int)oldval), "r"(newval) : "memory"); diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h index 94f587535dee..7b82dc9a8556 100644 --- a/arch/alpha/include/asm/uaccess.h +++ b/arch/alpha/include/asm/uaccess.h @@ -1,10 +1,6 @@ #ifndef __ALPHA_UACCESS_H #define __ALPHA_UACCESS_H -#include <linux/errno.h> -#include <linux/sched.h> - - /* * The fs value determines whether argument validity checking should be * performed or not. If get_fs() == USER_DS, checking is performed, with @@ -20,9 +16,6 @@ #define KERNEL_DS ((mm_segment_t) { 0UL }) #define USER_DS ((mm_segment_t) { -0x40000000000UL }) -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - #define get_fs() (current_thread_info()->addr_limit) #define get_ds() (KERNEL_DS) #define set_fs(x) (current_thread_info()->addr_limit = (x)) @@ -39,13 +32,13 @@ * - AND "addr+size" doesn't have any high-bits set * - OR we are in kernel mode. */ -#define __access_ok(addr, size, segment) \ - (((segment).seg & (addr | size | (addr+size))) == 0) +#define __access_ok(addr, size) \ + ((get_fs().seg & (addr | size | (addr+size))) == 0) -#define access_ok(type, addr, size) \ -({ \ - __chk_user_ptr(addr); \ - __access_ok(((unsigned long)(addr)), (size), get_fs()); \ +#define access_ok(type, addr, size) \ +({ \ + __chk_user_ptr(addr); \ + __access_ok(((unsigned long)(addr)), (size)); \ }) /* @@ -61,9 +54,9 @@ * (b) require any knowledge of processes at this stage */ #define put_user(x, ptr) \ - __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), get_fs()) + __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) #define get_user(x, ptr) \ - __get_user_check((x), (ptr), sizeof(*(ptr)), get_fs()) + __get_user_check((x), (ptr), sizeof(*(ptr))) /* * The "__xxx" versions do not do address space checking, useful when @@ -81,6 +74,11 @@ * more extensive comments with fixup_inline_exception below for * more information. */ +#define EXC(label,cont,res,err) \ + ".section __ex_table,\"a\"\n" \ + " .long "#label"-.\n" \ + " lda "#res","#cont"-"#label"("#err")\n" \ + ".previous\n" extern void __get_user_unknown(void); @@ -100,23 +98,23 @@ extern void __get_user_unknown(void); __gu_err; \ }) -#define __get_user_check(x, ptr, size, segment) \ -({ \ - long __gu_err = -EFAULT; \ - unsigned long __gu_val = 0; \ - const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ - if (__access_ok((unsigned long)__gu_addr, size, segment)) { \ - __gu_err = 0; \ - switch (size) { \ - case 1: __get_user_8(__gu_addr); break; \ - case 2: __get_user_16(__gu_addr); break; \ - case 4: __get_user_32(__gu_addr); break; \ - case 8: __get_user_64(__gu_addr); break; \ - default: __get_user_unknown(); break; \ - } \ - } \ - (x) = (__force __typeof__(*(ptr))) __gu_val; \ - __gu_err; \ +#define __get_user_check(x, ptr, size) \ +({ \ + long __gu_err = -EFAULT; \ + unsigned long __gu_val = 0; \ + const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ + if (__access_ok((unsigned long)__gu_addr, size)) { \ + __gu_err = 0; \ + switch (size) { \ + case 1: __get_user_8(__gu_addr); break; \ + case 2: __get_user_16(__gu_addr); break; \ + case 4: __get_user_32(__gu_addr); break; \ + case 8: __get_user_64(__gu_addr); break; \ + default: __get_user_unknown(); break; \ + } \ + } \ + (x) = (__force __typeof__(*(ptr))) __gu_val; \ + __gu_err; \ }) struct __large_struct { unsigned long buf[100]; }; @@ -125,20 +123,14 @@ struct __large_struct { unsigned long buf[100]; }; #define __get_user_64(addr) \ __asm__("1: ldq %0,%2\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda %0, 2b-1b(%1)\n" \ - ".previous" \ + EXC(1b,2b,%0,%1) \ : "=r"(__gu_val), "=r"(__gu_err) \ : "m"(__m(addr)), "1"(__gu_err)) #define __get_user_32(addr) \ __asm__("1: ldl %0,%2\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda %0, 2b-1b(%1)\n" \ - ".previous" \ + EXC(1b,2b,%0,%1) \ : "=r"(__gu_val), "=r"(__gu_err) \ : "m"(__m(addr)), "1"(__gu_err)) @@ -148,20 +140,14 @@ struct __large_struct { unsigned long buf[100]; }; #define __get_user_16(addr) \ __asm__("1: ldwu %0,%2\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda %0, 2b-1b(%1)\n" \ - ".previous" \ + EXC(1b,2b,%0,%1) \ : "=r"(__gu_val), "=r"(__gu_err) \ : "m"(__m(addr)), "1"(__gu_err)) #define __get_user_8(addr) \ __asm__("1: ldbu %0,%2\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda %0, 2b-1b(%1)\n" \ - ".previous" \ + EXC(1b,2b,%0,%1) \ : "=r"(__gu_val), "=r"(__gu_err) \ : "m"(__m(addr)), "1"(__gu_err)) #else @@ -177,12 +163,8 @@ struct __large_struct { unsigned long buf[100]; }; " extwh %1,%3,%1\n" \ " or %0,%1,%0\n" \ "3:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda %0, 3b-1b(%2)\n" \ - " .long 2b - .\n" \ - " lda %0, 3b-2b(%2)\n" \ - ".previous" \ + EXC(1b,3b,%0,%2) \ + EXC(2b,3b,%0,%2) \ : "=&r"(__gu_val), "=&r"(__gu_tmp), "=r"(__gu_err) \ : "r"(addr), "2"(__gu_err)); \ } @@ -191,10 +173,7 @@ struct __large_struct { unsigned long buf[100]; }; __asm__("1: ldq_u %0,0(%2)\n" \ " extbl %0,%2,%0\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda %0, 2b-1b(%1)\n" \ - ".previous" \ + EXC(1b,2b,%0,%1) \ : "=&r"(__gu_val), "=r"(__gu_err) \ : "r"(addr), "1"(__gu_err)) #endif @@ -215,21 +194,21 @@ extern void __put_user_unknown(void); __pu_err; \ }) -#define __put_user_check(x, ptr, size, segment) \ -({ \ - long __pu_err = -EFAULT; \ - __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ - if (__access_ok((unsigned long)__pu_addr, size, segment)) { \ - __pu_err = 0; \ - switch (size) { \ - case 1: __put_user_8(x, __pu_addr); break; \ - case 2: __put_user_16(x, __pu_addr); break; \ - case 4: __put_user_32(x, __pu_addr); break; \ - case 8: __put_user_64(x, __pu_addr); break; \ - default: __put_user_unknown(); break; \ - } \ - } \ - __pu_err; \ +#define __put_user_check(x, ptr, size) \ +({ \ + long __pu_err = -EFAULT; \ + __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ + if (__access_ok((unsigned long)__pu_addr, size)) { \ + __pu_err = 0; \ + switch (size) { \ + case 1: __put_user_8(x, __pu_addr); break; \ + case 2: __put_user_16(x, __pu_addr); break; \ + case 4: __put_user_32(x, __pu_addr); break; \ + case 8: __put_user_64(x, __pu_addr); break; \ + default: __put_user_unknown(); break; \ + } \ + } \ + __pu_err; \ }) /* @@ -240,20 +219,14 @@ extern void __put_user_unknown(void); #define __put_user_64(x, addr) \ __asm__ __volatile__("1: stq %r2,%1\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda $31,2b-1b(%0)\n" \ - ".previous" \ + EXC(1b,2b,$31,%0) \ : "=r"(__pu_err) \ : "m" (__m(addr)), "rJ" (x), "0"(__pu_err)) #define __put_user_32(x, addr) \ __asm__ __volatile__("1: stl %r2,%1\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda $31,2b-1b(%0)\n" \ - ".previous" \ + EXC(1b,2b,$31,%0) \ : "=r"(__pu_err) \ : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) @@ -263,20 +236,14 @@ __asm__ __volatile__("1: stl %r2,%1\n" \ #define __put_user_16(x, addr) \ __asm__ __volatile__("1: stw %r2,%1\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda $31,2b-1b(%0)\n" \ - ".previous" \ + EXC(1b,2b,$31,%0) \ : "=r"(__pu_err) \ : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) #define __put_user_8(x, addr) \ __asm__ __volatile__("1: stb %r2,%1\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda $31,2b-1b(%0)\n" \ - ".previous" \ + EXC(1b,2b,$31,%0) \ : "=r"(__pu_err) \ : "m"(__m(addr)), "rJ"(x), "0"(__pu_err)) #else @@ -298,16 +265,10 @@ __asm__ __volatile__("1: stb %r2,%1\n" \ "3: stq_u %2,1(%5)\n" \ "4: stq_u %1,0(%5)\n" \ "5:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda $31, 5b-1b(%0)\n" \ - " .long 2b - .\n" \ - " lda $31, 5b-2b(%0)\n" \ - " .long 3b - .\n" \ - " lda $31, 5b-3b(%0)\n" \ - " .long 4b - .\n" \ - " lda $31, 5b-4b(%0)\n" \ - ".previous" \ + EXC(1b,5b,$31,%0) \ + EXC(2b,5b,$31,%0) \ + EXC(3b,5b,$31,%0) \ + EXC(4b,5b,$31,%0) \ : "=r"(__pu_err), "=&r"(__pu_tmp1), \ "=&r"(__pu_tmp2), "=&r"(__pu_tmp3), \ "=&r"(__pu_tmp4) \ @@ -324,12 +285,8 @@ __asm__ __volatile__("1: stb %r2,%1\n" \ " or %1,%2,%1\n" \ "2: stq_u %1,0(%4)\n" \ "3:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda $31, 3b-1b(%0)\n" \ - " .long 2b - .\n" \ - " lda $31, 3b-2b(%0)\n" \ - ".previous" \ + EXC(1b,3b,$31,%0) \ + EXC(2b,3b,$31,%0) \ : "=r"(__pu_err), \ "=&r"(__pu_tmp1), "=&r"(__pu_tmp2) \ : "r"((unsigned long)(x)), "r"(addr), "0"(__pu_err)); \ @@ -341,153 +298,37 @@ __asm__ __volatile__("1: stb %r2,%1\n" \ * Complex access routines */ -/* This little bit of silliness is to get the GP loaded for a function - that ordinarily wouldn't. Otherwise we could have it done by the macro - directly, which can be optimized the linker. */ -#ifdef MODULE -#define __module_address(sym) "r"(sym), -#define __module_call(ra, arg, sym) "jsr $" #ra ",(%" #arg ")," #sym -#else -#define __module_address(sym) -#define __module_call(ra, arg, sym) "bsr $" #ra "," #sym " !samegp" -#endif - -extern void __copy_user(void); - -extern inline long -__copy_tofrom_user_nocheck(void *to, const void *from, long len) -{ - register void * __cu_to __asm__("$6") = to; - register const void * __cu_from __asm__("$7") = from; - register long __cu_len __asm__("$0") = len; - - __asm__ __volatile__( - __module_call(28, 3, __copy_user) - : "=r" (__cu_len), "=r" (__cu_from), "=r" (__cu_to) - : __module_address(__copy_user) - "0" (__cu_len), "1" (__cu_from), "2" (__cu_to) - : "$1", "$2", "$3", "$4", "$5", "$28", "memory"); - - return __cu_len; -} - -#define __copy_to_user(to, from, n) \ -({ \ - __chk_user_ptr(to); \ - __copy_tofrom_user_nocheck((__force void *)(to), (from), (n)); \ -}) -#define __copy_from_user(to, from, n) \ -({ \ - __chk_user_ptr(from); \ - __copy_tofrom_user_nocheck((to), (__force void *)(from), (n)); \ -}) - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user +extern long __copy_user(void *to, const void *from, long len); -extern inline long -copy_to_user(void __user *to, const void *from, long n) +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long len) { - if (likely(__access_ok((unsigned long)to, n, get_fs()))) - n = __copy_tofrom_user_nocheck((__force void *)to, from, n); - return n; + return __copy_user(to, (__force const void *)from, len); } -extern inline long -copy_from_user(void *to, const void __user *from, long n) +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long len) { - long res = n; - if (likely(__access_ok((unsigned long)from, n, get_fs()))) - res = __copy_from_user_inatomic(to, from, n); - if (unlikely(res)) - memset(to + (n - res), 0, res); - return res; + return __copy_user((__force void *)to, from, len); } -extern void __do_clear_user(void); - -extern inline long -__clear_user(void __user *to, long len) -{ - register void __user * __cl_to __asm__("$6") = to; - register long __cl_len __asm__("$0") = len; - __asm__ __volatile__( - __module_call(28, 2, __do_clear_user) - : "=r"(__cl_len), "=r"(__cl_to) - : __module_address(__do_clear_user) - "0"(__cl_len), "1"(__cl_to) - : "$1", "$2", "$3", "$4", "$5", "$28", "memory"); - return __cl_len; -} +extern long __clear_user(void __user *to, long len); extern inline long clear_user(void __user *to, long len) { - if (__access_ok((unsigned long)to, len, get_fs())) + if (__access_ok((unsigned long)to, len)) len = __clear_user(to, len); return len; } -#undef __module_address -#undef __module_call - #define user_addr_max() \ - (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL) + (uaccess_kernel() ? ~0UL : TASK_SIZE) extern long strncpy_from_user(char *dest, const char __user *src, long count); extern __must_check long strlen_user(const char __user *str); extern __must_check long strnlen_user(const char __user *str, long n); -/* - * About the exception table: - * - * - insn is a 32-bit pc-relative offset from the faulting insn. - * - nextinsn is a 16-bit offset off of the faulting instruction - * (not off of the *next* instruction as branches are). - * - errreg is the register in which to place -EFAULT. - * - valreg is the final target register for the load sequence - * and will be zeroed. - * - * Either errreg or valreg may be $31, in which case nothing happens. - * - * The exception fixup information "just so happens" to be arranged - * as in a MEM format instruction. This lets us emit our three - * values like so: - * - * lda valreg, nextinsn(errreg) - * - */ - -struct exception_table_entry -{ - signed int insn; - union exception_fixup { - unsigned unit; - struct { - signed int nextinsn : 16; - unsigned int errreg : 5; - unsigned int valreg : 5; - } bits; - } fixup; -}; - -/* Returns the new pc */ -#define fixup_exception(map_reg, _fixup, pc) \ -({ \ - if ((_fixup)->fixup.bits.valreg != 31) \ - map_reg((_fixup)->fixup.bits.valreg) = 0; \ - if ((_fixup)->fixup.bits.errreg != 31) \ - map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \ - (pc) + (_fixup)->fixup.bits.nextinsn; \ -}) - -#define ARCH_HAS_RELATIVE_EXTABLE - -#define swap_ex_entry_fixup(a, b, tmp, delta) \ - do { \ - (a)->fixup.unit = (b)->fixup.unit; \ - (b)->fixup.unit = (tmp).fixup.unit; \ - } while (0) - +#include <asm/extable.h> #endif /* __ALPHA_UACCESS_H */ diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 0b961093ca5c..9ec56dc97374 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -1016,6 +1016,7 @@ SYSCALL_DEFINE2(osf_gettimeofday, struct timeval32 __user *, tv, SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv, struct timezone __user *, tz) { + struct timespec64 kts64; struct timespec kts; struct timezone ktz; @@ -1023,13 +1024,14 @@ SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv, if (get_tv32((struct timeval *)&kts, tv)) return -EFAULT; kts.tv_nsec *= 1000; + kts64 = timespec_to_timespec64(kts); } if (tz) { if (copy_from_user(&ktz, tz, sizeof(*tz))) return -EFAULT; } - return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); + return do_sys_settimeofday64(tv ? &kts64 : NULL, tz ? &ktz : NULL); } asmlinkage long sys_ni_posix_timers(void); @@ -1290,7 +1292,7 @@ SYSCALL_DEFINE1(old_adjtimex, struct timex32 __user *, txc_p) /* copy relevant bits of struct timex. */ if (copy_from_user(&txc, txc_p, offsetof(struct timex32, time)) || copy_from_user(&txc.tick, &txc_p->tick, sizeof(struct timex32) - - offsetof(struct timex32, time))) + offsetof(struct timex32, tick))) return -EFAULT; ret = do_adjtimex(&txc); diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index b137390e87e7..65bb102d985b 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -482,12 +482,8 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, " extwl %1,%3,%1\n" " extwh %2,%3,%2\n" "3:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %1,3b-1b(%0)\n" - " .long 2b - .\n" - " lda %2,3b-2b(%0)\n" - ".previous" + EXC(1b,3b,%1,%0) + EXC(2b,3b,%2,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -502,12 +498,8 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, " extll %1,%3,%1\n" " extlh %2,%3,%2\n" "3:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %1,3b-1b(%0)\n" - " .long 2b - .\n" - " lda %2,3b-2b(%0)\n" - ".previous" + EXC(1b,3b,%1,%0) + EXC(2b,3b,%2,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -522,12 +514,8 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, " extql %1,%3,%1\n" " extqh %2,%3,%2\n" "3:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %1,3b-1b(%0)\n" - " .long 2b - .\n" - " lda %2,3b-2b(%0)\n" - ".previous" + EXC(1b,3b,%1,%0) + EXC(2b,3b,%2,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -551,16 +539,10 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, "3: stq_u %2,1(%5)\n" "4: stq_u %1,0(%5)\n" "5:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %2,5b-1b(%0)\n" - " .long 2b - .\n" - " lda %1,5b-2b(%0)\n" - " .long 3b - .\n" - " lda $31,5b-3b(%0)\n" - " .long 4b - .\n" - " lda $31,5b-4b(%0)\n" - ".previous" + EXC(1b,5b,%2,%0) + EXC(2b,5b,%1,%0) + EXC(3b,5b,$31,%0) + EXC(4b,5b,$31,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), "=&r"(tmp3), "=&r"(tmp4) : "r"(va), "r"(una_reg(reg)), "0"(0)); @@ -581,16 +563,10 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, "3: stq_u %2,3(%5)\n" "4: stq_u %1,0(%5)\n" "5:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %2,5b-1b(%0)\n" - " .long 2b - .\n" - " lda %1,5b-2b(%0)\n" - " .long 3b - .\n" - " lda $31,5b-3b(%0)\n" - " .long 4b - .\n" - " lda $31,5b-4b(%0)\n" - ".previous" + EXC(1b,5b,%2,%0) + EXC(2b,5b,%1,%0) + EXC(3b,5b,$31,%0) + EXC(4b,5b,$31,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), "=&r"(tmp3), "=&r"(tmp4) : "r"(va), "r"(una_reg(reg)), "0"(0)); @@ -611,16 +587,10 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, "3: stq_u %2,7(%5)\n" "4: stq_u %1,0(%5)\n" "5:\n" - ".section __ex_table,\"a\"\n\t" - " .long 1b - .\n" - " lda %2,5b-1b(%0)\n" - " .long 2b - .\n" - " lda %1,5b-2b(%0)\n" - " .long 3b - .\n" - " lda $31,5b-3b(%0)\n" - " .long 4b - .\n" - " lda $31,5b-4b(%0)\n" - ".previous" + EXC(1b,5b,%2,%0) + EXC(2b,5b,%1,%0) + EXC(3b,5b,$31,%0) + EXC(4b,5b,$31,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), "=&r"(tmp3), "=&r"(tmp4) : "r"(va), "r"(una_reg(reg)), "0"(0)); @@ -802,7 +772,7 @@ do_entUnaUser(void __user * va, unsigned long opcode, /* Don't bother reading ds in the access check since we already know that this came from the user. Also rely on the fact that the page at TASK_SIZE is unmapped and so can't be touched anyway. */ - if (!__access_ok((unsigned long)va, 0, USER_DS)) + if ((unsigned long)va >= TASK_SIZE) goto give_sigsegv; ++unaligned[1].count; @@ -835,12 +805,8 @@ do_entUnaUser(void __user * va, unsigned long opcode, " extwl %1,%3,%1\n" " extwh %2,%3,%2\n" "3:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %1,3b-1b(%0)\n" - " .long 2b - .\n" - " lda %2,3b-2b(%0)\n" - ".previous" + EXC(1b,3b,%1,%0) + EXC(2b,3b,%2,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -855,12 +821,8 @@ do_entUnaUser(void __user * va, unsigned long opcode, " extll %1,%3,%1\n" " extlh %2,%3,%2\n" "3:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %1,3b-1b(%0)\n" - " .long 2b - .\n" - " lda %2,3b-2b(%0)\n" - ".previous" + EXC(1b,3b,%1,%0) + EXC(2b,3b,%2,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -875,12 +837,8 @@ do_entUnaUser(void __user * va, unsigned long opcode, " extql %1,%3,%1\n" " extqh %2,%3,%2\n" "3:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %1,3b-1b(%0)\n" - " .long 2b - .\n" - " lda %2,3b-2b(%0)\n" - ".previous" + EXC(1b,3b,%1,%0) + EXC(2b,3b,%2,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -895,12 +853,8 @@ do_entUnaUser(void __user * va, unsigned long opcode, " extll %1,%3,%1\n" " extlh %2,%3,%2\n" "3:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %1,3b-1b(%0)\n" - " .long 2b - .\n" - " lda %2,3b-2b(%0)\n" - ".previous" + EXC(1b,3b,%1,%0) + EXC(2b,3b,%2,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -915,12 +869,8 @@ do_entUnaUser(void __user * va, unsigned long opcode, " extql %1,%3,%1\n" " extqh %2,%3,%2\n" "3:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %1,3b-1b(%0)\n" - " .long 2b - .\n" - " lda %2,3b-2b(%0)\n" - ".previous" + EXC(1b,3b,%1,%0) + EXC(2b,3b,%2,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2) : "r"(va), "0"(0)); if (error) @@ -944,16 +894,10 @@ do_entUnaUser(void __user * va, unsigned long opcode, "3: stq_u %2,1(%5)\n" "4: stq_u %1,0(%5)\n" "5:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %2,5b-1b(%0)\n" - " .long 2b - .\n" - " lda %1,5b-2b(%0)\n" - " .long 3b - .\n" - " lda $31,5b-3b(%0)\n" - " .long 4b - .\n" - " lda $31,5b-4b(%0)\n" - ".previous" + EXC(1b,5b,%2,%0) + EXC(2b,5b,%1,%0) + EXC(3b,5b,$31,%0) + EXC(4b,5b,$31,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), "=&r"(tmp3), "=&r"(tmp4) : "r"(va), "r"(*reg_addr), "0"(0)); @@ -978,16 +922,10 @@ do_entUnaUser(void __user * va, unsigned long opcode, "3: stq_u %2,3(%5)\n" "4: stq_u %1,0(%5)\n" "5:\n" - ".section __ex_table,\"a\"\n" - " .long 1b - .\n" - " lda %2,5b-1b(%0)\n" - " .long 2b - .\n" - " lda %1,5b-2b(%0)\n" - " .long 3b - .\n" - " lda $31,5b-3b(%0)\n" - " .long 4b - .\n" - " lda $31,5b-4b(%0)\n" - ".previous" + EXC(1b,5b,%2,%0) + EXC(2b,5b,%1,%0) + EXC(3b,5b,$31,%0) + EXC(4b,5b,$31,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), "=&r"(tmp3), "=&r"(tmp4) : "r"(va), "r"(*reg_addr), "0"(0)); @@ -1012,16 +950,10 @@ do_entUnaUser(void __user * va, unsigned long opcode, "3: stq_u %2,7(%5)\n" "4: stq_u %1,0(%5)\n" "5:\n" - ".section __ex_table,\"a\"\n\t" - " .long 1b - .\n" - " lda %2,5b-1b(%0)\n" - " .long 2b - .\n" - " lda %1,5b-2b(%0)\n" - " .long 3b - .\n" - " lda $31,5b-3b(%0)\n" - " .long 4b - .\n" - " lda $31,5b-4b(%0)\n" - ".previous" + EXC(1b,5b,%2,%0) + EXC(2b,5b,%1,%0) + EXC(3b,5b,$31,%0) + EXC(4b,5b,$31,%0) : "=r"(error), "=&r"(tmp1), "=&r"(tmp2), "=&r"(tmp3), "=&r"(tmp4) : "r"(va), "r"(*reg_addr), "0"(0)); @@ -1047,7 +979,7 @@ give_sigsegv: /* We need to replicate some of the logic in mm/fault.c, since we don't have access to the fault code in the exception handling return path. */ - if (!__access_ok((unsigned long)va, 0, USER_DS)) + if ((unsigned long)va >= TASK_SIZE) info.si_code = SEGV_ACCERR; else { struct mm_struct *mm = current->mm; diff --git a/arch/alpha/lib/clear_user.S b/arch/alpha/lib/clear_user.S index bf5b931866ba..006f469fef73 100644 --- a/arch/alpha/lib/clear_user.S +++ b/arch/alpha/lib/clear_user.S @@ -8,21 +8,6 @@ * right "bytes left to zero" value (and that it is updated only _after_ * a successful copy). There is also some rather minor exception setup * stuff. - * - * NOTE! This is not directly C-callable, because the calling semantics - * are different: - * - * Inputs: - * length in $0 - * destination address in $6 - * exception pointer in $7 - * return address in $28 (exceptions expect it there) - * - * Outputs: - * bytes left to copy in $0 - * - * Clobbers: - * $1,$2,$3,$4,$5,$6 */ #include <asm/export.h> @@ -38,62 +23,63 @@ .set noreorder .align 4 - .globl __do_clear_user - .ent __do_clear_user - .frame $30, 0, $28 + .globl __clear_user + .ent __clear_user + .frame $30, 0, $26 .prologue 0 $loop: and $1, 3, $4 # e0 : beq $4, 1f # .. e1 : -0: EX( stq_u $31, 0($6) ) # e0 : zero one word +0: EX( stq_u $31, 0($16) ) # e0 : zero one word subq $0, 8, $0 # .. e1 : subq $4, 1, $4 # e0 : - addq $6, 8, $6 # .. e1 : + addq $16, 8, $16 # .. e1 : bne $4, 0b # e1 : unop # : 1: bic $1, 3, $1 # e0 : beq $1, $tail # .. e1 : -2: EX( stq_u $31, 0($6) ) # e0 : zero four words +2: EX( stq_u $31, 0($16) ) # e0 : zero four words subq $0, 8, $0 # .. e1 : - EX( stq_u $31, 8($6) ) # e0 : + EX( stq_u $31, 8($16) ) # e0 : subq $0, 8, $0 # .. e1 : - EX( stq_u $31, 16($6) ) # e0 : + EX( stq_u $31, 16($16) ) # e0 : subq $0, 8, $0 # .. e1 : - EX( stq_u $31, 24($6) ) # e0 : + EX( stq_u $31, 24($16) ) # e0 : subq $0, 8, $0 # .. e1 : subq $1, 4, $1 # e0 : - addq $6, 32, $6 # .. e1 : + addq $16, 32, $16 # .. e1 : bne $1, 2b # e1 : $tail: bne $2, 1f # e1 : is there a tail to do? - ret $31, ($28), 1 # .. e1 : + ret $31, ($26), 1 # .. e1 : -1: EX( ldq_u $5, 0($6) ) # e0 : +1: EX( ldq_u $5, 0($16) ) # e0 : clr $0 # .. e1 : nop # e1 : mskqh $5, $0, $5 # e0 : - EX( stq_u $5, 0($6) ) # e0 : - ret $31, ($28), 1 # .. e1 : + EX( stq_u $5, 0($16) ) # e0 : + ret $31, ($26), 1 # .. e1 : -__do_clear_user: - and $6, 7, $4 # e0 : find dest misalignment +__clear_user: + and $17, $17, $0 + and $16, 7, $4 # e0 : find dest misalignment beq $0, $zerolength # .. e1 : addq $0, $4, $1 # e0 : bias counter and $1, 7, $2 # e1 : number of bytes in tail srl $1, 3, $1 # e0 : beq $4, $loop # .. e1 : - EX( ldq_u $5, 0($6) ) # e0 : load dst word to mask back in + EX( ldq_u $5, 0($16) ) # e0 : load dst word to mask back in beq $1, $oneword # .. e1 : sub-word store? - mskql $5, $6, $5 # e0 : take care of misaligned head - addq $6, 8, $6 # .. e1 : - EX( stq_u $5, -8($6) ) # e0 : + mskql $5, $16, $5 # e0 : take care of misaligned head + addq $16, 8, $16 # .. e1 : + EX( stq_u $5, -8($16) ) # e0 : addq $0, $4, $0 # .. e1 : bytes left -= 8 - misalignment subq $1, 1, $1 # e0 : subq $0, 8, $0 # .. e1 : @@ -101,15 +87,15 @@ __do_clear_user: unop # : $oneword: - mskql $5, $6, $4 # e0 : + mskql $5, $16, $4 # e0 : mskqh $5, $2, $5 # e0 : or $5, $4, $5 # e1 : - EX( stq_u $5, 0($6) ) # e0 : + EX( stq_u $5, 0($16) ) # e0 : clr $0 # .. e1 : $zerolength: $exception: - ret $31, ($28), 1 # .. e1 : + ret $31, ($26), 1 # .. e1 : - .end __do_clear_user - EXPORT_SYMBOL(__do_clear_user) + .end __clear_user + EXPORT_SYMBOL(__clear_user) diff --git a/arch/alpha/lib/copy_user.S b/arch/alpha/lib/copy_user.S index 509f62b65311..159f1b7e6e49 100644 --- a/arch/alpha/lib/copy_user.S +++ b/arch/alpha/lib/copy_user.S @@ -9,21 +9,6 @@ * contains the right "bytes left to copy" value (and that it is updated * only _after_ a successful copy). There is also some rather minor * exception setup stuff.. - * - * NOTE! This is not directly C-callable, because the calling semantics are - * different: - * - * Inputs: - * length in $0 - * destination address in $6 - * source address in $7 - * return address in $28 - * - * Outputs: - * bytes left to copy in $0 - * - * Clobbers: - * $1,$2,$3,$4,$5,$6,$7 */ #include <asm/export.h> @@ -49,58 +34,59 @@ .ent __copy_user __copy_user: .prologue 0 - and $6,7,$3 + and $18,$18,$0 + and $16,7,$3 beq $0,$35 beq $3,$36 subq $3,8,$3 .align 4 $37: - EXI( ldq_u $1,0($7) ) - EXO( ldq_u $2,0($6) ) - extbl $1,$7,$1 - mskbl $2,$6,$2 - insbl $1,$6,$1 + EXI( ldq_u $1,0($17) ) + EXO( ldq_u $2,0($16) ) + extbl $1,$17,$1 + mskbl $2,$16,$2 + insbl $1,$16,$1 addq $3,1,$3 bis $1,$2,$1 - EXO( stq_u $1,0($6) ) + EXO( stq_u $1,0($16) ) subq $0,1,$0 - addq $6,1,$6 - addq $7,1,$7 + addq $16,1,$16 + addq $17,1,$17 beq $0,$41 bne $3,$37 $36: - and $7,7,$1 + and $17,7,$1 bic $0,7,$4 beq $1,$43 beq $4,$48 - EXI( ldq_u $3,0($7) ) + EXI( ldq_u $3,0($17) ) .align 4 $50: - EXI( ldq_u $2,8($7) ) + EXI( ldq_u $2,8($17) ) subq $4,8,$4 - extql $3,$7,$3 - extqh $2,$7,$1 + extql $3,$17,$3 + extqh $2,$17,$1 bis $3,$1,$1 - EXO( stq $1,0($6) ) - addq $7,8,$7 + EXO( stq $1,0($16) ) + addq $17,8,$17 subq $0,8,$0 - addq $6,8,$6 + addq $16,8,$16 bis $2,$2,$3 bne $4,$50 $48: beq $0,$41 .align 4 $57: - EXI( ldq_u $1,0($7) ) - EXO( ldq_u $2,0($6) ) - extbl $1,$7,$1 - mskbl $2,$6,$2 - insbl $1,$6,$1 + EXI( ldq_u $1,0($17) ) + EXO( ldq_u $2,0($16) ) + extbl $1,$17,$1 + mskbl $2,$16,$2 + insbl $1,$16,$1 bis $1,$2,$1 - EXO( stq_u $1,0($6) ) + EXO( stq_u $1,0($16) ) subq $0,1,$0 - addq $6,1,$6 - addq $7,1,$7 + addq $16,1,$16 + addq $17,1,$17 bne $0,$57 br $31,$41 .align 4 @@ -108,27 +94,27 @@ $43: beq $4,$65 .align 4 $66: - EXI( ldq $1,0($7) ) + EXI( ldq $1,0($17) ) subq $4,8,$4 - EXO( stq $1,0($6) ) - addq $7,8,$7 + EXO( stq $1,0($16) ) + addq $17,8,$17 subq $0,8,$0 - addq $6,8,$6 + addq $16,8,$16 bne $4,$66 $65: beq $0,$41 - EXI( ldq $2,0($7) ) - EXO( ldq $1,0($6) ) + EXI( ldq $2,0($17) ) + EXO( ldq $1,0($16) ) mskql $2,$0,$2 mskqh $1,$0,$1 bis $2,$1,$2 - EXO( stq $2,0($6) ) + EXO( stq $2,0($16) ) bis $31,$31,$0 $41: $35: $exitin: $exitout: - ret $31,($28),1 + ret $31,($26),1 .end __copy_user EXPORT_SYMBOL(__copy_user) diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c index 5dfb7975895f..ab42afba1720 100644 --- a/arch/alpha/lib/csum_partial_copy.c +++ b/arch/alpha/lib/csum_partial_copy.c @@ -45,10 +45,7 @@ __asm__ __volatile__("insqh %1,%2,%0":"=r" (z):"r" (x),"r" (y)) __asm__ __volatile__( \ "1: ldq_u %0,%2\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - .\n" \ - " lda %0,2b-1b(%1)\n" \ - ".previous" \ + EXC(1b,2b,%0,%1) \ : "=r"(x), "=r"(__guu_err) \ : "m"(__m(ptr)), "1"(0)); \ __guu_err; \ @@ -60,10 +57,7 @@ __asm__ __volatile__("insqh %1,%2,%0":"=r" (z):"r" (x),"r" (y)) __asm__ __volatile__( \ "1: stq_u %2,%1\n" \ "2:\n" \ - ".section __ex_table,\"a\"\n" \ - " .long 1b - ." \ - " lda $31,2b-1b(%0)\n" \ - ".previous" \ + EXC(1b,2b,$31,%0) \ : "=r"(__puu_err) \ : "m"(__m(addr)), "rJ"(x), "0"(0)); \ __puu_err; \ diff --git a/arch/alpha/lib/ev6-clear_user.S b/arch/alpha/lib/ev6-clear_user.S index 05bef6b50598..e179e4757ef8 100644 --- a/arch/alpha/lib/ev6-clear_user.S +++ b/arch/alpha/lib/ev6-clear_user.S @@ -9,21 +9,6 @@ * a successful copy). There is also some rather minor exception setup * stuff. * - * NOTE! This is not directly C-callable, because the calling semantics - * are different: - * - * Inputs: - * length in $0 - * destination address in $6 - * exception pointer in $7 - * return address in $28 (exceptions expect it there) - * - * Outputs: - * bytes left to copy in $0 - * - * Clobbers: - * $1,$2,$3,$4,$5,$6 - * * Much of the information about 21264 scheduling/coding comes from: * Compiler Writer's Guide for the Alpha 21264 * abbreviated as 'CWG' in other comments here @@ -56,14 +41,15 @@ .set noreorder .align 4 - .globl __do_clear_user - .ent __do_clear_user - .frame $30, 0, $28 + .globl __clear_user + .ent __clear_user + .frame $30, 0, $26 .prologue 0 # Pipeline info : Slotting & Comments -__do_clear_user: - and $6, 7, $4 # .. E .. .. : find dest head misalignment +__clear_user: + and $17, $17, $0 + and $16, 7, $4 # .. E .. .. : find dest head misalignment beq $0, $zerolength # U .. .. .. : U L U L addq $0, $4, $1 # .. .. .. E : bias counter @@ -75,14 +61,14 @@ __do_clear_user: /* * Head is not aligned. Write (8 - $4) bytes to head of destination - * This means $6 is known to be misaligned + * This means $16 is known to be misaligned */ - EX( ldq_u $5, 0($6) ) # .. .. .. L : load dst word to mask back in + EX( ldq_u $5, 0($16) ) # .. .. .. L : load dst word to mask back in beq $1, $onebyte # .. .. U .. : sub-word store? - mskql $5, $6, $5 # .. U .. .. : take care of misaligned head - addq $6, 8, $6 # E .. .. .. : L U U L + mskql $5, $16, $5 # .. U .. .. : take care of misaligned head + addq $16, 8, $16 # E .. .. .. : L U U L - EX( stq_u $5, -8($6) ) # .. .. .. L : + EX( stq_u $5, -8($16) ) # .. .. .. L : subq $1, 1, $1 # .. .. E .. : addq $0, $4, $0 # .. E .. .. : bytes left -= 8 - misalignment subq $0, 8, $0 # E .. .. .. : U L U L @@ -93,11 +79,11 @@ __do_clear_user: * values upon initial entry to the loop * $1 is number of quadwords to clear (zero is a valid value) * $2 is number of trailing bytes (0..7) ($2 never used...) - * $6 is known to be aligned 0mod8 + * $16 is known to be aligned 0mod8 */ $headalign: subq $1, 16, $4 # .. .. .. E : If < 16, we can not use the huge loop - and $6, 0x3f, $2 # .. .. E .. : Forward work for huge loop + and $16, 0x3f, $2 # .. .. E .. : Forward work for huge loop subq $2, 0x40, $3 # .. E .. .. : bias counter (huge loop) blt $4, $trailquad # U .. .. .. : U L U L @@ -114,21 +100,21 @@ $headalign: beq $3, $bigalign # U .. .. .. : U L U L : Aligned 0mod64 $alignmod64: - EX( stq_u $31, 0($6) ) # .. .. .. L + EX( stq_u $31, 0($16) ) # .. .. .. L addq $3, 8, $3 # .. .. E .. subq $0, 8, $0 # .. E .. .. nop # E .. .. .. : U L U L nop # .. .. .. E subq $1, 1, $1 # .. .. E .. - addq $6, 8, $6 # .. E .. .. + addq $16, 8, $16 # .. E .. .. blt $3, $alignmod64 # U .. .. .. : U L U L $bigalign: /* * $0 is the number of bytes left * $1 is the number of quads left - * $6 is aligned 0mod64 + * $16 is aligned 0mod64 * we know that we'll be taking a minimum of one trip through * CWG Section 3.7.6: do not expect a sustained store rate of > 1/cycle * We are _not_ going to update $0 after every single store. That @@ -145,39 +131,39 @@ $bigalign: nop # E : nop # E : nop # E : - bis $6,$6,$3 # E : U L U L : Initial wh64 address is dest + bis $16,$16,$3 # E : U L U L : Initial wh64 address is dest /* This might actually help for the current trip... */ $do_wh64: wh64 ($3) # .. .. .. L1 : memory subsystem hint subq $1, 16, $4 # .. .. E .. : Forward calculation - repeat the loop? - EX( stq_u $31, 0($6) ) # .. L .. .. + EX( stq_u $31, 0($16) ) # .. L .. .. subq $0, 8, $0 # E .. .. .. : U L U L - addq $6, 128, $3 # E : Target address of wh64 - EX( stq_u $31, 8($6) ) # L : - EX( stq_u $31, 16($6) ) # L : + addq $16, 128, $3 # E : Target address of wh64 + EX( stq_u $31, 8($16) ) # L : + EX( stq_u $31, 16($16) ) # L : subq $0, 16, $0 # E : U L L U nop # E : - EX( stq_u $31, 24($6) ) # L : - EX( stq_u $31, 32($6) ) # L : + EX( stq_u $31, 24($16) ) # L : + EX( stq_u $31, 32($16) ) # L : subq $0, 168, $5 # E : U L L U : two trips through the loop left? /* 168 = 192 - 24, since we've already completed some stores */ subq $0, 16, $0 # E : - EX( stq_u $31, 40($6) ) # L : - EX( stq_u $31, 48($6) ) # L : - cmovlt $5, $6, $3 # E : U L L U : Latency 2, extra mapping cycle + EX( stq_u $31, 40($16) ) # L : + EX( stq_u $31, 48($16) ) # L : + cmovlt $5, $16, $3 # E : U L L U : Latency 2, extra mapping cycle subq $1, 8, $1 # E : subq $0, 16, $0 # E : - EX( stq_u $31, 56($6) ) # L : + EX( stq_u $31, 56($16) ) # L : nop # E : U L U L nop # E : subq $0, 8, $0 # E : - addq $6, 64, $6 # E : + addq $16, 64, $16 # E : bge $4, $do_wh64 # U : U L U L $trailquad: @@ -190,14 +176,14 @@ $trailquad: beq $1, $trailbytes # U .. .. .. : U L U L : Only 0..7 bytes to go $onequad: - EX( stq_u $31, 0($6) ) # .. .. .. L + EX( stq_u $31, 0($16) ) # .. .. .. L subq $1, 1, $1 # .. .. E .. subq $0, 8, $0 # .. E .. .. nop # E .. .. .. : U L U L nop # .. .. .. E nop # .. .. E .. - addq $6, 8, $6 # .. E .. .. + addq $16, 8, $16 # .. E .. .. bgt $1, $onequad # U .. .. .. : U L U L # We have an unknown number of bytes left to go. @@ -211,9 +197,9 @@ $trailbytes: # so we will use $0 as the loop counter # We know for a fact that $0 > 0 zero due to previous context $onebyte: - EX( stb $31, 0($6) ) # .. .. .. L + EX( stb $31, 0($16) ) # .. .. .. L subq $0, 1, $0 # .. .. E .. : - addq $6, 1, $6 # .. E .. .. : + addq $16, 1, $16 # .. E .. .. : bgt $0, $onebyte # U .. .. .. : U L U L $zerolength: @@ -221,6 +207,6 @@ $exception: # Destination for exception recovery(?) nop # .. .. .. E : nop # .. .. E .. : nop # .. E .. .. : - ret $31, ($28), 1 # L0 .. .. .. : L U L U - .end __do_clear_user - EXPORT_SYMBOL(__do_clear_user) + ret $31, ($26), 1 # L0 .. .. .. : L U L U + .end __clear_user + EXPORT_SYMBOL(__clear_user) diff --git a/arch/alpha/lib/ev6-copy_user.S b/arch/alpha/lib/ev6-copy_user.S index be720b518af9..35e6710d0700 100644 --- a/arch/alpha/lib/ev6-copy_user.S +++ b/arch/alpha/lib/ev6-copy_user.S @@ -12,21 +12,6 @@ * only _after_ a successful copy). There is also some rather minor * exception setup stuff.. * - * NOTE! This is not directly C-callable, because the calling semantics are - * different: - * - * Inputs: - * length in $0 - * destination address in $6 - * source address in $7 - * return address in $28 - * - * Outputs: - * bytes left to copy in $0 - * - * Clobbers: - * $1,$2,$3,$4,$5,$6,$7 - * * Much of the information about 21264 scheduling/coding comes from: * Compiler Writer's Guide for the Alpha 21264 * abbreviated as 'CWG' in other comments here @@ -60,10 +45,11 @@ # Pipeline info: Slotting & Comments __copy_user: .prologue 0 - subq $0, 32, $1 # .. E .. .. : Is this going to be a small copy? + andq $18, $18, $0 + subq $18, 32, $1 # .. E .. .. : Is this going to be a small copy? beq $0, $zerolength # U .. .. .. : U L U L - and $6,7,$3 # .. .. .. E : is leading dest misalignment + and $16,7,$3 # .. .. .. E : is leading dest misalignment ble $1, $onebyteloop # .. .. U .. : 1st branch : small amount of data beq $3, $destaligned # .. U .. .. : 2nd (one cycle fetcher stall) subq $3, 8, $3 # E .. .. .. : L U U L : trip counter @@ -73,17 +59,17 @@ __copy_user: * We know we have at least one trip through this loop */ $aligndest: - EXI( ldbu $1,0($7) ) # .. .. .. L : Keep loads separate from stores - addq $6,1,$6 # .. .. E .. : Section 3.8 in the CWG + EXI( ldbu $1,0($17) ) # .. .. .. L : Keep loads separate from stores + addq $16,1,$16 # .. .. E .. : Section 3.8 in the CWG addq $3,1,$3 # .. E .. .. : nop # E .. .. .. : U L U L /* - * the -1 is to compensate for the inc($6) done in a previous quadpack + * the -1 is to compensate for the inc($16) done in a previous quadpack * which allows us zero dependencies within either quadpack in the loop */ - EXO( stb $1,-1($6) ) # .. .. .. L : - addq $7,1,$7 # .. .. E .. : Section 3.8 in the CWG + EXO( stb $1,-1($16) ) # .. .. .. L : + addq $17,1,$17 # .. .. E .. : Section 3.8 in the CWG subq $0,1,$0 # .. E .. .. : bne $3, $aligndest # U .. .. .. : U L U L @@ -92,29 +78,29 @@ $aligndest: * If we arrived via branch, we have a minimum of 32 bytes */ $destaligned: - and $7,7,$1 # .. .. .. E : Check _current_ source alignment + and $17,7,$1 # .. .. .. E : Check _current_ source alignment bic $0,7,$4 # .. .. E .. : number bytes as a quadword loop - EXI( ldq_u $3,0($7) ) # .. L .. .. : Forward fetch for fallthrough code + EXI( ldq_u $3,0($17) ) # .. L .. .. : Forward fetch for fallthrough code beq $1,$quadaligned # U .. .. .. : U L U L /* - * In the worst case, we've just executed an ldq_u here from 0($7) + * In the worst case, we've just executed an ldq_u here from 0($17) * and we'll repeat it once if we take the branch */ /* Misaligned quadword loop - not unrolled. Leave it that way. */ $misquad: - EXI( ldq_u $2,8($7) ) # .. .. .. L : + EXI( ldq_u $2,8($17) ) # .. .. .. L : subq $4,8,$4 # .. .. E .. : - extql $3,$7,$3 # .. U .. .. : - extqh $2,$7,$1 # U .. .. .. : U U L L + extql $3,$17,$3 # .. U .. .. : + extqh $2,$17,$1 # U .. .. .. : U U L L bis $3,$1,$1 # .. .. .. E : - EXO( stq $1,0($6) ) # .. .. L .. : - addq $7,8,$7 # .. E .. .. : + EXO( stq $1,0($16) ) # .. .. L .. : + addq $17,8,$17 # .. E .. .. : subq $0,8,$0 # E .. .. .. : U L L U - addq $6,8,$6 # .. .. .. E : + addq $16,8,$16 # .. .. .. E : bis $2,$2,$3 # .. .. E .. : nop # .. E .. .. : bne $4,$misquad # U .. .. .. : U L U L @@ -125,8 +111,8 @@ $misquad: beq $0,$zerolength # U .. .. .. : U L U L /* We know we have at least one trip through the byte loop */ - EXI ( ldbu $2,0($7) ) # .. .. .. L : No loads in the same quad - addq $6,1,$6 # .. .. E .. : as the store (Section 3.8 in CWG) + EXI ( ldbu $2,0($17) ) # .. .. .. L : No loads in the same quad + addq $16,1,$16 # .. .. E .. : as the store (Section 3.8 in CWG) nop # .. E .. .. : br $31, $dirtyentry # L0 .. .. .. : L U U L /* Do the trailing byte loop load, then hop into the store part of the loop */ @@ -136,8 +122,8 @@ $misquad: * Based upon the usage context, it's worth the effort to unroll this loop * $0 - number of bytes to be moved * $4 - number of bytes to move as quadwords - * $6 is current destination address - * $7 is current source address + * $16 is current destination address + * $17 is current source address */ $quadaligned: subq $4, 32, $2 # .. .. .. E : do not unroll for small stuff @@ -155,29 +141,29 @@ $quadaligned: * instruction memory hint instruction). */ $unroll4: - EXI( ldq $1,0($7) ) # .. .. .. L - EXI( ldq $2,8($7) ) # .. .. L .. + EXI( ldq $1,0($17) ) # .. .. .. L + EXI( ldq $2,8($17) ) # .. .. L .. subq $4,32,$4 # .. E .. .. nop # E .. .. .. : U U L L - addq $7,16,$7 # .. .. .. E - EXO( stq $1,0($6) ) # .. .. L .. - EXO( stq $2,8($6) ) # .. L .. .. + addq $17,16,$17 # .. .. .. E + EXO( stq $1,0($16) ) # .. .. L .. + EXO( stq $2,8($16) ) # .. L .. .. subq $0,16,$0 # E .. .. .. : U L L U - addq $6,16,$6 # .. .. .. E - EXI( ldq $1,0($7) ) # .. .. L .. - EXI( ldq $2,8($7) ) # .. L .. .. + addq $16,16,$16 # .. .. .. E + EXI( ldq $1,0($17) ) # .. .. L .. + EXI( ldq $2,8($17) ) # .. L .. .. subq $4, 32, $3 # E .. .. .. : U U L L : is there enough for another trip? - EXO( stq $1,0($6) ) # .. .. .. L - EXO( stq $2,8($6) ) # .. .. L .. + EXO( stq $1,0($16) ) # .. .. .. L + EXO( stq $2,8($16) ) # .. .. L .. subq $0,16,$0 # .. E .. .. - addq $7,16,$7 # E .. .. .. : U L L U + addq $17,16,$17 # E .. .. .. : U L L U nop # .. .. .. E nop # .. .. E .. - addq $6,16,$6 # .. E .. .. + addq $16,16,$16 # .. E .. .. bgt $3,$unroll4 # U .. .. .. : U L U L nop @@ -186,14 +172,14 @@ $unroll4: beq $4, $noquads $onequad: - EXI( ldq $1,0($7) ) + EXI( ldq $1,0($17) ) subq $4,8,$4 - addq $7,8,$7 + addq $17,8,$17 nop - EXO( stq $1,0($6) ) + EXO( stq $1,0($16) ) subq $0,8,$0 - addq $6,8,$6 + addq $16,8,$16 bne $4,$onequad $noquads: @@ -207,23 +193,23 @@ $noquads: * There's no point in doing a lot of complex alignment calculations to try to * to quadword stuff for a small amount of data. * $0 - remaining number of bytes left to copy - * $6 - current dest addr - * $7 - current source addr + * $16 - current dest addr + * $17 - current source addr */ $onebyteloop: - EXI ( ldbu $2,0($7) ) # .. .. .. L : No loads in the same quad - addq $6,1,$6 # .. .. E .. : as the store (Section 3.8 in CWG) + EXI ( ldbu $2,0($17) ) # .. .. .. L : No loads in the same quad + addq $16,1,$16 # .. .. E .. : as the store (Section 3.8 in CWG) nop # .. E .. .. : nop # E .. .. .. : U L U L $dirtyentry: /* - * the -1 is to compensate for the inc($6) done in a previous quadpack + * the -1 is to compensate for the inc($16) done in a previous quadpack * which allows us zero dependencies within either quadpack in the loop */ - EXO ( stb $2,-1($6) ) # .. .. .. L : - addq $7,1,$7 # .. .. E .. : quadpack as the load + EXO ( stb $2,-1($16) ) # .. .. .. L : + addq $17,1,$17 # .. .. E .. : quadpack as the load subq $0,1,$0 # .. E .. .. : change count _after_ copy bgt $0,$onebyteloop # U .. .. .. : U L U L @@ -233,7 +219,7 @@ $exitout: # Destination for exception recovery(?) nop # .. .. .. E nop # .. .. E .. nop # .. E .. .. - ret $31,($28),1 # L0 .. .. .. : L U L U + ret $31,($26),1 # L0 .. .. .. : L U L U .end __copy_user EXPORT_SYMBOL(__copy_user) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index c9f30f4763ab..5d7fb3e7cb97 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -406,6 +406,14 @@ config ARC_HAS_DIV_REM bool "Insn: div, divu, rem, remu" default y +config ARC_HAS_ACCL_REGS + bool "Reg Pair ACCL:ACCH (FPU and/or MPY > 6)" + default n + help + Depending on the configuration, CPU can contain accumulator reg-pair + (also referred to as r58:r59). These can also be used by gcc as GPR so + kernel needs to save/restore per process + endif # ISA_ARCV2 endmenu # "ARC CPU Configuration" diff --git a/arch/arc/boot/dts/skeleton.dtsi b/arch/arc/boot/dts/skeleton.dtsi index 65808fe0a290..2891cb266cf0 100644 --- a/arch/arc/boot/dts/skeleton.dtsi +++ b/arch/arc/boot/dts/skeleton.dtsi @@ -26,6 +26,7 @@ device_type = "cpu"; compatible = "snps,arc770d"; reg = <0>; + clocks = <&core_clk>; }; }; diff --git a/arch/arc/boot/dts/skeleton_hs.dtsi b/arch/arc/boot/dts/skeleton_hs.dtsi index 2dfe8037dfbb..5e944d3e5b74 100644 --- a/arch/arc/boot/dts/skeleton_hs.dtsi +++ b/arch/arc/boot/dts/skeleton_hs.dtsi @@ -21,6 +21,7 @@ device_type = "cpu"; compatible = "snps,archs38"; reg = <0>; + clocks = <&core_clk>; }; }; diff --git a/arch/arc/boot/dts/skeleton_hs_idu.dtsi b/arch/arc/boot/dts/skeleton_hs_idu.dtsi index 4c11079f3565..54b277d7dea0 100644 --- a/arch/arc/boot/dts/skeleton_hs_idu.dtsi +++ b/arch/arc/boot/dts/skeleton_hs_idu.dtsi @@ -19,8 +19,27 @@ cpu@0 { device_type = "cpu"; - compatible = "snps,archs38xN"; + compatible = "snps,archs38"; reg = <0>; + clocks = <&core_clk>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <1>; + clocks = <&core_clk>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <2>; + clocks = <&core_clk>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <3>; + clocks = <&core_clk>; }; }; diff --git a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi index f0df59b23e21..459fc656b759 100644 --- a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi +++ b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi @@ -112,13 +112,19 @@ interrupts = <7>; bus-width = <4>; }; + }; - /* Embedded Vision subsystem UIO mappings; only relevant for EV VDK */ - uio_ev: uio@0xD0000000 { - compatible = "generic-uio"; - reg = <0xD0000000 0x2000 0xD1000000 0x2000 0x90000000 0x10000000 0xC0000000 0x10000000>; - reg-names = "ev_gsa", "ev_ctrl", "ev_shared_mem", "ev_code_mem"; - interrupts = <23>; - }; + /* + * Embedded Vision subsystem UIO mappings; only relevant for EV VDK + * + * This node is intentionally put outside of MB above becase + * it maps areas outside of MB's 0xEz-0xFz. + */ + uio_ev: uio@0xD0000000 { + compatible = "generic-uio"; + reg = <0xD0000000 0x2000 0xD1000000 0x2000 0x90000000 0x10000000 0xC0000000 0x10000000>; + reg-names = "ev_gsa", "ev_ctrl", "ev_shared_mem", "ev_code_mem"; + interrupt-parent = <&mb_intc>; + interrupts = <23>; }; }; diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index 63a04013d05a..7bee4e4799fd 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -6,6 +6,7 @@ generic-y += device.h generic-y += div64.h generic-y += emergency-restart.h generic-y += errno.h +generic-y += extable.h generic-y += fb.h generic-y += fcntl.h generic-y += ftrace.h diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index b65930a49589..54b54da6384c 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -17,10 +17,11 @@ #include <asm/barrier.h> #include <asm/smp.h> +#define ATOMIC_INIT(i) { (i) } + #ifndef CONFIG_ARC_PLAT_EZNPS #define atomic_read(v) READ_ONCE((v)->counter) -#define ATOMIC_INIT(i) { (i) } #ifdef CONFIG_ARC_HAS_LLSC diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h index aee1a77934cf..ac85380d14a4 100644 --- a/arch/arc/include/asm/entry-arcv2.h +++ b/arch/arc/include/asm/entry-arcv2.h @@ -16,6 +16,11 @@ ; ; Now manually save: r12, sp, fp, gp, r25 +#ifdef CONFIG_ARC_HAS_ACCL_REGS + PUSH r59 + PUSH r58 +#endif + PUSH r30 PUSH r12 @@ -75,6 +80,11 @@ POP r12 POP r30 +#ifdef CONFIG_ARC_HAS_ACCL_REGS + POP r58 + POP r59 +#endif + .endm /*------------------------------------------------------------------------*/ diff --git a/arch/arc/include/asm/kprobes.h b/arch/arc/include/asm/kprobes.h index 00bdbe167615..2e52d18e6bc7 100644 --- a/arch/arc/include/asm/kprobes.h +++ b/arch/arc/include/asm/kprobes.h @@ -54,9 +54,7 @@ int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause); void kretprobe_trampoline(void); void trap_is_kprobe(unsigned long address, struct pt_regs *regs); #else -static void trap_is_kprobe(unsigned long address, struct pt_regs *regs) -{ -} +#define trap_is_kprobe(address, regs) #endif /* CONFIG_KPROBES */ #endif /* _ARC_KPROBES_H */ diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 47111d565a95..5297faa8a378 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -86,6 +86,10 @@ struct pt_regs { unsigned long r12, r30; +#ifdef CONFIG_ARC_HAS_ACCL_REGS + unsigned long r58, r59; /* ACCL/ACCH used by FPU / DSP MPY */ +#endif + /*------- Below list auto saved by h/w -----------*/ unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11; diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h index 41faf17cd28d..f35974ee7264 100644 --- a/arch/arc/include/asm/uaccess.h +++ b/arch/arc/include/asm/uaccess.h @@ -24,12 +24,10 @@ #ifndef _ASM_ARC_UACCESS_H #define _ASM_ARC_UACCESS_H -#include <linux/sched.h> -#include <asm/errno.h> #include <linux/string.h> /* for generic string functions */ -#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) +#define __kernel_ok (uaccess_kernel()) /* * Algorithmically, for __user_ok() we want do: @@ -170,7 +168,7 @@ static inline unsigned long -__arc_copy_from_user(void *to, const void __user *from, unsigned long n) +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { long res = 0; char val; @@ -396,11 +394,8 @@ __arc_copy_from_user(void *to, const void __user *from, unsigned long n) return res; } -extern unsigned long slowpath_copy_to_user(void __user *to, const void *from, - unsigned long n); - static inline unsigned long -__arc_copy_to_user(void __user *to, const void *from, unsigned long n) +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { long res = 0; char val; @@ -726,24 +721,20 @@ static inline long __arc_strnlen_user(const char __user *s, long n) } #ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE -#define __copy_from_user(t, f, n) __arc_copy_from_user(t, f, n) -#define __copy_to_user(t, f, n) __arc_copy_to_user(t, f, n) + +#define INLINE_COPY_TO_USER +#define INLINE_COPY_FROM_USER + #define __clear_user(d, n) __arc_clear_user(d, n) #define __strncpy_from_user(d, s, n) __arc_strncpy_from_user(d, s, n) #define __strnlen_user(s, n) __arc_strnlen_user(s, n) #else -extern long arc_copy_from_user_noinline(void *to, const void __user * from, - unsigned long n); -extern long arc_copy_to_user_noinline(void __user *to, const void *from, - unsigned long n); extern unsigned long arc_clear_user_noinline(void __user *to, unsigned long n); extern long arc_strncpy_from_user_noinline (char *dst, const char __user *src, long count); extern long arc_strnlen_user_noinline(const char __user *src, long n); -#define __copy_from_user(t, f, n) arc_copy_from_user_noinline(t, f, n) -#define __copy_to_user(t, f, n) arc_copy_to_user_noinline(t, f, n) #define __clear_user(d, n) arc_clear_user_noinline(d, n) #define __strncpy_from_user(d, s, n) arc_strncpy_from_user_noinline(d, s, n) #define __strnlen_user(s, n) arc_strnlen_user_noinline(s, n) @@ -752,6 +743,4 @@ extern long arc_strnlen_user_noinline(const char __user *src, long n); #include <asm-generic/uaccess.h> -extern int fixup_exception(struct pt_regs *regs); - #endif diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S index 2585632eaa68..cc558a25b8fa 100644 --- a/arch/arc/kernel/entry-arcv2.S +++ b/arch/arc/kernel/entry-arcv2.S @@ -100,15 +100,21 @@ END(handle_interrupt) ;################### Non TLB Exception Handling ############################# ENTRY(EV_SWI) - flag 1 + ; TODO: implement this + EXCEPTION_PROLOGUE + b ret_from_exception END(EV_SWI) ENTRY(EV_DivZero) - flag 1 + ; TODO: implement this + EXCEPTION_PROLOGUE + b ret_from_exception END(EV_DivZero) ENTRY(EV_DCError) - flag 1 + ; TODO: implement this + EXCEPTION_PROLOGUE + b ret_from_exception END(EV_DCError) ; --------------------------------------------- diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 3093fa898a23..fc8211f338ad 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -10,6 +10,7 @@ #include <linux/fs.h> #include <linux/delay.h> #include <linux/root_dev.h> +#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/clocksource.h> #include <linux/console.h> @@ -318,7 +319,8 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) static void arc_chk_core_config(void) { struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; - int fpu_enabled; + int saved = 0, present = 0; + char *opt_nm = NULL;; if (!cpu->extn.timer0) panic("Timer0 is not present!\n"); @@ -345,17 +347,28 @@ static void arc_chk_core_config(void) /* * FP hardware/software config sanity - * -If hardware contains DPFP, kernel needs to save/restore FPU state + * -If hardware present, kernel needs to save/restore FPU state * -If not, it will crash trying to save/restore the non-existant regs - * - * (only DPDP checked since SP has no arch visible regs) */ - fpu_enabled = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE); - if (cpu->extn.fpu_dp && !fpu_enabled) - pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n"); - else if (!cpu->extn.fpu_dp && fpu_enabled) - panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n"); + if (is_isa_arcompact()) { + opt_nm = "CONFIG_ARC_FPU_SAVE_RESTORE"; + saved = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE); + + /* only DPDP checked since SP has no arch visible regs */ + present = cpu->extn.fpu_dp; + } else { + opt_nm = "CONFIG_ARC_HAS_ACCL_REGS"; + saved = IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS); + + /* Accumulator Low:High pair (r58:59) present if DSP MPY or FPU */ + present = cpu->extn_mpy.dsp | cpu->extn.fpu_sp | cpu->extn.fpu_dp; + } + + if (present && !saved) + pr_warn("Enable %s for working apps\n", opt_nm); + else if (!present && saved) + panic("Disable %s, hardware NOT present\n", opt_nm); } /* @@ -488,8 +501,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) { char *str; int cpu_id = ptr_to_cpu(v); - struct device_node *core_clk = of_find_node_by_name(NULL, "core_clk"); - u32 freq = 0; + struct device *cpu_dev = get_cpu_device(cpu_id); + struct clk *cpu_clk; + unsigned long freq = 0; if (!cpu_online(cpu_id)) { seq_printf(m, "processor [%d]\t: Offline\n", cpu_id); @@ -502,9 +516,15 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE)); - of_property_read_u32(core_clk, "clock-frequency", &freq); + cpu_clk = clk_get(cpu_dev, NULL); + if (IS_ERR(cpu_clk)) { + seq_printf(m, "CPU speed \t: Cannot get clock for processor [%d]\n", + cpu_id); + } else { + freq = clk_get_rate(cpu_clk); + } if (freq) - seq_printf(m, "CPU speed\t: %u.%02u Mhz\n", + seq_printf(m, "CPU speed\t: %lu.%02lu Mhz\n", freq / 1000000, (freq / 10000) % 100); seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n", diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index d408fa21a07c..928562967f3c 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -633,6 +633,9 @@ noinline static void slc_entire_op(const int op) write_aux_reg(ARC_REG_SLC_INVALIDATE, 1); + /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */ + read_aux_reg(r); + /* Important to wait for flush to complete */ while (read_aux_reg(r) & SLC_CTRL_BUSY); } diff --git a/arch/arc/mm/extable.c b/arch/arc/mm/extable.c index c86906b41bfe..72125a34e780 100644 --- a/arch/arc/mm/extable.c +++ b/arch/arc/mm/extable.c @@ -28,20 +28,6 @@ int fixup_exception(struct pt_regs *regs) #ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE -long arc_copy_from_user_noinline(void *to, const void __user *from, - unsigned long n) -{ - return __arc_copy_from_user(to, from, n); -} -EXPORT_SYMBOL(arc_copy_from_user_noinline); - -long arc_copy_to_user_noinline(void __user *to, const void *from, - unsigned long n) -{ - return __arc_copy_to_user(to, from, n); -} -EXPORT_SYMBOL(arc_copy_to_user_noinline); - unsigned long arc_clear_user_noinline(void __user *to, unsigned long n) { diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0d4e71b42c77..8a7ab5e73af9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -41,7 +41,6 @@ config ARM select HARDIRQS_SW_RESEND select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT) select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 - select HAVE_ARCH_HARDENED_USERCOPY select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU select HAVE_ARCH_MMAP_RND_BITS if MMU diff --git a/arch/arm/boot/dts/am335x-baltos.dtsi b/arch/arm/boot/dts/am335x-baltos.dtsi index efb5eae290a8..d42b98f15e8b 100644 --- a/arch/arm/boot/dts/am335x-baltos.dtsi +++ b/arch/arm/boot/dts/am335x-baltos.dtsi @@ -371,6 +371,8 @@ phy1: ethernet-phy@1 { reg = <7>; + eee-broken-100tx; + eee-broken-1000t; }; }; diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index 9e43c443738a..9ba4b18c0cb2 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -672,6 +672,7 @@ ti,non-removable; bus-width = <4>; cap-power-off-card; + keep-power-in-suspend; pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 2c9e56f4aac5..bbfb9d5a70a9 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -283,6 +283,7 @@ device_type = "pci"; ranges = <0x81000000 0 0 0x03000 0 0x00010000 0x82000000 0 0x20013000 0x13000 0 0xffed000>; + bus-range = <0x00 0xff>; #interrupt-cells = <1>; num-lanes = <1>; linux,pci-domain = <0>; @@ -319,6 +320,7 @@ device_type = "pci"; ranges = <0x81000000 0 0 0x03000 0 0x00010000 0x82000000 0 0x30013000 0x13000 0 0xffed000>; + bus-range = <0x00 0xff>; #interrupt-cells = <1>; num-lanes = <1>; linux,pci-domain = <1>; diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi index 8f9a69ca818c..efe53998c961 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi @@ -121,7 +121,7 @@ &i2c3 { clock-frequency = <400000>; at24@50 { - compatible = "at24,24c02"; + compatible = "atmel,24c64"; readonly; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index cf91254d0a43..1aff4ad22fc4 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -106,6 +106,22 @@ }; }; + timer3: timer@2000e000 { + compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer"; + reg = <0x2000e000 0x20>; + interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru SCLK_TIMER3>, <&cru PCLK_TIMER3>; + clock-names = "timer", "pclk"; + }; + + timer6: timer@200380a0 { + compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer"; + reg = <0x200380a0 0x20>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru SCLK_TIMER6>, <&cru PCLK_TIMER0>; + clock-names = "timer", "pclk"; + }; + i2s0: i2s@1011a000 { compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s"; reg = <0x1011a000 0x2000>; @@ -530,6 +546,7 @@ &global_timer { interrupts = <GIC_PPI 11 0xf04>; + status = "disabled"; }; &local_timer { diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi index 9dff8221112c..641607d9ad29 100644 --- a/arch/arm/boot/dts/rk322x.dtsi +++ b/arch/arm/boot/dts/rk322x.dtsi @@ -325,7 +325,7 @@ }; timer: timer@110c0000 { - compatible = "rockchip,rk3288-timer"; + compatible = "rockchip,rk3228-timer", "rockchip,rk3288-timer"; reg = <0x110c0000 0x20>; interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; clocks = <&xin24m>, <&cru PCLK_TIMER>; diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi index 162e1eb5373d..6c5affe2d0f5 100644 --- a/arch/arm/boot/dts/ste-dbx5x0.dtsi +++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi @@ -1189,11 +1189,6 @@ status = "disabled"; }; - cpufreq-cooling { - compatible = "stericsson,db8500-cpufreq-cooling"; - status = "disabled"; - }; - mcde@a0350000 { compatible = "stericsson,mcde"; reg = <0xa0350000 0x1000>, /* MCDE */ diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi index 18c174fef84f..306af6cadf26 100644 --- a/arch/arm/boot/dts/sun8i-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a33.dtsi @@ -66,12 +66,6 @@ opp-microvolt = <1200000>; clock-latency-ns = <244144>; /* 8 32k periods */ }; - - opp@1200000000 { - opp-hz = /bits/ 64 <1200000000>; - opp-microvolt = <1320000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - }; }; cpus { @@ -81,16 +75,22 @@ operating-points-v2 = <&cpu0_opp_table>; }; + cpu@1 { + operating-points-v2 = <&cpu0_opp_table>; + }; + cpu@2 { compatible = "arm,cortex-a7"; device_type = "cpu"; reg = <2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu@3 { compatible = "arm,cortex-a7"; device_type = "cpu"; reg = <3>; + operating-points-v2 = <&cpu0_opp_table>; }; }; @@ -113,8 +113,8 @@ simple-audio-card,mclk-fs = <512>; simple-audio-card,aux-devs = <&codec_analog>; simple-audio-card,routing = - "Left DAC", "Digital Left DAC", - "Right DAC", "Digital Right DAC"; + "Left DAC", "AIF1 Slot 0 Left", + "Right DAC", "AIF1 Slot 0 Right"; status = "disabled"; simple-audio-card,cpu { diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index a94126fb02c2..6aa7be191f1a 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -748,7 +748,6 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_LEDS_TRIGGER_TRANSIENT=y CONFIG_LEDS_TRIGGER_CAMERA=y CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y CONFIG_EDAC_HIGHBANK_MC=y CONFIG_EDAC_HIGHBANK_L2=y CONFIG_RTC_CLASS=y diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 2aac99fd1c41..1318f61589dc 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -635,8 +635,7 @@ CONFIG_LEDS_TRIGGER_GPIO=m CONFIG_LEDS_TRIGGER_DEFAULT_ON=m CONFIG_LEDS_TRIGGER_TRANSIENT=m CONFIG_LEDS_TRIGGER_CAMERA=m -CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC=m CONFIG_RTC_CLASS=y CONFIG_RTC_DEBUG=y CONFIG_RTC_DRV_DS1307=m diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index b14e8c7d71bd..3a36d99ff836 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -7,6 +7,7 @@ generic-y += early_ioremap.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += ioctl.h generic-y += ipcbuf.h generic-y += irq_regs.h diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index e4e6a9d6a825..17f1f1a814ff 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -85,6 +85,18 @@ static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) */ #define ZIMAGE_OFFSET_LIMIT SZ_128M #define MIN_ZIMAGE_OFFSET MAX_UNCOMP_KERNEL_SIZE -#define MAX_FDT_OFFSET ZIMAGE_OFFSET_LIMIT + +/* on ARM, the FDT should be located in the first 128 MB of RAM */ +static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) +{ + return dram_base + ZIMAGE_OFFSET_LIMIT; +} + +/* on ARM, the initrd should be loaded in a lowmem region */ +static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, + unsigned long image_addr) +{ + return dram_base + SZ_512M; +} #endif /* _ASM_ARM_EFI_H */ diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index b7e0125c0bbf..2577405d082d 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -12,8 +12,6 @@ * User space memory access functions */ #include <linux/string.h> -#include <linux/thread_info.h> -#include <asm/errno.h> #include <asm/memory.h> #include <asm/domain.h> #include <asm/unified.h> @@ -26,28 +24,7 @@ #define __put_user_unaligned __put_user #endif -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -extern int fixup_exception(struct pt_regs *regs); +#include <asm/extable.h> /* * These two functions allow hooking accesses to userspace to increase @@ -271,7 +248,7 @@ static inline void set_fs(mm_segment_t fs) #define access_ok(type, addr, size) (__range_ok(addr, size) == 0) #define user_addr_max() \ - (segment_eq(get_fs(), KERNEL_DS) ? ~0UL : get_fs()) + (uaccess_kernel() ? ~0UL : get_fs()) /* * The "__xxx" versions of the user access functions do not verify the @@ -478,7 +455,7 @@ extern unsigned long __must_check arm_copy_from_user(void *to, const void __user *from, unsigned long n); static inline unsigned long __must_check -__arch_copy_from_user(void *to, const void __user *from, unsigned long n) +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { unsigned int __ua_flags; @@ -494,7 +471,7 @@ extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n); static inline unsigned long __must_check -__arch_copy_to_user(void __user *to, const void *from, unsigned long n) +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { #ifndef CONFIG_UACCESS_WITH_MEMCPY unsigned int __ua_flags; @@ -522,54 +499,22 @@ __clear_user(void __user *addr, unsigned long n) } #else -#define __arch_copy_from_user(to, from, n) \ - (memcpy(to, (void __force *)from, n), 0) -#define __arch_copy_to_user(to, from, n) \ - (memcpy((void __force *)to, from, n), 0) -#define __clear_user(addr, n) (memset((void __force *)addr, 0, n), 0) -#endif - -static inline unsigned long __must_check -__copy_from_user(void *to, const void __user *from, unsigned long n) -{ - check_object_size(to, n, false); - return __arch_copy_from_user(to, from, n); -} - -static inline unsigned long __must_check -copy_from_user(void *to, const void __user *from, unsigned long n) -{ - unsigned long res = n; - - check_object_size(to, n, false); - - if (likely(access_ok(VERIFY_READ, from, n))) - res = __arch_copy_from_user(to, from, n); - if (unlikely(res)) - memset(to + (n - res), 0, res); - return res; -} - -static inline unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n) +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - check_object_size(from, n, true); - - return __arch_copy_to_user(to, from, n); + memcpy(to, (const void __force *)from, n); + return 0; } - -static inline unsigned long __must_check -copy_to_user(void __user *to, const void *from, unsigned long n) +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - check_object_size(from, n, true); - - if (access_ok(VERIFY_WRITE, to, n)) - n = __arch_copy_to_user(to, from, n); - return n; + memcpy((void __force *)to, from, n); + return 0; } - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user +#define __clear_user(addr, n) (memset((void __force *)addr, 0, n), 0) +#endif +#define INLINE_COPY_TO_USER +#define INLINE_COPY_FROM_USER static inline unsigned long __must_check clear_user(void __user *to, unsigned long n) { diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S index 37b2a11af345..8265b116218d 100644 --- a/arch/arm/kernel/vmlinux-xip.lds.S +++ b/arch/arm/kernel/vmlinux-xip.lds.S @@ -242,6 +242,8 @@ SECTIONS } _edata_loc = __data_loc + SIZEOF(.data); + BUG_TABLE + #ifdef CONFIG_HAVE_TCM /* * We align everything to a page boundary so we can diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index ce18007f9e4e..c83a7ba737d6 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -262,6 +262,8 @@ SECTIONS } _edata_loc = __data_loc + SIZEOF(.data); + BUG_TABLE + #ifdef CONFIG_HAVE_TCM /* * We align everything to a page boundary so we can diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 96dba7cd8be7..314eb6abe1ff 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -1124,6 +1124,9 @@ static void cpu_hyp_reinit(void) if (__hyp_get_vectors() == hyp_default_vectors) cpu_init_hyp_mode(NULL); } + + if (vgic_present) + kvm_vgic_init_cpu_hardware(); } static void cpu_hyp_reset(void) diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 962616fd4ddd..582a972371cf 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -292,11 +292,18 @@ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size) phys_addr_t addr = start, end = start + size; phys_addr_t next; + assert_spin_locked(&kvm->mmu_lock); pgd = kvm->arch.pgd + stage2_pgd_index(addr); do { next = stage2_pgd_addr_end(addr, end); if (!stage2_pgd_none(*pgd)) unmap_stage2_puds(kvm, pgd, addr, next); + /* + * If the range is too large, release the kvm->mmu_lock + * to prevent starvation and lockup detector warnings. + */ + if (next != end) + cond_resched_lock(&kvm->mmu_lock); } while (pgd++, addr = next, addr != end); } @@ -803,6 +810,7 @@ void stage2_unmap_vm(struct kvm *kvm) int idx; idx = srcu_read_lock(&kvm->srcu); + down_read(¤t->mm->mmap_sem); spin_lock(&kvm->mmu_lock); slots = kvm_memslots(kvm); @@ -810,6 +818,7 @@ void stage2_unmap_vm(struct kvm *kvm) stage2_unmap_memslot(kvm, memslot); spin_unlock(&kvm->mmu_lock); + up_read(¤t->mm->mmap_sem); srcu_read_unlock(&kvm->srcu, idx); } @@ -829,7 +838,10 @@ void kvm_free_stage2_pgd(struct kvm *kvm) if (kvm->arch.pgd == NULL) return; + spin_lock(&kvm->mmu_lock); unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE); + spin_unlock(&kvm->mmu_lock); + /* Free the HW pgd, one page at a time */ free_pages_exact(kvm->arch.pgd, S2_PGD_SIZE); kvm->arch.pgd = NULL; @@ -1801,6 +1813,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, (KVM_PHYS_SIZE >> PAGE_SHIFT)) return -EFAULT; + down_read(¤t->mm->mmap_sem); /* * A memory region could potentially cover multiple VMAs, and any holes * between them, so iterate over all of them to find out if we can map @@ -1844,8 +1857,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, pa += vm_start - vma->vm_start; /* IO region dirty page logging not allowed */ - if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) - return -EINVAL; + if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) { + ret = -EINVAL; + goto out; + } ret = kvm_phys_addr_ioremap(kvm, gpa, pa, vm_end - vm_start, @@ -1857,7 +1872,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, } while (hva < reg_end); if (change == KVM_MR_FLAGS_ONLY) - return ret; + goto out; spin_lock(&kvm->mmu_lock); if (ret) @@ -1865,6 +1880,8 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, else stage2_flush_memslot(kvm, memslot); spin_unlock(&kvm->mmu_lock); +out: + up_read(¤t->mm->mmap_sem); return ret; } diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c index 6bd1089b07e0..9b4ed1728616 100644 --- a/arch/arm/lib/uaccess_with_memcpy.c +++ b/arch/arm/lib/uaccess_with_memcpy.c @@ -90,7 +90,7 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n) unsigned long ua_flags; int atomic; - if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { + if (uaccess_kernel()) { memcpy((void *)to, from, n); return 0; } @@ -162,7 +162,7 @@ __clear_user_memset(void __user *addr, unsigned long n) { unsigned long ua_flags; - if (unlikely(segment_eq(get_fs(), KERNEL_DS))) { + if (uaccess_kernel()) { memset((void *)addr, 0, n); return 0; } diff --git a/arch/arm/mach-moxart/Kconfig b/arch/arm/mach-moxart/Kconfig index f69e28b85e88..70db2abf6163 100644 --- a/arch/arm/mach-moxart/Kconfig +++ b/arch/arm/mach-moxart/Kconfig @@ -3,8 +3,8 @@ menuconfig ARCH_MOXART depends on ARCH_MULTI_V4 select CPU_FA526 select ARM_DMA_MEM_BUFFERABLE + select FARADAY_FTINTC010 select MOXART_TIMER - select GENERIC_IRQ_CHIP select GPIOLIB select PHYLIB if NETDEVICES help diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index c4f2ace91ea2..3089d3bfa19b 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -270,6 +270,7 @@ extern const struct smp_operations omap4_smp_ops; extern int omap4_mpuss_init(void); extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state); extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state); +extern u32 omap4_get_cpu1_ns_pa_addr(void); #else static inline int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index d3fb5661bb5d..433db6d0b073 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c @@ -50,7 +50,7 @@ void omap4_cpu_die(unsigned int cpu) omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF); if (omap_secure_apis_support()) - boot_cpu = omap_read_auxcoreboot0(); + boot_cpu = omap_read_auxcoreboot0() >> 9; else boot_cpu = readl_relaxed(base + OMAP_AUX_CORE_BOOT_0) >> 5; diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 113ab2dd2ee9..03ec6d307c82 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -64,6 +64,7 @@ #include "prm-regbits-44xx.h" static void __iomem *sar_base; +static u32 old_cpu1_ns_pa_addr; #if defined(CONFIG_PM) && defined(CONFIG_SMP) @@ -212,6 +213,11 @@ static void __init save_l2x0_context(void) {} #endif +u32 omap4_get_cpu1_ns_pa_addr(void) +{ + return old_cpu1_ns_pa_addr; +} + /** * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function * The purpose of this function is to manage low power programming @@ -460,22 +466,30 @@ int __init omap4_mpuss_init(void) void __init omap4_mpuss_early_init(void) { unsigned long startup_pa; + void __iomem *ns_pa_addr; - if (!(cpu_is_omap44xx() || soc_is_omap54xx())) + if (!(soc_is_omap44xx() || soc_is_omap54xx())) return; sar_base = omap4_get_sar_ram_base(); - if (cpu_is_omap443x()) + /* Save old NS_PA_ADDR for validity checks later on */ + if (soc_is_omap44xx()) + ns_pa_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; + else + ns_pa_addr = sar_base + OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET; + old_cpu1_ns_pa_addr = readl_relaxed(ns_pa_addr); + + if (soc_is_omap443x()) startup_pa = __pa_symbol(omap4_secondary_startup); - else if (cpu_is_omap446x()) + else if (soc_is_omap446x()) startup_pa = __pa_symbol(omap4460_secondary_startup); else if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE) startup_pa = __pa_symbol(omap5_secondary_hyp_startup); else startup_pa = __pa_symbol(omap5_secondary_startup); - if (cpu_is_omap44xx()) + if (soc_is_omap44xx()) writel_relaxed(startup_pa, sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET); else diff --git a/arch/arm/mach-omap2/omap-smc.S b/arch/arm/mach-omap2/omap-smc.S index fd90125bffc7..72506e6cf9e7 100644 --- a/arch/arm/mach-omap2/omap-smc.S +++ b/arch/arm/mach-omap2/omap-smc.S @@ -94,6 +94,5 @@ ENTRY(omap_read_auxcoreboot0) ldr r12, =0x103 dsb smc #0 - mov r0, r0, lsr #9 ldmfd sp!, {r2-r12, pc} ENDPROC(omap_read_auxcoreboot0) diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 003353b0b794..3faf454ba487 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -21,6 +21,7 @@ #include <linux/io.h> #include <linux/irqchip/arm-gic.h> +#include <asm/sections.h> #include <asm/smp_scu.h> #include <asm/virt.h> @@ -40,10 +41,14 @@ #define OMAP5_CORE_COUNT 0x2 +#define AUX_CORE_BOOT0_GP_RELEASE 0x020 +#define AUX_CORE_BOOT0_HS_RELEASE 0x200 + struct omap_smp_config { unsigned long cpu1_rstctrl_pa; void __iomem *cpu1_rstctrl_va; void __iomem *scu_base; + void __iomem *wakeupgen_base; void *startup_addr; }; @@ -140,7 +145,6 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) static struct clockdomain *cpu1_clkdm; static bool booted; static struct powerdomain *cpu1_pwrdm; - void __iomem *base = omap_get_wakeupgen_base(); /* * Set synchronisation state between this boot processor @@ -155,9 +159,11 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) * A barrier is added to ensure that write buffer is drained */ if (omap_secure_apis_support()) - omap_modify_auxcoreboot0(0x200, 0xfffffdff); + omap_modify_auxcoreboot0(AUX_CORE_BOOT0_HS_RELEASE, + 0xfffffdff); else - writel_relaxed(0x20, base + OMAP_AUX_CORE_BOOT_0); + writel_relaxed(AUX_CORE_BOOT0_GP_RELEASE, + cfg.wakeupgen_base + OMAP_AUX_CORE_BOOT_0); if (!cpu1_clkdm && !cpu1_pwrdm) { cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); @@ -261,9 +267,72 @@ static void __init omap4_smp_init_cpus(void) set_cpu_possible(i, true); } +/* + * For now, just make sure the start-up address is not within the booting + * kernel space as that means we just overwrote whatever secondary_startup() + * code there was. + */ +static bool __init omap4_smp_cpu1_startup_valid(unsigned long addr) +{ + if ((addr >= __pa(PAGE_OFFSET)) && (addr <= __pa(__bss_start))) + return false; + + return true; +} + +/* + * We may need to reset CPU1 before configuring, otherwise kexec boot can end + * up trying to use old kernel startup address or suspend-resume will + * occasionally fail to bring up CPU1 on 4430 if CPU1 fails to enter deeper + * idle states. + */ +static void __init omap4_smp_maybe_reset_cpu1(struct omap_smp_config *c) +{ + unsigned long cpu1_startup_pa, cpu1_ns_pa_addr; + bool needs_reset = false; + u32 released; + + if (omap_secure_apis_support()) + released = omap_read_auxcoreboot0() & AUX_CORE_BOOT0_HS_RELEASE; + else + released = readl_relaxed(cfg.wakeupgen_base + + OMAP_AUX_CORE_BOOT_0) & + AUX_CORE_BOOT0_GP_RELEASE; + if (released) { + pr_warn("smp: CPU1 not parked?\n"); + + return; + } + + cpu1_startup_pa = readl_relaxed(cfg.wakeupgen_base + + OMAP_AUX_CORE_BOOT_1); + cpu1_ns_pa_addr = omap4_get_cpu1_ns_pa_addr(); + + /* Did the configured secondary_startup() get overwritten? */ + if (!omap4_smp_cpu1_startup_valid(cpu1_startup_pa)) + needs_reset = true; + + /* + * If omap4 or 5 has NS_PA_ADDR configured, CPU1 may be in a + * deeper idle state in WFI and will wake to an invalid address. + */ + if ((soc_is_omap44xx() || soc_is_omap54xx()) && + !omap4_smp_cpu1_startup_valid(cpu1_ns_pa_addr)) + needs_reset = true; + + if (!needs_reset || !c->cpu1_rstctrl_va) + return; + + pr_info("smp: CPU1 parked within kernel, needs reset (0x%lx 0x%lx)\n", + cpu1_startup_pa, cpu1_ns_pa_addr); + + writel_relaxed(1, c->cpu1_rstctrl_va); + readl_relaxed(c->cpu1_rstctrl_va); + writel_relaxed(0, c->cpu1_rstctrl_va); +} + static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) { - void __iomem *base = omap_get_wakeupgen_base(); const struct omap_smp_config *c = NULL; if (soc_is_omap443x()) @@ -281,6 +350,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) /* Must preserve cfg.scu_base set earlier */ cfg.cpu1_rstctrl_pa = c->cpu1_rstctrl_pa; cfg.startup_addr = c->startup_addr; + cfg.wakeupgen_base = omap_get_wakeupgen_base(); if (soc_is_dra74x() || soc_is_omap54xx()) { if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE) @@ -299,15 +369,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) if (cfg.scu_base) scu_enable(cfg.scu_base); - /* - * Reset CPU1 before configuring, otherwise kexec will - * end up trying to use old kernel startup address. - */ - if (cfg.cpu1_rstctrl_va) { - writel_relaxed(1, cfg.cpu1_rstctrl_va); - readl_relaxed(cfg.cpu1_rstctrl_va); - writel_relaxed(0, cfg.cpu1_rstctrl_va); - } + omap4_smp_maybe_reset_cpu1(&cfg); /* * Write the address of secondary startup routine into the @@ -319,7 +381,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) omap_auxcoreboot_addr(__pa_symbol(cfg.startup_addr)); else writel_relaxed(__pa_symbol(cfg.startup_addr), - base + OMAP_AUX_CORE_BOOT_1); + cfg.wakeupgen_base + OMAP_AUX_CORE_BOOT_1); } const struct smp_operations omap4_smp_ops __initconst = { diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index e920dd83e443..f989145480c8 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -222,6 +222,14 @@ static int _omap_device_notifier_call(struct notifier_block *nb, dev_err(dev, "failed to idle\n"); } break; + case BUS_NOTIFY_BIND_DRIVER: + od = to_omap_device(pdev); + if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED) && + pm_runtime_status_suspended(dev)) { + od->_driver_status = BUS_NOTIFY_BIND_DRIVER; + pm_runtime_set_active(dev); + } + break; case BUS_NOTIFY_ADD_DEVICE: if (pdev->dev.of_node) omap_device_build_from_dt(pdev); diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index 633442ad4e4c..2a7bb6ccdcb7 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -6,6 +6,7 @@ menuconfig ARCH_ORION5X select GPIOLIB select MVEBU_MBUS select PCI + select PHYLIB if NETDEVICES select PLAT_ORION_LEGACY help Support for the following Marvell Orion 5x series SoCs: diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 63eabb06f9f1..475811f5383a 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -935,13 +935,31 @@ static void arm_coherent_dma_free(struct device *dev, size_t size, void *cpu_add __arm_dma_free(dev, size, cpu_addr, handle, attrs, true); } +/* + * The whole dma_get_sgtable() idea is fundamentally unsafe - it seems + * that the intention is to allow exporting memory allocated via the + * coherent DMA APIs through the dma_buf API, which only accepts a + * scattertable. This presents a couple of problems: + * 1. Not all memory allocated via the coherent DMA APIs is backed by + * a struct page + * 2. Passing coherent DMA memory into the streaming APIs is not allowed + * as we will try to flush the memory through a different alias to that + * actually being used (and the flushes are redundant.) + */ int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt, void *cpu_addr, dma_addr_t handle, size_t size, unsigned long attrs) { - struct page *page = pfn_to_page(dma_to_pfn(dev, handle)); + unsigned long pfn = dma_to_pfn(dev, handle); + struct page *page; int ret; + /* If the PFN is not valid, we do not have a struct page */ + if (!pfn_valid(pfn)) + return -ENXIO; + + page = pfn_to_page(pfn); + ret = sg_alloc_table(sgt, 1, GFP_KERNEL); if (unlikely(ret)) return ret; diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 3b5c7aaf9c76..33a45bd96860 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -303,7 +303,10 @@ static inline void set_vbar(unsigned long val) */ static inline bool security_extensions_enabled(void) { - return !!cpuid_feature_extract(CPUID_EXT_PFR1, 4); + /* Check CPUID Identification Scheme before ID_PFR1 read */ + if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) + return !!cpuid_feature_extract(CPUID_EXT_PFR1, 4); + return 0; } static unsigned long __init setup_vectors_base(void) diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 9255b6d67ba5..aff6994950ba 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -468,6 +468,7 @@ void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, eth_data, &orion_ge11); } +#ifdef CONFIG_ARCH_ORION5X /***************************************************************************** * Ethernet switch ****************************************************************************/ @@ -480,6 +481,9 @@ void __init orion_ge00_switch_init(struct dsa_chip_data *d) struct mdio_board_info *bd; unsigned int i; + if (!IS_BUILTIN(CONFIG_PHYLIB)) + return; + for (i = 0; i < ARRAY_SIZE(d->port_names); i++) if (!strcmp(d->port_names[i], "cpu")) break; @@ -493,6 +497,7 @@ void __init orion_ge00_switch_init(struct dsa_chip_data *d) mdiobus_register_board_info(&orion_ge00_switch_board_info, 1); } +#endif /***************************************************************************** * I2C diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c index b6dc9d838a9a..ad1f4e6a9e33 100644 --- a/arch/arm/probes/kprobes/core.c +++ b/arch/arm/probes/kprobes/core.c @@ -266,11 +266,20 @@ void __kprobes kprobe_handler(struct pt_regs *regs) #endif if (p) { - if (cur) { + if (!p->ainsn.insn_check_cc(regs->ARM_cpsr)) { + /* + * Probe hit but conditional execution check failed, + * so just skip the instruction and continue as if + * nothing had happened. + * In this case, we can skip recursing check too. + */ + singlestep_skip(p, regs); + } else if (cur) { /* Kprobe is pending, so we're recursing. */ switch (kcb->kprobe_status) { case KPROBE_HIT_ACTIVE: case KPROBE_HIT_SSDONE: + case KPROBE_HIT_SS: /* A pre- or post-handler probe got us here. */ kprobes_inc_nmissed_count(p); save_previous_kprobe(kcb); @@ -279,11 +288,16 @@ void __kprobes kprobe_handler(struct pt_regs *regs) singlestep(p, regs, kcb); restore_previous_kprobe(kcb); break; + case KPROBE_REENTER: + /* A nested probe was hit in FIQ, it is a BUG */ + pr_warn("Unrecoverable kprobe detected at %p.\n", + p->addr); + /* fall through */ default: /* impossible cases */ BUG(); } - } else if (p->ainsn.insn_check_cc(regs->ARM_cpsr)) { + } else { /* Probe hit and conditional execution check ok. */ set_current_kprobe(p); kcb->kprobe_status = KPROBE_HIT_ACTIVE; @@ -304,13 +318,6 @@ void __kprobes kprobe_handler(struct pt_regs *regs) } reset_current_kprobe(); } - } else { - /* - * Probe hit but conditional execution check failed, - * so just skip the instruction and continue as if - * nothing had happened. - */ - singlestep_skip(p, regs); } } else if (cur) { /* We probably hit a jprobe. Call its break handler. */ @@ -434,6 +441,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) struct hlist_node *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; + kprobe_opcode_t *correct_ret_addr = NULL; INIT_HLIST_HEAD(&empty_rp); kretprobe_hash_lock(current, &head, &flags); @@ -456,14 +464,34 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) /* another task is sharing our hash bucket */ continue; + orig_ret_address = (unsigned long)ri->ret_addr; + + if (orig_ret_address != trampoline_address) + /* + * This is the real return address. Any other + * instances associated with this task are for + * other calls deeper on the call stack + */ + break; + } + + kretprobe_assert(ri, orig_ret_address, trampoline_address); + + correct_ret_addr = ri->ret_addr; + hlist_for_each_entry_safe(ri, tmp, head, hlist) { + if (ri->task != current) + /* another task is sharing our hash bucket */ + continue; + + orig_ret_address = (unsigned long)ri->ret_addr; if (ri->rp && ri->rp->handler) { __this_cpu_write(current_kprobe, &ri->rp->kp); get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; + ri->ret_addr = correct_ret_addr; ri->rp->handler(ri, regs); __this_cpu_write(current_kprobe, NULL); } - orig_ret_address = (unsigned long)ri->ret_addr; recycle_rp_inst(ri, &empty_rp); if (orig_ret_address != trampoline_address) @@ -475,7 +503,6 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) break; } - kretprobe_assert(ri, orig_ret_address, trampoline_address); kretprobe_hash_unlock(current, &flags); hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { diff --git a/arch/arm/probes/kprobes/test-core.c b/arch/arm/probes/kprobes/test-core.c index c893726aa52d..1c98a87786ca 100644 --- a/arch/arm/probes/kprobes/test-core.c +++ b/arch/arm/probes/kprobes/test-core.c @@ -977,7 +977,10 @@ static void coverage_end(void) void __naked __kprobes_test_case_start(void) { __asm__ __volatile__ ( - "stmdb sp!, {r4-r11} \n\t" + "mov r2, sp \n\t" + "bic r3, r2, #7 \n\t" + "mov sp, r3 \n\t" + "stmdb sp!, {r2-r11} \n\t" "sub sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t" "bic r0, lr, #1 @ r0 = inline data \n\t" "mov r1, sp \n\t" @@ -997,7 +1000,8 @@ void __naked __kprobes_test_case_end_32(void) "movne pc, r0 \n\t" "mov r0, r4 \n\t" "add sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t" - "ldmia sp!, {r4-r11} \n\t" + "ldmia sp!, {r2-r11} \n\t" + "mov sp, r2 \n\t" "mov pc, r0 \n\t" ); } @@ -1013,7 +1017,8 @@ void __naked __kprobes_test_case_end_16(void) "bxne r0 \n\t" "mov r0, r4 \n\t" "add sp, sp, #"__stringify(TEST_MEMORY_SIZE)"\n\t" - "ldmia sp!, {r4-r11} \n\t" + "ldmia sp!, {r2-r11} \n\t" + "mov sp, r2 \n\t" "bx r0 \n\t" ); } diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3741859765cf..67695fadae96 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -2,6 +2,7 @@ config ARM64 def_bool y select ACPI_CCA_REQUIRED if ACPI select ACPI_GENERIC_GSI if ACPI + select ACPI_GTDT if ACPI select ACPI_REDUCED_HARDWARE_ONLY if ACPI select ACPI_MCFG if ACPI select ACPI_SPCR_TABLE if ACPI @@ -60,7 +61,6 @@ config ARM64 select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_BITREVERSE - select HAVE_ARCH_HARDENED_USERCOPY select HAVE_ARCH_HUGE_VMAP select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP && !(ARM64_16K_PAGES && ARM64_VA_BITS_48) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index 1c64ea2d23f9..0565779e66fa 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -179,8 +179,10 @@ usbphy: phy@01c19400 { compatible = "allwinner,sun50i-a64-usb-phy"; reg = <0x01c19400 0x14>, + <0x01c1a800 0x4>, <0x01c1b800 0x4>; reg-names = "phy_ctrl", + "pmu0", "pmu1"; clocks = <&ccu CLK_USB_PHY0>, <&ccu CLK_USB_PHY1>; diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index b4b34004a21e..74d08e44a651 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -25,6 +25,7 @@ #include <linux/bug.h> #include <linux/init.h> #include <linux/jump_label.h> +#include <linux/smp.h> #include <linux/types.h> #include <clocksource/arm_arch_timer.h> @@ -37,24 +38,44 @@ extern struct static_key_false arch_timer_read_ool_enabled; #define needs_unstable_timer_counter_workaround() false #endif +enum arch_timer_erratum_match_type { + ate_match_dt, + ate_match_local_cap_id, + ate_match_acpi_oem_info, +}; + +struct clock_event_device; struct arch_timer_erratum_workaround { - const char *id; /* Indicate the Erratum ID */ + enum arch_timer_erratum_match_type match_type; + const void *id; + const char *desc; u32 (*read_cntp_tval_el0)(void); u32 (*read_cntv_tval_el0)(void); u64 (*read_cntvct_el0)(void); + int (*set_next_event_phys)(unsigned long, struct clock_event_device *); + int (*set_next_event_virt)(unsigned long, struct clock_event_device *); }; -extern const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround; - -#define arch_timer_reg_read_stable(reg) \ -({ \ - u64 _val; \ - if (needs_unstable_timer_counter_workaround()) \ - _val = timer_unstable_counter_workaround->read_##reg();\ - else \ - _val = read_sysreg(reg); \ - _val; \ +DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *, + timer_unstable_counter_workaround); + +#define arch_timer_reg_read_stable(reg) \ +({ \ + u64 _val; \ + if (needs_unstable_timer_counter_workaround()) { \ + const struct arch_timer_erratum_workaround *wa; \ + preempt_disable(); \ + wa = __this_cpu_read(timer_unstable_counter_workaround); \ + if (wa && wa->read_##reg) \ + _val = wa->read_##reg(); \ + else \ + _val = read_sysreg(reg); \ + preempt_enable(); \ + } else { \ + _val = read_sysreg(reg); \ + } \ + _val; \ }) /* diff --git a/arch/arm64/include/asm/bug.h b/arch/arm64/include/asm/bug.h index 561190d15881..a9be1072933c 100644 --- a/arch/arm64/include/asm/bug.h +++ b/arch/arm64/include/asm/bug.h @@ -55,7 +55,7 @@ _BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ unreachable(); \ } while (0) -#define __WARN_TAINT(taint) _BUG_FLAGS(BUGFLAG_TAINT(taint)) +#define __WARN_FLAGS(flags) _BUG_FLAGS(BUGFLAG_WARNING|(flags)) #endif /* ! CONFIG_GENERIC_BUG */ diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index fb78a5d3b60b..b3aab8a17868 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -37,7 +37,8 @@ #define ARM64_HAS_NO_FPSIMD 16 #define ARM64_WORKAROUND_REPEAT_TLBI 17 #define ARM64_WORKAROUND_QCOM_FALKOR_E1003 18 +#define ARM64_WORKAROUND_858921 19 -#define ARM64_NCAPS 19 +#define ARM64_NCAPS 20 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index fc502713ab37..0984d1b3a8f2 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -80,6 +80,7 @@ #define ARM_CPU_PART_FOUNDATION 0xD00 #define ARM_CPU_PART_CORTEX_A57 0xD07 #define ARM_CPU_PART_CORTEX_A53 0xD03 +#define ARM_CPU_PART_CORTEX_A73 0xD09 #define APM_CPU_PART_POTENZA 0x000 @@ -92,6 +93,7 @@ #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) +#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1) diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h index 86c404171305..f6580d4afb0e 100644 --- a/arch/arm64/include/asm/current.h +++ b/arch/arm64/include/asm/current.h @@ -3,8 +3,6 @@ #include <linux/compiler.h> -#include <asm/sysreg.h> - #ifndef __ASSEMBLY__ struct task_struct; diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index e7445281e534..8f3043aba873 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -1,6 +1,7 @@ #ifndef _ASM_EFI_H #define _ASM_EFI_H +#include <asm/boot.h> #include <asm/cpufeature.h> #include <asm/io.h> #include <asm/mmu_context.h> @@ -46,7 +47,28 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); * 2MiB so we know it won't cross a 2MiB boundary. */ #define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */ -#define MAX_FDT_OFFSET SZ_512M + +/* on arm64, the FDT may be located anywhere in system RAM */ +static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) +{ + return ULONG_MAX; +} + +/* + * On arm64, we have to ensure that the initrd ends up in the linear region, + * which is a 1 GB aligned region of size '1UL << (VA_BITS - 1)' that is + * guaranteed to cover the kernel Image. + * + * Since the EFI stub is part of the kernel Image, we can relax the + * usual requirements in Documentation/arm64/booting.txt, which still + * apply to other bootloaders, and are required for some kernel + * configurations. + */ +static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, + unsigned long image_addr) +{ + return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS - 1)); +} #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) #define __efi_call_early(f, ...) f(__VA_ARGS__) diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index d14c478976d0..ad42e79a5d4d 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -175,6 +175,8 @@ #define ESR_ELx_SYS64_ISS_SYS_CTR_READ (ESR_ELx_SYS64_ISS_SYS_CTR | \ ESR_ELx_SYS64_ISS_DIR_READ) +#define ESR_ELx_SYS64_ISS_SYS_CNTVCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \ + ESR_ELx_SYS64_ISS_DIR_READ) #ifndef __ASSEMBLY__ #include <asm/types.h> diff --git a/arch/arm64/include/asm/extable.h b/arch/arm64/include/asm/extable.h new file mode 100644 index 000000000000..42f50f15a44c --- /dev/null +++ b/arch/arm64/include/asm/extable.h @@ -0,0 +1,25 @@ +#ifndef __ASM_EXTABLE_H +#define __ASM_EXTABLE_H + +/* + * The exception table consists of pairs of relative offsets: the first + * is the relative offset to an instruction that is allowed to fault, + * and the second is the relative offset at which the program should + * continue. No registers are modified, so it is entirely up to the + * continuation code to figure out what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + int insn, fixup; +}; + +#define ARCH_HAS_RELATIVE_EXTABLE + +extern int fixup_exception(struct pt_regs *regs); +#endif diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index 5308d696311b..ba497172610d 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -28,38 +28,12 @@ #include <linux/bitops.h> #include <linux/kasan-checks.h> #include <linux/string.h> -#include <linux/thread_info.h> #include <asm/cpufeature.h> #include <asm/ptrace.h> -#include <asm/errno.h> #include <asm/memory.h> #include <asm/compiler.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -/* - * The exception table consists of pairs of relative offsets: the first - * is the relative offset to an instruction that is allowed to fault, - * and the second is the relative offset at which the program should - * continue. No registers are modified, so it is entirely up to the - * continuation code to figure out what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - int insn, fixup; -}; - -#define ARCH_HAS_RELATIVE_EXTABLE - -extern int fixup_exception(struct pt_regs *regs); +#include <asm/extable.h> #define KERNEL_DS (-1UL) #define get_ds() (KERNEL_DS) @@ -357,58 +331,13 @@ do { \ }) extern unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n); +#define raw_copy_from_user __arch_copy_from_user extern unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n); -extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n); +#define raw_copy_to_user __arch_copy_to_user +extern unsigned long __must_check raw_copy_in_user(void __user *to, const void __user *from, unsigned long n); extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); - -static inline unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n) -{ - kasan_check_write(to, n); - check_object_size(to, n, false); - return __arch_copy_from_user(to, from, n); -} - -static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n) -{ - kasan_check_read(from, n); - check_object_size(from, n, true); - return __arch_copy_to_user(to, from, n); -} - -static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) -{ - unsigned long res = n; - kasan_check_write(to, n); - check_object_size(to, n, false); - - if (access_ok(VERIFY_READ, from, n)) { - res = __arch_copy_from_user(to, from, n); - } - if (unlikely(res)) - memset(to + (n - res), 0, res); - return res; -} - -static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) -{ - kasan_check_read(from, n); - check_object_size(from, n, true); - - if (access_ok(VERIFY_WRITE, to, n)) { - n = __arch_copy_to_user(to, from, n); - } - return n; -} - -static inline unsigned long __must_check copy_in_user(void __user *to, const void __user *from, unsigned long n) -{ - if (access_ok(VERIFY_READ, from, n) && access_ok(VERIFY_WRITE, to, n)) - n = __copy_in_user(to, from, n); - return n; -} - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user +#define INLINE_COPY_TO_USER +#define INLINE_COPY_FROM_USER static inline unsigned long __must_check clear_user(void __user *to, unsigned long n) { diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index 64d9cbd61678..e25c11e727fe 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -18,6 +18,7 @@ #include <linux/acpi.h> #include <linux/bootmem.h> #include <linux/cpumask.h> +#include <linux/efi-bgrt.h> #include <linux/init.h> #include <linux/irq.h> #include <linux/irqdomain.h> @@ -233,6 +234,8 @@ done: early_init_dt_scan_chosen_stdout(); } else { parse_spcr(earlycon_init_is_deferred); + if (IS_ENABLED(CONFIG_ACPI_BGRT)) + acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); } } diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c index e9c4dc9e0ada..67368c7329c0 100644 --- a/arch/arm64/kernel/arm64ksyms.c +++ b/arch/arm64/kernel/arm64ksyms.c @@ -38,7 +38,7 @@ EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(__arch_copy_from_user); EXPORT_SYMBOL(__arch_copy_to_user); EXPORT_SYMBOL(__clear_user); -EXPORT_SYMBOL(__copy_in_user); +EXPORT_SYMBOL(raw_copy_in_user); /* physical memory */ EXPORT_SYMBOL(memstart_addr); diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index f6cc67e7626e..2ed2a7657711 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -53,6 +53,13 @@ static int cpu_enable_trap_ctr_access(void *__unused) .midr_range_min = min, \ .midr_range_max = max +#define MIDR_ALL_VERSIONS(model) \ + .def_scope = SCOPE_LOCAL_CPU, \ + .matches = is_affected_midr_range, \ + .midr_model = model, \ + .midr_range_min = 0, \ + .midr_range_max = (MIDR_VARIANT_MASK | MIDR_REVISION_MASK) + const struct arm64_cpu_capabilities arm64_errata[] = { #if defined(CONFIG_ARM64_ERRATUM_826319) || \ defined(CONFIG_ARM64_ERRATUM_827319) || \ @@ -151,6 +158,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { MIDR_CPU_VAR_REV(0, 0)), }, #endif +#ifdef CONFIG_ARM64_ERRATUM_858921 + { + /* Cortex-A73 all versions */ + .desc = "ARM erratum 858921", + .capability = ARM64_WORKAROUND_858921, + MIDR_ALL_VERSIONS(MIDR_CORTEX_A73), + }, +#endif { } }; diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index abda8e861865..6eb77ae99b79 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1090,20 +1090,29 @@ static void __init setup_feature_capabilities(void) * Check if the current CPU has a given feature capability. * Should be called from non-preemptible context. */ -bool this_cpu_has_cap(unsigned int cap) +static bool __this_cpu_has_cap(const struct arm64_cpu_capabilities *cap_array, + unsigned int cap) { const struct arm64_cpu_capabilities *caps; if (WARN_ON(preemptible())) return false; - for (caps = arm64_features; caps->desc; caps++) + for (caps = cap_array; caps->desc; caps++) if (caps->capability == cap && caps->matches) return caps->matches(caps, SCOPE_LOCAL_CPU); return false; } +extern const struct arm64_cpu_capabilities arm64_errata[]; + +bool this_cpu_has_cap(unsigned int cap) +{ + return (__this_cpu_has_cap(arm64_features, cap) || + __this_cpu_has_cap(arm64_errata, cap)); +} + void __init setup_cpu_features(void) { u32 cwg; diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index ef1caae02110..9b1036570586 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -944,7 +944,7 @@ static bool have_cpu_die(void) #ifdef CONFIG_HOTPLUG_CPU int any_cpu = raw_smp_processor_id(); - if (cpu_ops[any_cpu]->cpu_die) + if (cpu_ops[any_cpu] && cpu_ops[any_cpu]->cpu_die) return true; #endif return false; diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index e52be6aa44ee..1de444e6c669 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -505,6 +505,14 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs) regs->pc += 4; } +static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs) +{ + int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; + + pt_regs_write_reg(regs, rt, arch_counter_get_cntvct()); + regs->pc += 4; +} + struct sys64_hook { unsigned int esr_mask; unsigned int esr_val; @@ -523,6 +531,12 @@ static struct sys64_hook sys64_hooks[] = { .esr_val = ESR_ELx_SYS64_ISS_SYS_CTR_READ, .handler = ctr_read_handler, }, + { + /* Trap read access to CNTVCT_EL0 */ + .esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK, + .esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCT, + .handler = cntvct_read_handler, + }, {}, }; diff --git a/arch/arm64/kernel/vdso/.gitignore b/arch/arm64/kernel/vdso/.gitignore index b8cc94e9698b..f8b69d84238e 100644 --- a/arch/arm64/kernel/vdso/.gitignore +++ b/arch/arm64/kernel/vdso/.gitignore @@ -1,2 +1 @@ vdso.lds -vdso-offsets.h diff --git a/arch/arm64/lib/copy_in_user.S b/arch/arm64/lib/copy_in_user.S index 47184c3a97da..b24a830419ad 100644 --- a/arch/arm64/lib/copy_in_user.S +++ b/arch/arm64/lib/copy_in_user.S @@ -64,14 +64,14 @@ .endm end .req x5 -ENTRY(__copy_in_user) +ENTRY(raw_copy_in_user) uaccess_enable_not_uao x3, x4 add end, x0, x2 #include "copy_template.S" uaccess_disable_not_uao x3 mov x0, #0 ret -ENDPROC(__copy_in_user) +ENDPROC(raw_copy_in_user) .section .fixup,"ax" .align 2 diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 4bf899fb451b..1b35b8bddbfb 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -42,7 +42,20 @@ #include <asm/pgtable.h> #include <asm/tlbflush.h> -static const char *fault_name(unsigned int esr); +struct fault_info { + int (*fn)(unsigned long addr, unsigned int esr, + struct pt_regs *regs); + int sig; + int code; + const char *name; +}; + +static const struct fault_info fault_info[]; + +static inline const struct fault_info *esr_to_fault_info(unsigned int esr) +{ + return fault_info + (esr & 63); +} #ifdef CONFIG_KPROBES static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr) @@ -197,10 +210,12 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, struct pt_regs *regs) { struct siginfo si; + const struct fault_info *inf; if (unhandled_signal(tsk, sig) && show_unhandled_signals_ratelimited()) { + inf = esr_to_fault_info(esr); pr_info("%s[%d]: unhandled %s (%d) at 0x%08lx, esr 0x%03x\n", - tsk->comm, task_pid_nr(tsk), fault_name(esr), sig, + tsk->comm, task_pid_nr(tsk), inf->name, sig, addr, esr); show_pte(tsk->mm, addr); show_regs(regs); @@ -219,14 +234,16 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re { struct task_struct *tsk = current; struct mm_struct *mm = tsk->active_mm; + const struct fault_info *inf; /* * If we are in kernel mode at this point, we have no context to * handle this fault with. */ - if (user_mode(regs)) - __do_user_fault(tsk, addr, esr, SIGSEGV, SEGV_MAPERR, regs); - else + if (user_mode(regs)) { + inf = esr_to_fault_info(esr); + __do_user_fault(tsk, addr, esr, inf->sig, inf->code, regs); + } else __do_kernel_fault(mm, addr, esr, regs); } @@ -488,12 +505,7 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs) return 1; } -static const struct fault_info { - int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs); - int sig; - int code; - const char *name; -} fault_info[] = { +static const struct fault_info fault_info[] = { { do_bad, SIGBUS, 0, "ttbr address size fault" }, { do_bad, SIGBUS, 0, "level 1 address size fault" }, { do_bad, SIGBUS, 0, "level 2 address size fault" }, @@ -560,19 +572,13 @@ static const struct fault_info { { do_bad, SIGBUS, 0, "unknown 63" }, }; -static const char *fault_name(unsigned int esr) -{ - const struct fault_info *inf = fault_info + (esr & 63); - return inf->name; -} - /* * Dispatch a data abort to the relevant handler. */ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs) { - const struct fault_info *inf = fault_info + (esr & 63); + const struct fault_info *inf = esr_to_fault_info(esr); struct siginfo info; if (!inf->fn(addr, esr, regs)) diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index e25584d72396..7514a000e361 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -294,10 +294,6 @@ static __init int setup_hugepagesz(char *opt) hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); } else if (ps == PUD_SIZE) { hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); - } else if (ps == (PAGE_SIZE * CONT_PTES)) { - hugetlb_add_hstate(CONT_PTE_SHIFT); - } else if (ps == (PMD_SIZE * CONT_PMDS)) { - hugetlb_add_hstate((PMD_SHIFT + CONT_PMD_SHIFT) - PAGE_SHIFT); } else { hugetlb_bad_size(); pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10); @@ -306,13 +302,3 @@ static __init int setup_hugepagesz(char *opt) return 1; } __setup("hugepagesz=", setup_hugepagesz); - -#ifdef CONFIG_ARM64_64K_PAGES -static __init int add_default_hugepagesz(void) -{ - if (size_to_hstate(CONT_PTES * PAGE_SIZE) == NULL) - hugetlb_add_hstate(CONT_PTE_SHIFT); - return 0; -} -arch_initcall(add_default_hugepagesz); -#endif diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig deleted file mode 100644 index 7e75d45e20cd..000000000000 --- a/arch/avr32/Kconfig +++ /dev/null @@ -1,288 +0,0 @@ -config AVR32 - def_bool y - # With EXPERT=n, we get lots of stuff automatically selected - # that we usually don't need on AVR32. - select EXPERT - select HAVE_CLK - select HAVE_EXIT_THREAD - select HAVE_OPROFILE - select HAVE_KPROBES - select VIRT_TO_BUS - select GENERIC_IRQ_PROBE - select GENERIC_ATOMIC64 - select HARDIRQS_SW_RESEND - select GENERIC_IRQ_SHOW - select ARCH_HAVE_CUSTOM_GPIO_H - select ARCH_WANT_IPC_PARSE_VERSION - select ARCH_HAVE_NMI_SAFE_CMPXCHG - select GENERIC_CLOCKEVENTS - select HAVE_MOD_ARCH_SPECIFIC - select MODULES_USE_ELF_RELA - select HAVE_NMI - help - AVR32 is a high-performance 32-bit RISC microprocessor core, - designed for cost-sensitive embedded applications, with particular - emphasis on low power consumption and high code density. - - There is an AVR32 Linux project with a web page at - http://avr32linux.org/. - -config STACKTRACE_SUPPORT - def_bool y - -config LOCKDEP_SUPPORT - def_bool y - -config TRACE_IRQFLAGS_SUPPORT - def_bool y - -config RWSEM_GENERIC_SPINLOCK - def_bool y - -config RWSEM_XCHGADD_ALGORITHM - def_bool n - -config ARCH_HAS_ILOG2_U32 - def_bool n - -config ARCH_HAS_ILOG2_U64 - def_bool n - -config GENERIC_HWEIGHT - def_bool y - -config GENERIC_CALIBRATE_DELAY - def_bool y - -config GENERIC_BUG - def_bool y - depends on BUG - -source "init/Kconfig" - -source "kernel/Kconfig.freezer" - -menu "System Type and features" - -config SUBARCH_AVR32B - bool -config MMU - bool -config PERFORMANCE_COUNTERS - bool - -config PLATFORM_AT32AP - bool - select SUBARCH_AVR32B - select MMU - select PERFORMANCE_COUNTERS - select GPIOLIB - select GENERIC_ALLOCATOR - select HAVE_FB_ATMEL - -# -# CPU types -# - -# AP7000 derivatives -config CPU_AT32AP700X - bool - select PLATFORM_AT32AP -config CPU_AT32AP7000 - bool - select CPU_AT32AP700X -config CPU_AT32AP7001 - bool - select CPU_AT32AP700X -config CPU_AT32AP7002 - bool - select CPU_AT32AP700X - -# AP700X boards -config BOARD_ATNGW100_COMMON - bool - select CPU_AT32AP7000 - -choice - prompt "AVR32 board type" - default BOARD_ATSTK1000 - -config BOARD_ATSTK1000 - bool "ATSTK1000 evaluation board" - -config BOARD_ATNGW100_MKI - bool "ATNGW100 Network Gateway" - select BOARD_ATNGW100_COMMON - -config BOARD_ATNGW100_MKII - bool "ATNGW100 mkII Network Gateway" - select BOARD_ATNGW100_COMMON - -config BOARD_HAMMERHEAD - bool "Hammerhead board" - select CPU_AT32AP7000 - select USB_ARCH_HAS_HCD - help - The Hammerhead platform is built around an AVR32 32-bit microcontroller from Atmel. - It offers versatile peripherals, such as ethernet, usb device, usb host etc. - - The board also incorporates a power supply and is a Power over Ethernet (PoE) Powered - Device (PD). - - Additionally, a Cyclone III FPGA from Altera is integrated on the board. The FPGA is - mapped into the 32-bit AVR memory bus. The FPGA offers two DDR2 SDRAM interfaces, which - will cover even the most exceptional need of memory bandwidth. Together with the onboard - video decoder the board is ready for video processing. - - For more information see: http://www.miromico.ch/index.php/hammerhead.html - -config BOARD_FAVR_32 - bool "Favr-32 LCD-board" - select CPU_AT32AP7000 - -config BOARD_MERISC - bool "Merisc board" - select CPU_AT32AP7000 - help - Merisc is the family name for a range of AVR32-based boards. - - The boards are designed to be used in a man-machine - interfacing environment, utilizing a touch-based graphical - user interface. They host a vast range of I/O peripherals as - well as a large SDRAM & Flash memory bank. - - For more information see: http://www.martinsson.se/merisc - -config BOARD_MIMC200 - bool "MIMC200 CPU board" - select CPU_AT32AP7000 -endchoice - -source "arch/avr32/boards/atstk1000/Kconfig" -source "arch/avr32/boards/atngw100/Kconfig" -source "arch/avr32/boards/hammerhead/Kconfig" -source "arch/avr32/boards/favr-32/Kconfig" -source "arch/avr32/boards/merisc/Kconfig" - -choice - prompt "Boot loader type" - default LOADER_U_BOOT - -config LOADER_U_BOOT - bool "U-Boot (or similar) bootloader" -endchoice - -source "arch/avr32/mach-at32ap/Kconfig" - -config LOAD_ADDRESS - hex - default 0x10000000 if LOADER_U_BOOT=y && CPU_AT32AP700X=y - -config ENTRY_ADDRESS - hex - default 0x90000000 if LOADER_U_BOOT=y && CPU_AT32AP700X=y - -config PHYS_OFFSET - hex - default 0x10000000 if CPU_AT32AP700X=y - -source "kernel/Kconfig.preempt" - -config QUICKLIST - def_bool y - -config ARCH_HAVE_MEMORY_PRESENT - def_bool n - -config NEED_NODE_MEMMAP_SIZE - def_bool n - -config ARCH_FLATMEM_ENABLE - def_bool y - -config ARCH_DISCONTIGMEM_ENABLE - def_bool n - -config ARCH_SPARSEMEM_ENABLE - def_bool n - -config NODES_SHIFT - int - default "2" - depends on NEED_MULTIPLE_NODES - -source "mm/Kconfig" - -config OWNERSHIP_TRACE - bool "Ownership trace support" - default y - help - Say Y to generate an Ownership Trace message on every context switch, - enabling Nexus-compliant debuggers to keep track of the PID of the - currently executing task. - -config NMI_DEBUGGING - bool "NMI Debugging" - default n - help - Say Y here and pass the nmi_debug command-line parameter to - the kernel to turn on NMI debugging. Depending on the value - of the nmi_debug option, various pieces of information will - be dumped to the console when a Non-Maskable Interrupt - happens. - -# FPU emulation goes here - -source "kernel/Kconfig.hz" - -config CMDLINE - string "Default kernel command line" - default "" - help - If you don't have a boot loader capable of passing a command line string - to the kernel, you may specify one here. As a minimum, you should specify - the memory size and the root device (e.g., mem=8M, root=/dev/nfs). - -endmenu - -menu "Power management options" - -source "kernel/power/Kconfig" - -config ARCH_SUSPEND_POSSIBLE - def_bool y - -menu "CPU Frequency scaling" -source "drivers/cpufreq/Kconfig" -endmenu - -endmenu - -menu "Bus options" - -config PCI - bool - -source "drivers/pci/Kconfig" - -source "drivers/pcmcia/Kconfig" - -endmenu - -menu "Executable file formats" -source "fs/Kconfig.binfmt" -endmenu - -source "net/Kconfig" - -source "drivers/Kconfig" - -source "fs/Kconfig" - -source "arch/avr32/Kconfig.debug" - -source "security/Kconfig" - -source "crypto/Kconfig" - -source "lib/Kconfig" diff --git a/arch/avr32/Kconfig.debug b/arch/avr32/Kconfig.debug deleted file mode 100644 index 2283933a9a93..000000000000 --- a/arch/avr32/Kconfig.debug +++ /dev/null @@ -1,9 +0,0 @@ -menu "Kernel hacking" - -config TRACE_IRQFLAGS_SUPPORT - bool - default y - -source "lib/Kconfig.debug" - -endmenu diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile deleted file mode 100644 index dba48a5d5bb9..000000000000 --- a/arch/avr32/Makefile +++ /dev/null @@ -1,84 +0,0 @@ -# -# 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) 2004-2006 Atmel Corporation. - -# Default target when executing plain make -.PHONY: all -all: uImage vmlinux.elf - -KBUILD_DEFCONFIG := atstk1002_defconfig - -KBUILD_CFLAGS += -pipe -fno-builtin -mno-pic -D__linux__ -KBUILD_AFLAGS += -mrelax -mno-pic -KBUILD_CFLAGS_MODULE += -mno-relax -LDFLAGS_vmlinux += --relax - -cpuflags-$(CONFIG_PLATFORM_AT32AP) += -march=ap - -KBUILD_CFLAGS += $(cpuflags-y) -KBUILD_AFLAGS += $(cpuflags-y) - -CHECKFLAGS += -D__avr32__ -D__BIG_ENDIAN - -machine-$(CONFIG_PLATFORM_AT32AP) := at32ap -machdirs := $(patsubst %,arch/avr32/mach-%/, $(machine-y)) - -KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs)) - -head-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/head.o -head-y += arch/avr32/kernel/head.o -core-y += $(machdirs) -core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/ -core-$(CONFIG_BOARD_ATNGW100_COMMON) += arch/avr32/boards/atngw100/ -core-$(CONFIG_BOARD_HAMMERHEAD) += arch/avr32/boards/hammerhead/ -core-$(CONFIG_BOARD_FAVR_32) += arch/avr32/boards/favr-32/ -core-$(CONFIG_BOARD_MERISC) += arch/avr32/boards/merisc/ -core-$(CONFIG_BOARD_MIMC200) += arch/avr32/boards/mimc200/ -core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/ -core-y += arch/avr32/kernel/ -core-y += arch/avr32/mm/ -drivers-$(CONFIG_OPROFILE) += arch/avr32/oprofile/ -libs-y += arch/avr32/lib/ - -BOOT_TARGETS := vmlinux.elf vmlinux.bin uImage uImage.srec - -.PHONY: $(BOOT_TARGETS) install - -boot := arch/$(ARCH)/boot/images - - KBUILD_IMAGE := $(boot)/uImage -vmlinux.elf: KBUILD_IMAGE := $(boot)/vmlinux.elf -vmlinux.cso: KBUILD_IMAGE := $(boot)/vmlinux.cso -uImage.srec: KBUILD_IMAGE := $(boot)/uImage.srec -uImage: KBUILD_IMAGE := $(boot)/uImage - -quiet_cmd_listing = LST $@ - cmd_listing = avr32-linux-objdump $(OBJDUMPFLAGS) -lS $< > $@ -quiet_cmd_disasm = DIS $@ - cmd_disasm = avr32-linux-objdump $(OBJDUMPFLAGS) -d $< > $@ - -vmlinux.elf vmlinux.bin uImage.srec uImage vmlinux.cso: vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ - -install: vmlinux - $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ - -vmlinux.s: vmlinux - $(call if_changed,disasm) - -vmlinux.lst: vmlinux - $(call if_changed,listing) - -CLEAN_FILES += vmlinux.s vmlinux.lst - -archclean: - $(Q)$(MAKE) $(clean)=$(boot) - -define archhelp - @echo '* vmlinux.elf - ELF image with load address 0' - @echo ' vmlinux.cso - PathFinder CSO image' - @echo '* uImage - Create a bootable image for U-Boot' -endef diff --git a/arch/avr32/boards/atngw100/Kconfig b/arch/avr32/boards/atngw100/Kconfig deleted file mode 100644 index 4e55617ade2d..000000000000 --- a/arch/avr32/boards/atngw100/Kconfig +++ /dev/null @@ -1,65 +0,0 @@ -# NGW100 customization - -if BOARD_ATNGW100_COMMON - -config BOARD_ATNGW100_MKII_LCD - bool "Enable ATNGW100 mkII LCD interface" - depends on BOARD_ATNGW100_MKII - help - This enables the LCD controller (LCDC) in the AT32AP7000. Since the - LCDC is multiplexed with MACB1 (LAN) Ethernet port, only one can be - enabled at a time. - - This choice enables the LCDC and disables the MACB1 interface marked - LAN on the PCB. - -choice - prompt "Select an NGW100 add-on board to support" - default BOARD_ATNGW100_ADDON_NONE - -config BOARD_ATNGW100_ADDON_NONE - bool "None" - -config BOARD_ATNGW100_EVKLCD10X - bool "EVKLCD10X addon board" - depends on BOARD_ATNGW100_MKI || BOARD_ATNGW100_MKII_LCD - help - This enables support for the EVKLCD100 (QVGA) or EVKLCD101 (VGA) - addon board for the NGW100 and NGW100 mkII. By enabling this the LCD - controller and AC97 controller is added as platform devices. - -config BOARD_ATNGW100_MRMT - bool "Mediama RMT1/2 add-on board" - help - This enables support for the Mediama RMT1 or RMT2 board. - RMT provides LCD support, AC97 codec and other - optional peripherals to the Atmel NGW100. - - This choice disables the detect pin and the write-protect pin for the - MCI platform device, since it conflicts with the LCD platform device. - The MCI pins can be reenabled by editing the "add device function" but - this may break the setup for other displays that use these pins. - -endchoice - -choice - prompt "LCD panel resolution on EVKLCD10X" - depends on BOARD_ATNGW100_EVKLCD10X - default BOARD_ATNGW100_EVKLCD10X_VGA - -config BOARD_ATNGW100_EVKLCD10X_QVGA - bool "QVGA (320x240)" - -config BOARD_ATNGW100_EVKLCD10X_VGA - bool "VGA (640x480)" - -config BOARD_ATNGW100_EVKLCD10X_POW_QVGA - bool "Powertip QVGA (320x240)" - -endchoice - -if BOARD_ATNGW100_MRMT -source "arch/avr32/boards/atngw100/Kconfig_mrmt" -endif - -endif # BOARD_ATNGW100_COMMON diff --git a/arch/avr32/boards/atngw100/Kconfig_mrmt b/arch/avr32/boards/atngw100/Kconfig_mrmt deleted file mode 100644 index 9a199a207f3c..000000000000 --- a/arch/avr32/boards/atngw100/Kconfig_mrmt +++ /dev/null @@ -1,80 +0,0 @@ -# RMT for NGW100 customization - -choice - prompt "RMT Version" - help - Select the RMTx board version. - -config BOARD_MRMT_REV1 - bool "RMT1" -config BOARD_MRMT_REV2 - bool "RMT2" - -endchoice - -config BOARD_MRMT_AC97 - bool "Enable AC97 CODEC" - help - Enable the UCB1400 AC97 CODEC driver. - -choice - prompt "Touchscreen Driver" - default BOARD_MRMT_ADS7846_TS - -config BOARD_MRMT_UCB1400_TS - bool "Use UCB1400 Touchscreen" - -config BOARD_MRMT_ADS7846_TS - bool "Use ADS7846 Touchscreen" - -endchoice - -choice - prompt "RMTx LCD Selection" - default BOARD_MRMT_LCD_DISABLE - -config BOARD_MRMT_LCD_DISABLE - bool "LCD Disabled" - -config BOARD_MRMT_LCD_LQ043T3DX0X - bool "Sharp LQ043T3DX0x or compatible" - help - If using RMT2, be sure to load the resistor pack selectors accordingly - -if BOARD_MRMT_REV2 -config BOARD_MRMT_LCD_KWH043GM08 - bool "Formike KWH043GM08 or compatible" - help - Be sure to load the RMT2 resistor pack selectors accordingly -endif - -endchoice - -if !BOARD_MRMT_LCD_DISABLE -config BOARD_MRMT_BL_PWM - bool "Use PWM control for LCD Backlight" - help - Use PWM driver for controlling LCD Backlight. - Otherwise, LCD Backlight is always on. -endif - -config BOARD_MRMT_RTC_I2C - bool "Use External RTC on I2C Bus" - help - RMT1 has an optional RTC device on the I2C bus. - It is a SII S35390A. Be sure to select the - matching RTC driver. - -choice - prompt "Wireless Module on ttyS2" - default BOARD_MRMT_WIRELESS_ZB - -config BOARD_MRMT_WIRELESS_ZB - bool "Use ZigBee/802.15.4 Module" - -config BOARD_MRMT_WIRELESS_BT - bool "Use Bluetooth (HCI) Module" - -config BOARD_MRMT_WIRELESS_NONE - bool "Not Installed" -endchoice diff --git a/arch/avr32/boards/atngw100/Makefile b/arch/avr32/boards/atngw100/Makefile deleted file mode 100644 index f4ebe42a8254..000000000000 --- a/arch/avr32/boards/atngw100/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-y += setup.o flash.o -obj-$(CONFIG_BOARD_ATNGW100_EVKLCD10X) += evklcd10x.o -obj-$(CONFIG_BOARD_ATNGW100_MRMT) += mrmt.o diff --git a/arch/avr32/boards/atngw100/evklcd10x.c b/arch/avr32/boards/atngw100/evklcd10x.c deleted file mode 100644 index 64919b0da7aa..000000000000 --- a/arch/avr32/boards/atngw100/evklcd10x.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Board-specific setup code for the ATEVKLCD10X addon board to the ATNGW100 - * Network Gateway - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#include <linux/init.h> -#include <linux/linkage.h> -#include <linux/gpio.h> -#include <linux/fb.h> -#include <linux/platform_device.h> - -#include <video/atmel_lcdc.h> - -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/portmux.h> -#include <mach/board.h> - -#include <sound/atmel-ac97c.h> - -static struct ac97c_platform_data __initdata ac97c0_data = { - .reset_pin = GPIO_PIN_PB(19), -}; - -#ifdef CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA -static struct fb_videomode __initdata tcg057vglad_modes[] = { - { - .name = "640x480 @ 50", - .refresh = 50, - .xres = 640, .yres = 480, - .pixclock = KHZ2PICOS(25180), - - .left_margin = 64, .right_margin = 96, - .upper_margin = 34, .lower_margin = 11, - .hsync_len = 64, .vsync_len = 15, - - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs __initdata atevklcd10x_default_monspecs = { - .manufacturer = "KYO", - .monitor = "TCG057VGLAD", - .modedb = tcg057vglad_modes, - .modedb_len = ARRAY_SIZE(tcg057vglad_modes), - .hfmin = 19948, - .hfmax = 31478, - .vfmin = 50, - .vfmax = 67, - .dclkmax = 28330000, -}; - -static struct atmel_lcdfb_pdata __initdata atevklcd10x_lcdc_data = { - .default_bpp = 16, - .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, - .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE - | ATMEL_LCDC_MEMOR_BIG), - .default_monspecs = &atevklcd10x_default_monspecs, - .guard_time = 2, -}; -#elif CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA -static struct fb_videomode __initdata tcg057qvlad_modes[] = { - { - .name = "320x240 @ 50", - .refresh = 50, - .xres = 320, .yres = 240, - .pixclock = KHZ2PICOS(6300), - - .left_margin = 34, .right_margin = 46, - .upper_margin = 7, .lower_margin = 15, - .hsync_len = 64, .vsync_len = 12, - - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs __initdata atevklcd10x_default_monspecs = { - .manufacturer = "KYO", - .monitor = "TCG057QVLAD", - .modedb = tcg057qvlad_modes, - .modedb_len = ARRAY_SIZE(tcg057qvlad_modes), - .hfmin = 19948, - .hfmax = 31478, - .vfmin = 50, - .vfmax = 67, - .dclkmax = 7000000, -}; - -static struct atmel_lcdfb_pdata __initdata atevklcd10x_lcdc_data = { - .default_bpp = 16, - .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, - .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE - | ATMEL_LCDC_MEMOR_BIG), - .default_monspecs = &atevklcd10x_default_monspecs, - .guard_time = 2, -}; -#elif CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA -static struct fb_videomode __initdata ph320240t_modes[] = { - { - .name = "320x240 @ 60", - .refresh = 60, - .xres = 320, .yres = 240, - .pixclock = KHZ2PICOS(6300), - - .left_margin = 38, .right_margin = 20, - .upper_margin = 15, .lower_margin = 5, - .hsync_len = 30, .vsync_len = 3, - - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs __initdata atevklcd10x_default_monspecs = { - .manufacturer = "POW", - .monitor = "PH320240T", - .modedb = ph320240t_modes, - .modedb_len = ARRAY_SIZE(ph320240t_modes), - .hfmin = 14400, - .hfmax = 21600, - .vfmin = 50, - .vfmax = 90, - .dclkmax = 6400000, -}; - -static struct atmel_lcdfb_pdata __initdata atevklcd10x_lcdc_data = { - .default_bpp = 16, - .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, - .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE - | ATMEL_LCDC_MEMOR_BIG), - .default_monspecs = &atevklcd10x_default_monspecs, - .guard_time = 2, -}; -#endif - -static void atevklcd10x_lcdc_power_control(struct atmel_lcdfb_pdata *pdata, int on) -{ - gpio_set_value(GPIO_PIN_PB(15), on); -} - -static int __init atevklcd10x_init(void) -{ - /* PB15 is connected to the enable line on the boost regulator - * controlling the backlight for the LCD panel. - */ - at32_select_gpio(GPIO_PIN_PB(15), AT32_GPIOF_OUTPUT); - gpio_request(GPIO_PIN_PB(15), "backlight"); - gpio_direction_output(GPIO_PIN_PB(15), 0); - - atevklcd10x_lcdc_data.atmel_lcdfb_power_control = - atevklcd10x_lcdc_power_control; - - at32_add_device_lcdc(0, &atevklcd10x_lcdc_data, - fbmem_start, fbmem_size, -#ifdef CONFIG_BOARD_ATNGW100_MKII - ATMEL_LCDC_PRI_18BIT | ATMEL_LCDC_PC_DVAL -#else - ATMEL_LCDC_ALT_18BIT | ATMEL_LCDC_PE_DVAL -#endif - ); - - at32_add_device_ac97c(0, &ac97c0_data, AC97C_BOTH); - - return 0; -} -postcore_initcall(atevklcd10x_init); diff --git a/arch/avr32/boards/atngw100/flash.c b/arch/avr32/boards/atngw100/flash.c deleted file mode 100644 index 55ccc9ce4892..000000000000 --- a/arch/avr32/boards/atngw100/flash.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * ATNGW100 board-specific flash initialization - * - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> - -#include <mach/smc.h> - -static struct smc_timing flash_timing __initdata = { - .ncs_read_setup = 0, - .nrd_setup = 40, - .ncs_write_setup = 0, - .nwe_setup = 10, - - .ncs_read_pulse = 80, - .nrd_pulse = 40, - .ncs_write_pulse = 65, - .nwe_pulse = 55, - - .read_cycle = 120, - .write_cycle = 120, -}; - -static struct smc_config flash_config __initdata = { - .bus_width = 2, - .nrd_controlled = 1, - .nwe_controlled = 1, - .byte_write = 1, -}; - -static struct mtd_partition flash_parts[] = { - { - .name = "u-boot", - .offset = 0x00000000, - .size = 0x00020000, /* 128 KiB */ - .mask_flags = MTD_WRITEABLE, - }, - { - .name = "root", - .offset = 0x00020000, - .size = 0x007d0000, - }, - { - .name = "env", - .offset = 0x007f0000, - .size = 0x00010000, - .mask_flags = MTD_WRITEABLE, - }, -}; - -static struct physmap_flash_data flash_data = { - .width = 2, - .nr_parts = ARRAY_SIZE(flash_parts), - .parts = flash_parts, -}; - -static struct resource flash_resource = { - .start = 0x00000000, - .end = 0x007fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device flash_device = { - .name = "physmap-flash", - .id = 0, - .resource = &flash_resource, - .num_resources = 1, - .dev = { - .platform_data = &flash_data, - }, -}; - -/* This needs to be called after the SMC has been initialized */ -static int __init atngw100_flash_init(void) -{ - int ret; - - smc_set_timing(&flash_config, &flash_timing); - ret = smc_set_configuration(0, &flash_config); - if (ret < 0) { - printk(KERN_ERR "atngw100: failed to set NOR flash timing\n"); - return ret; - } - - platform_device_register(&flash_device); - - return 0; -} -device_initcall(atngw100_flash_init); diff --git a/arch/avr32/boards/atngw100/mrmt.c b/arch/avr32/boards/atngw100/mrmt.c deleted file mode 100644 index 99b0a7984950..000000000000 --- a/arch/avr32/boards/atngw100/mrmt.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Board-specific setup code for Remote Media Terminal 1 (RMT1) - * add-on board for the ATNGW100 Network Gateway - * - * Copyright (C) 2008 Mediama Technologies - * Based on ATNGW100 Network Gateway (Copyright (C) Atmel) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/irq.h> -#include <linux/linkage.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/fb.h> -#include <linux/leds.h> -#include <linux/pwm.h> -#include <linux/leds_pwm.h> -#include <linux/input.h> -#include <linux/gpio_keys.h> -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> - -#include <video/atmel_lcdc.h> -#include <sound/atmel-ac97c.h> - -#include <asm/delay.h> -#include <asm/io.h> -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/board.h> -#include <mach/init.h> -#include <mach/portmux.h> - -/* Define board-specifoic GPIO assignments */ -#define PIN_LCD_BL GPIO_PIN_PA(28) -#define PWM_CH_BL 0 /* Must match with GPIO pin definition */ -#define PIN_LCD_DISP GPIO_PIN_PA(31) -#define PIN_AC97_RST_N GPIO_PIN_PA(30) -#define PB_EXTINT_BASE 25 -#define TS_IRQ 0 -#define PIN_TS_EXTINT GPIO_PIN_PB(PB_EXTINT_BASE+TS_IRQ) -#define PIN_PB_LEFT GPIO_PIN_PB(11) -#define PIN_PB_RIGHT GPIO_PIN_PB(12) -#define PIN_PWR_SW_N GPIO_PIN_PB(14) -#define PIN_PWR_ON GPIO_PIN_PB(13) -#define PIN_ZB_RST_N GPIO_PIN_PA(21) -#define PIN_BT_RST GPIO_PIN_PA(22) -#define PIN_LED_SYS GPIO_PIN_PA(16) -#define PIN_LED_A GPIO_PIN_PA(19) -#define PIN_LED_B GPIO_PIN_PE(19) - -#ifdef CONFIG_BOARD_MRMT_LCD_LQ043T3DX0X -/* Sharp LQ043T3DX0x (or compatible) panel */ -static struct fb_videomode __initdata lcd_fb_modes[] = { - { - .name = "480x272 @ 59.94Hz", - .refresh = 59.94, - .xres = 480, .yres = 272, - .pixclock = KHZ2PICOS(9000), - - .left_margin = 2, .right_margin = 2, - .upper_margin = 3, .lower_margin = 9, - .hsync_len = 41, .vsync_len = 1, - - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs __initdata lcd_fb_default_monspecs = { - .manufacturer = "SHA", - .monitor = "LQ043T3DX02", - .modedb = lcd_fb_modes, - .modedb_len = ARRAY_SIZE(lcd_fb_modes), - .hfmin = 14915, - .hfmax = 17638, - .vfmin = 53, - .vfmax = 61, - .dclkmax = 9260000, -}; - -static struct atmel_lcdfb_pdata __initdata rmt_lcdc_data = { - .default_bpp = 24, - .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, - .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE - | ATMEL_LCDC_INVCLK_NORMAL - | ATMEL_LCDC_MEMOR_BIG), - .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, - .default_monspecs = &lcd_fb_default_monspecs, - .guard_time = 2, -}; -#endif - -#ifdef CONFIG_BOARD_MRMT_LCD_KWH043GM08 -/* Sharp KWH043GM08-Fxx (or compatible) panel */ -static struct fb_videomode __initdata lcd_fb_modes[] = { - { - .name = "480x272 @ 59.94Hz", - .refresh = 59.94, - .xres = 480, .yres = 272, - .pixclock = KHZ2PICOS(9000), - - .left_margin = 2, .right_margin = 2, - .upper_margin = 3, .lower_margin = 9, - .hsync_len = 41, .vsync_len = 1, - - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs __initdata lcd_fb_default_monspecs = { - .manufacturer = "FOR", - .monitor = "KWH043GM08", - .modedb = lcd_fb_modes, - .modedb_len = ARRAY_SIZE(lcd_fb_modes), - .hfmin = 14915, - .hfmax = 17638, - .vfmin = 53, - .vfmax = 61, - .dclkmax = 9260000, -}; - -static struct atmel_lcdfb_pdata __initdata rmt_lcdc_data = { - .default_bpp = 24, - .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, - .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE - | ATMEL_LCDC_INVCLK_INVERTED - | ATMEL_LCDC_MEMOR_BIG), - .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB, - .default_monspecs = &lcd_fb_default_monspecs, - .guard_time = 2, -}; -#endif - -#ifdef CONFIG_BOARD_MRMT_AC97 -static struct ac97c_platform_data __initdata ac97c0_data = { - .reset_pin = PIN_AC97_RST_N, -}; -#endif - -#ifdef CONFIG_BOARD_MRMT_UCB1400_TS -/* NOTE: IRQ assignment relies on kernel module parameter */ -static struct platform_device rmt_ts_device = { - .name = "ucb1400_ts", - .id = -1, -}; -#endif - -#ifdef CONFIG_BOARD_MRMT_BL_PWM -/* PWM LEDs: LCD Backlight, etc */ -static struct pwm_lookup pwm_lookup[] = { - PWM_LOOKUP("at91sam9rl-pwm", PWM_CH_BL, "leds_pwm", "ds1", - 5000, PWM_POLARITY_INVERSED), -}; - -static struct led_pwm pwm_leds[] = { - { - .name = "backlight", - .max_brightness = 255, - }, -}; - -static struct led_pwm_platform_data pwm_data = { - .num_leds = ARRAY_SIZE(pwm_leds), - .leds = pwm_leds, -}; - -static struct platform_device leds_pwm = { - .name = "leds_pwm", - .id = -1, - .dev = { - .platform_data = &pwm_data, - }, -}; -#endif - -#ifdef CONFIG_BOARD_MRMT_ADS7846_TS -static int ads7846_pendown_state(void) -{ - return !gpio_get_value( PIN_TS_EXTINT ); /* PENIRQ.*/ -} - -static struct ads7846_platform_data ads_info = { - .model = 7846, - .keep_vref_on = 0, /* Use external VREF pin */ - .vref_delay_usecs = 0, - .vref_mv = 3300, /* VREF = 3.3V */ - .settle_delay_usecs = 800, - .penirq_recheck_delay_usecs = 800, - .x_plate_ohms = 750, - .y_plate_ohms = 300, - .pressure_max = 4096, - .debounce_max = 1, - .debounce_rep = 0, - .debounce_tol = (~0), - .get_pendown_state = ads7846_pendown_state, - .filter = NULL, - .filter_init = NULL, -}; - -static struct spi_board_info spi01_board_info[] __initdata = { - { - .modalias = "ads7846", - .max_speed_hz = 31250*26, - .bus_num = 0, - .chip_select = 1, - .platform_data = &ads_info, - .irq = AT32_EXTINT(TS_IRQ), - }, -}; -#endif - -/* GPIO Keys: left, right, power, etc */ -static const struct gpio_keys_button rmt_gpio_keys_buttons[] = { - [0] = { - .type = EV_KEY, - .code = KEY_POWER, - .gpio = PIN_PWR_SW_N, - .active_low = 1, - .desc = "power button", - }, - [1] = { - .type = EV_KEY, - .code = KEY_LEFT, - .gpio = PIN_PB_LEFT, - .active_low = 1, - .desc = "left button", - }, - [2] = { - .type = EV_KEY, - .code = KEY_RIGHT, - .gpio = PIN_PB_RIGHT, - .active_low = 1, - .desc = "right button", - }, -}; - -static const struct gpio_keys_platform_data rmt_gpio_keys_data = { - .nbuttons = ARRAY_SIZE(rmt_gpio_keys_buttons), - .buttons = (void *) rmt_gpio_keys_buttons, -}; - -static struct platform_device rmt_gpio_keys = { - .name = "gpio-keys", - .id = -1, - .dev = { - .platform_data = (void *) &rmt_gpio_keys_data, - } -}; - -#ifdef CONFIG_BOARD_MRMT_RTC_I2C -static struct i2c_board_info __initdata mrmt1_i2c_rtc = { - I2C_BOARD_INFO("s35390a", 0x30), - .irq = 0, -}; -#endif - -static void mrmt_power_off(void) -{ - /* PWR_ON=0 will force power off */ - gpio_set_value( PIN_PWR_ON, 0 ); -} - -static int __init mrmt1_init(void) -{ - gpio_set_value( PIN_PWR_ON, 1 ); /* Ensure PWR_ON is enabled */ - - pm_power_off = mrmt_power_off; - - /* Setup USARTS (other than console) */ - at32_map_usart(2, 1, 0); /* USART 2: /dev/ttyS1, RMT1:DB9M */ - at32_map_usart(3, 2, ATMEL_USART_RTS | ATMEL_USART_CTS); - /* USART 3: /dev/ttyS2, RMT1:Wireless, w/ RTS/CTS */ - at32_add_device_usart(1); - at32_add_device_usart(2); - - /* Select GPIO Key pins */ - at32_select_gpio( PIN_PWR_SW_N, AT32_GPIOF_DEGLITCH); - at32_select_gpio( PIN_PB_LEFT, AT32_GPIOF_DEGLITCH); - at32_select_gpio( PIN_PB_RIGHT, AT32_GPIOF_DEGLITCH); - platform_device_register(&rmt_gpio_keys); - -#ifdef CONFIG_BOARD_MRMT_RTC_I2C - i2c_register_board_info(0, &mrmt1_i2c_rtc, 1); -#endif - -#ifndef CONFIG_BOARD_MRMT_LCD_DISABLE - /* User "alternate" LCDC inferface on Port E & D */ - /* NB: exclude LCDC_CC pin, as NGW100 reserves it for other use */ - at32_add_device_lcdc(0, &rmt_lcdc_data, - fbmem_start, fbmem_size, - (ATMEL_LCDC_ALT_24BIT | ATMEL_LCDC_PE_DVAL ) ); -#endif - -#ifdef CONFIG_BOARD_MRMT_AC97 - at32_add_device_ac97c(0, &ac97c0_data, AC97C_BOTH); -#endif - -#ifdef CONFIG_BOARD_MRMT_ADS7846_TS - /* Select the Touchscreen interrupt pin mode */ - at32_select_periph( GPIO_PIOB_BASE, 1 << (PB_EXTINT_BASE+TS_IRQ), - GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); - irq_set_irq_type(AT32_EXTINT(TS_IRQ), IRQ_TYPE_EDGE_FALLING); - at32_spi_setup_slaves(0,spi01_board_info,ARRAY_SIZE(spi01_board_info)); - spi_register_board_info(spi01_board_info,ARRAY_SIZE(spi01_board_info)); -#endif - -#ifdef CONFIG_BOARD_MRMT_UCB1400_TS - /* Select the Touchscreen interrupt pin mode */ - at32_select_periph( GPIO_PIOB_BASE, 1 << (PB_EXTINT_BASE+TS_IRQ), - GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH); - platform_device_register(&rmt_ts_device); -#endif - - at32_select_gpio( PIN_LCD_DISP, AT32_GPIOF_OUTPUT ); - gpio_request( PIN_LCD_DISP, "LCD_DISP" ); - gpio_direction_output( PIN_LCD_DISP, 0 ); /* LCD DISP */ -#ifdef CONFIG_BOARD_MRMT_LCD_DISABLE - /* Keep Backlight and DISP off */ - at32_select_gpio( PIN_LCD_BL, AT32_GPIOF_OUTPUT ); - gpio_request( PIN_LCD_BL, "LCD_BL" ); - gpio_direction_output( PIN_LCD_BL, 0 ); /* Backlight */ -#else - gpio_set_value( PIN_LCD_DISP, 1 ); /* DISP asserted first */ -#ifdef CONFIG_BOARD_MRMT_BL_PWM - /* Use PWM for Backlight controls */ - at32_add_device_pwm(1 << PWM_CH_BL); - pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup)); - platform_device_register(&leds_pwm); -#else - /* Backlight always on */ - udelay( 1 ); - at32_select_gpio( PIN_LCD_BL, AT32_GPIOF_OUTPUT ); - gpio_request( PIN_LCD_BL, "LCD_BL" ); - gpio_direction_output( PIN_LCD_BL, 1 ); -#endif -#endif - - /* Make sure BT and Zigbee modules in reset */ - at32_select_gpio( PIN_BT_RST, AT32_GPIOF_OUTPUT ); - gpio_request( PIN_BT_RST, "BT_RST" ); - gpio_direction_output( PIN_BT_RST, 1 ); - /* BT Module in Reset */ - - at32_select_gpio( PIN_ZB_RST_N, AT32_GPIOF_OUTPUT ); - gpio_request( PIN_ZB_RST_N, "ZB_RST_N" ); - gpio_direction_output( PIN_ZB_RST_N, 0 ); - /* XBee Module in Reset */ - -#ifdef CONFIG_BOARD_MRMT_WIRELESS_ZB - udelay( 1000 ); - /* Unreset the XBee Module */ - gpio_set_value( PIN_ZB_RST_N, 1 ); -#endif -#ifdef CONFIG_BOARD_MRMT_WIRELESS_BT - udelay( 1000 ); - /* Unreset the BT Module */ - gpio_set_value( PIN_BT_RST, 0 ); -#endif - - return 0; -} -arch_initcall(mrmt1_init); - -static int __init mrmt1_early_init(void) -{ - /* To maintain power-on signal in case boot loader did not already */ - at32_select_gpio( PIN_PWR_ON, AT32_GPIOF_OUTPUT ); - gpio_request( PIN_PWR_ON, "PIN_PWR_ON" ); - gpio_direction_output( PIN_PWR_ON, 1 ); - - return 0; -} -core_initcall(mrmt1_early_init); diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c deleted file mode 100644 index afeae8978a8d..000000000000 --- a/arch/avr32/boards/atngw100/setup.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Board-specific setup code for the ATNGW100 Network Gateway - * - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/etherdevice.h> -#include <linux/gpio.h> -#include <linux/irq.h> -#include <linux/i2c.h> -#include <linux/i2c-gpio.h> -#include <linux/init.h> -#include <linux/linkage.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/leds.h> -#include <linux/spi/spi.h> -#include <linux/atmel-mci.h> -#include <linux/usb/atmel_usba_udc.h> - -#include <asm/io.h> -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/board.h> -#include <mach/init.h> -#include <mach/portmux.h> - -/* Oscillator frequencies. These are board-specific */ -unsigned long at32_board_osc_rates[3] = { - [0] = 32768, /* 32.768 kHz on RTC osc */ - [1] = 20000000, /* 20 MHz on osc0 */ - [2] = 12000000, /* 12 MHz on osc1 */ -}; - -/* - * The ATNGW100 mkII is very similar to the ATNGW100. Both have the AT32AP7000 - * chip on board; the difference is that the ATNGW100 mkII has 128 MB 32-bit - * SDRAM (the ATNGW100 has 32 MB 16-bit SDRAM) and 256 MB 16-bit NAND flash - * (the ATNGW100 has none.) - * - * The RAM difference is handled by the boot loader, so the only difference we - * end up handling here is the NAND flash, EBI pin reservation and if LCDC or - * MACB1 should be enabled. - */ -#ifdef CONFIG_BOARD_ATNGW100_MKII -#include <linux/mtd/partitions.h> -#include <mach/smc.h> - -static struct smc_timing nand_timing __initdata = { - .ncs_read_setup = 0, - .nrd_setup = 10, - .ncs_write_setup = 0, - .nwe_setup = 10, - - .ncs_read_pulse = 30, - .nrd_pulse = 15, - .ncs_write_pulse = 30, - .nwe_pulse = 15, - - .read_cycle = 30, - .write_cycle = 30, - - .ncs_read_recover = 0, - .nrd_recover = 15, - .ncs_write_recover = 0, - /* WE# high -> RE# low min 60 ns */ - .nwe_recover = 50, -}; - -static struct smc_config nand_config __initdata = { - .bus_width = 2, - .nrd_controlled = 1, - .nwe_controlled = 1, - .nwait_mode = 0, - .byte_write = 0, - .tdf_cycles = 2, - .tdf_mode = 0, -}; - -static struct mtd_partition nand_partitions[] = { - { - .name = "main", - .offset = 0x00000000, - .size = MTDPART_SIZ_FULL, - }, -}; - - -static struct atmel_nand_data atngw100mkii_nand_data __initdata = { - .cle = 21, - .ale = 22, - .rdy_pin = GPIO_PIN_PB(28), - .enable_pin = GPIO_PIN_PE(23), - .bus_width_16 = true, - .ecc_mode = NAND_ECC_SOFT, - .parts = nand_partitions, - .num_parts = ARRAY_SIZE(nand_partitions), -}; -#endif - -/* Initialized by bootloader-specific startup code. */ -struct tag *bootloader_tags __initdata; - -struct eth_addr { - u8 addr[6]; -}; -static struct eth_addr __initdata hw_addr[2]; -static struct macb_platform_data __initdata eth_data[2]; - -static struct spi_board_info spi0_board_info[] __initdata = { - { - .modalias = "mtd_dataflash", - .max_speed_hz = 8000000, - .chip_select = 0, - }, -}; - -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, -#if defined(CONFIG_BOARD_ATNGW100_MKII) - .detect_pin = GPIO_PIN_PC(25), - .wp_pin = GPIO_PIN_PE(22), -#else - .detect_pin = GPIO_PIN_PC(25), - .wp_pin = GPIO_PIN_PE(0), -#endif - }, -}; - -static struct usba_platform_data atngw100_usba_data __initdata = { -#if defined(CONFIG_BOARD_ATNGW100_MKII) - .vbus_pin = GPIO_PIN_PE(26), -#else - .vbus_pin = -ENODEV, -#endif -}; - -/* - * The next two functions should go away as the boot loader is - * supposed to initialize the macb address registers with a valid - * ethernet address. But we need to keep it around for a while until - * we can be reasonably sure the boot loader does this. - * - * The phy_id is ignored as the driver will probe for it. - */ -static int __init parse_tag_ethernet(struct tag *tag) -{ - int i; - - i = tag->u.ethernet.mac_index; - if (i < ARRAY_SIZE(hw_addr)) - memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, - sizeof(hw_addr[i].addr)); - - return 0; -} -__tagtable(ATAG_ETHERNET, parse_tag_ethernet); - -static void __init set_hw_addr(struct platform_device *pdev) -{ - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - const u8 *addr; - void __iomem *regs; - struct clk *pclk; - - if (!res) - return; - if (pdev->id >= ARRAY_SIZE(hw_addr)) - return; - - addr = hw_addr[pdev->id].addr; - if (!is_valid_ether_addr(addr)) - return; - - /* - * Since this is board-specific code, we'll cheat and use the - * physical address directly as we happen to know that it's - * the same as the virtual address. - */ - regs = (void __iomem __force *)res->start; - pclk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(pclk)) - return; - - clk_enable(pclk); - __raw_writel((addr[3] << 24) | (addr[2] << 16) - | (addr[1] << 8) | addr[0], regs + 0x98); - __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); - clk_disable(pclk); - clk_put(pclk); -} - -void __init setup_board(void) -{ - at32_map_usart(1, 0, 0); /* USART 1: /dev/ttyS0, DB9 */ - at32_setup_serial_console(0); -} - -static const struct gpio_led ngw_leds[] = { - { .name = "sys", .gpio = GPIO_PIN_PA(16), .active_low = 1, - .default_trigger = "heartbeat", - }, - { .name = "a", .gpio = GPIO_PIN_PA(19), .active_low = 1, }, - { .name = "b", .gpio = GPIO_PIN_PE(19), .active_low = 1, }, -}; - -static const struct gpio_led_platform_data ngw_led_data = { - .num_leds = ARRAY_SIZE(ngw_leds), - .leds = (void *) ngw_leds, -}; - -static struct platform_device ngw_gpio_leds = { - .name = "leds-gpio", - .id = -1, - .dev = { - .platform_data = (void *) &ngw_led_data, - } -}; - -static struct i2c_gpio_platform_data i2c_gpio_data = { - .sda_pin = GPIO_PIN_PA(6), - .scl_pin = GPIO_PIN_PA(7), - .sda_is_open_drain = 1, - .scl_is_open_drain = 1, - .udelay = 2, /* close to 100 kHz */ -}; - -static struct platform_device i2c_gpio_device = { - .name = "i2c-gpio", - .id = 0, - .dev = { - .platform_data = &i2c_gpio_data, - }, -}; - -static struct i2c_board_info __initdata i2c_info[] = { - /* NOTE: original ATtiny24 firmware is at address 0x0b */ -}; - -static int __init atngw100_init(void) -{ - unsigned i; - - /* - * ATNGW100 mkII uses 32-bit SDRAM interface. Reserve the - * SDRAM-specific pins so that nobody messes with them. - */ -#ifdef CONFIG_BOARD_ATNGW100_MKII - at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); - - smc_set_timing(&nand_config, &nand_timing); - smc_set_configuration(3, &nand_config); - at32_add_device_nand(0, &atngw100mkii_nand_data); -#endif - - at32_add_device_usart(0); - - set_hw_addr(at32_add_device_eth(0, ð_data[0])); -#ifndef CONFIG_BOARD_ATNGW100_MKII_LCD - set_hw_addr(at32_add_device_eth(1, ð_data[1])); -#endif - - at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); - at32_add_device_mci(0, &mci0_data); - at32_add_device_usba(0, &atngw100_usba_data); - - for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) { - at32_select_gpio(ngw_leds[i].gpio, - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - } - platform_device_register(&ngw_gpio_leds); - - /* all these i2c/smbus pins should have external pullups for - * open-drain sharing among all I2C devices. SDA and SCL do; - * PB28/EXTINT3 (ATNGW100) and PE21 (ATNGW100 mkII) doesn't; it should - * be SMBALERT# (for PMBus), but it's not available off-board. - */ -#ifdef CONFIG_BOARD_ATNGW100_MKII - at32_select_periph(GPIO_PIOE_BASE, 1 << 21, 0, AT32_GPIOF_PULLUP); -#else - at32_select_periph(GPIO_PIOB_BASE, 1 << 28, 0, AT32_GPIOF_PULLUP); -#endif - at32_select_gpio(i2c_gpio_data.sda_pin, - AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(i2c_gpio_data.scl_pin, - AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - platform_device_register(&i2c_gpio_device); - i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info)); - - return 0; -} -postcore_initcall(atngw100_init); - -static int __init atngw100_arch_init(void) -{ - /* PB30 (ATNGW100) and PE30 (ATNGW100 mkII) is the otherwise unused - * jumper on the mainboard, with an external pullup; the jumper grounds - * it. Use it however you like, including letting U-Boot or Linux tweak - * boot sequences. - */ -#ifdef CONFIG_BOARD_ATNGW100_MKII - at32_select_gpio(GPIO_PIN_PE(30), 0); - gpio_request(GPIO_PIN_PE(30), "j15"); - gpio_direction_input(GPIO_PIN_PE(30)); - gpio_export(GPIO_PIN_PE(30), false); -#else - at32_select_gpio(GPIO_PIN_PB(30), 0); - gpio_request(GPIO_PIN_PB(30), "j15"); - gpio_direction_input(GPIO_PIN_PB(30)); - gpio_export(GPIO_PIN_PB(30), false); -#endif - - /* set_irq_type() after the arch_initcall for EIC has run, and - * before the I2C subsystem could try using this IRQ. - */ - return irq_set_irq_type(AT32_EXTINT(3), IRQ_TYPE_EDGE_FALLING); -} -arch_initcall(atngw100_arch_init); diff --git a/arch/avr32/boards/atstk1000/Kconfig b/arch/avr32/boards/atstk1000/Kconfig deleted file mode 100644 index 8dc48214f0b7..000000000000 --- a/arch/avr32/boards/atstk1000/Kconfig +++ /dev/null @@ -1,109 +0,0 @@ -# STK1000 customization - -if BOARD_ATSTK1000 - -choice - prompt "ATSTK1000 CPU daughterboard type" - default BOARD_ATSTK1002 - -config BOARD_ATSTK1002 - bool "ATSTK1002" - select CPU_AT32AP7000 - -config BOARD_ATSTK1003 - bool "ATSTK1003" - select CPU_AT32AP7001 - -config BOARD_ATSTK1004 - bool "ATSTK1004" - select CPU_AT32AP7002 - -config BOARD_ATSTK1006 - bool "ATSTK1006" - select CPU_AT32AP7000 - -endchoice - - -config BOARD_ATSTK100X_CUSTOM - bool "Non-default STK1002/STK1003/STK1004 jumper settings" - help - You will normally leave the jumpers on the CPU card at their - default settings. If you need to use certain peripherals, - you will need to change some of those jumpers. - -if BOARD_ATSTK100X_CUSTOM - -config BOARD_ATSTK100X_SW1_CUSTOM - bool "SW1: use SSC1 (not SPI0)" - help - This also prevents using the external DAC as an audio interface, - and means you can't initialize the on-board QVGA display. - -config BOARD_ATSTK100X_SW2_CUSTOM - bool "SW2: use IRDA or TIMER0 (not UART-A, MMC/SD, and PS2-A)" - help - If you change this you'll want an updated boot loader putting - the console on UART-C not UART-A. - -config BOARD_ATSTK100X_SW3_CUSTOM - bool "SW3: use TIMER1 (not SSC0 and GCLK)" - help - This also prevents using the external DAC as an audio interface. - -config BOARD_ATSTK100X_SW4_CUSTOM - bool "SW4: use ISI/Camera (not GPIOs, SPI1, and PS2-B)" - help - To use the camera interface you'll need a custom card (on the - PCI-format connector) connect a video sensor. - -config BOARD_ATSTK1002_SW5_CUSTOM - bool "SW5: use MACB1 (not LCDC)" - depends on BOARD_ATSTK1002 - -config BOARD_ATSTK1002_SW6_CUSTOM - bool "SW6: more GPIOs (not MACB0)" - depends on BOARD_ATSTK1002 - -endif # custom - -config BOARD_ATSTK100X_SPI1 - bool "Configure SPI1 controller" - depends on !BOARD_ATSTK100X_SW4_CUSTOM - help - All the signals for the second SPI controller are available on - GPIO lines and accessed through the J1 jumper block. Say "y" - here to configure that SPI controller. - -config BOARD_ATSTK1000_J2_LED - bool - default BOARD_ATSTK1000_J2_LED8 || BOARD_ATSTK1000_J2_RGB - -choice - prompt "LEDs connected to J2:" - depends on LEDS_GPIO && !BOARD_ATSTK100X_SW4_CUSTOM - optional - help - Select this if you have jumpered the J2 jumper block to the - LED0..LED7 amber leds, or to the RGB leds, using a ten-pin - IDC cable. A default "heartbeat" trigger is provided, but - you can of course override this. - -config BOARD_ATSTK1000_J2_LED8 - bool "LED0..LED7" - help - Select this if J2 is jumpered to LED0..LED7 amber leds. - -config BOARD_ATSTK1000_J2_RGB - bool "RGB leds" - help - Select this if J2 is jumpered to the RGB leds. - -endchoice - -config BOARD_ATSTK1000_EXTDAC - bool - depends on !BOARD_ATSTK100X_SW1_CUSTOM && !BOARD_ATSTK100X_SW3_CUSTOM - default y - -endif # stk 1000 diff --git a/arch/avr32/boards/atstk1000/Makefile b/arch/avr32/boards/atstk1000/Makefile deleted file mode 100644 index edecee03742d..000000000000 --- a/arch/avr32/boards/atstk1000/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-y += setup.o flash.o -obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o -obj-$(CONFIG_BOARD_ATSTK1003) += atstk1003.o -obj-$(CONFIG_BOARD_ATSTK1004) += atstk1004.o -obj-$(CONFIG_BOARD_ATSTK1006) += atstk1002.o diff --git a/arch/avr32/boards/atstk1000/atstk1000.h b/arch/avr32/boards/atstk1000/atstk1000.h deleted file mode 100644 index 653cc09e536c..000000000000 --- a/arch/avr32/boards/atstk1000/atstk1000.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * ATSTK1000 setup code: Daughterboard interface - * - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H -#define __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H - -extern struct atmel_lcdfb_pdata atstk1000_lcdc_data; - -void atstk1000_setup_j2_leds(void); - -#endif /* __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H */ diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c deleted file mode 100644 index 6c80aba7bf96..000000000000 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * ATSTK1002/ATSTK1006 daughterboard-specific init code - * - * Copyright (C) 2005-2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/etherdevice.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/string.h> -#include <linux/types.h> -#include <linux/spi/spi.h> -#include <linux/spi/at73c213.h> -#include <linux/atmel-mci.h> - -#include <video/atmel_lcdc.h> - -#include <asm/io.h> -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/board.h> -#include <mach/init.h> -#include <mach/portmux.h> - -#include "atstk1000.h" - -/* Oscillator frequencies. These are board specific */ -unsigned long at32_board_osc_rates[3] = { - [0] = 32768, /* 32.768 kHz on RTC osc */ - [1] = 20000000, /* 20 MHz on osc0 */ - [2] = 12000000, /* 12 MHz on osc1 */ -}; - -/* - * The ATSTK1006 daughterboard is very similar to the ATSTK1002. Both - * have the AT32AP7000 chip on board; the difference is that the - * STK1006 has 128 MB SDRAM (the STK1002 uses the 8 MB SDRAM chip on - * the STK1000 motherboard) and 256 MB NAND flash (the STK1002 has - * none.) - * - * The RAM difference is handled by the boot loader, so the only - * difference we end up handling here is the NAND flash. - */ -#ifdef CONFIG_BOARD_ATSTK1006 -#include <linux/mtd/partitions.h> -#include <mach/smc.h> - -static struct smc_timing nand_timing __initdata = { - .ncs_read_setup = 0, - .nrd_setup = 10, - .ncs_write_setup = 0, - .nwe_setup = 10, - - .ncs_read_pulse = 30, - .nrd_pulse = 15, - .ncs_write_pulse = 30, - .nwe_pulse = 15, - - .read_cycle = 30, - .write_cycle = 30, - - .ncs_read_recover = 0, - .nrd_recover = 15, - .ncs_write_recover = 0, - /* WE# high -> RE# low min 60 ns */ - .nwe_recover = 50, -}; - -static struct smc_config nand_config __initdata = { - .bus_width = 1, - .nrd_controlled = 1, - .nwe_controlled = 1, - .nwait_mode = 0, - .byte_write = 0, - .tdf_cycles = 2, - .tdf_mode = 0, -}; - -static struct mtd_partition nand_partitions[] = { - { - .name = "main", - .offset = 0x00000000, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct atmel_nand_data atstk1006_nand_data __initdata = { - .cle = 21, - .ale = 22, - .rdy_pin = GPIO_PIN_PB(30), - .enable_pin = GPIO_PIN_PB(29), - .ecc_mode = NAND_ECC_SOFT, - .parts = nand_partitions, - .num_parts = ARRAY_SIZE(nand_partitions), -}; -#endif - -struct eth_addr { - u8 addr[6]; -}; - -static struct eth_addr __initdata hw_addr[2]; -static struct macb_platform_data __initdata eth_data[2] = { - { - /* - * The MDIO pullups on STK1000 are a bit too weak for - * the autodetection to work properly, so we have to - * mask out everything but the correct address. - */ - .phy_mask = ~(1U << 16), - }, - { - .phy_mask = ~(1U << 17), - }, -}; - -#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC -static struct at73c213_board_info at73c213_data = { - .ssc_id = 0, - .shortname = "AVR32 STK1000 external DAC", -}; -#endif - -#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM -static struct spi_board_info spi0_board_info[] __initdata = { -#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC - { - /* AT73C213 */ - .modalias = "at73c213", - .max_speed_hz = 200000, - .chip_select = 0, - .mode = SPI_MODE_1, - .platform_data = &at73c213_data, - }, -#endif - { - /* QVGA display */ - .modalias = "ltv350qv", - .max_speed_hz = 16000000, - .chip_select = 1, - .mode = SPI_MODE_3, - }, -}; -#endif - -#ifdef CONFIG_BOARD_ATSTK100X_SPI1 -static struct spi_board_info spi1_board_info[] __initdata = { { - /* patch in custom entries here */ -} }; -#endif - -/* - * The next two functions should go away as the boot loader is - * supposed to initialize the macb address registers with a valid - * ethernet address. But we need to keep it around for a while until - * we can be reasonably sure the boot loader does this. - * - * The phy_id is ignored as the driver will probe for it. - */ -static int __init parse_tag_ethernet(struct tag *tag) -{ - int i; - - i = tag->u.ethernet.mac_index; - if (i < ARRAY_SIZE(hw_addr)) - memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, - sizeof(hw_addr[i].addr)); - - return 0; -} -__tagtable(ATAG_ETHERNET, parse_tag_ethernet); - -static void __init set_hw_addr(struct platform_device *pdev) -{ - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - const u8 *addr; - void __iomem *regs; - struct clk *pclk; - - if (!res) - return; - if (pdev->id >= ARRAY_SIZE(hw_addr)) - return; - - addr = hw_addr[pdev->id].addr; - if (!is_valid_ether_addr(addr)) - return; - - /* - * Since this is board-specific code, we'll cheat and use the - * physical address directly as we happen to know that it's - * the same as the virtual address. - */ - regs = (void __iomem __force *)res->start; - pclk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(pclk)) - return; - - clk_enable(pclk); - __raw_writel((addr[3] << 24) | (addr[2] << 16) - | (addr[1] << 8) | addr[0], regs + 0x98); - __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); - clk_disable(pclk); - clk_put(pclk); -} - -#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC -static void __init atstk1002_setup_extdac(void) -{ - struct clk *gclk; - struct clk *pll; - - gclk = clk_get(NULL, "gclk0"); - if (IS_ERR(gclk)) - goto err_gclk; - pll = clk_get(NULL, "pll0"); - if (IS_ERR(pll)) - goto err_pll; - - if (clk_set_parent(gclk, pll)) { - pr_debug("STK1000: failed to set pll0 as parent for DAC clock\n"); - goto err_set_clk; - } - - at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0); - at73c213_data.dac_clk = gclk; - -err_set_clk: - clk_put(pll); -err_pll: - clk_put(gclk); -err_gclk: - return; -} -#else -static void __init atstk1002_setup_extdac(void) -{ - -} -#endif /* CONFIG_BOARD_ATSTK1000_EXTDAC */ - -void __init setup_board(void) -{ -#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */ -#else - at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */ -#endif - /* USART 2/unused: expansion connector */ - at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */ - - at32_setup_serial_console(0); -} - -#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, - -/* MMC card detect requires MACB0 *NOT* be used */ -#ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM - .detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */ - .wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */ -#else - .detect_pin = -ENODEV, - .wp_pin = -ENODEV, -#endif /* SW6 for sd{cd,wp} routing */ - }, -}; - -#endif /* SW2 for MMC signal routing */ - -static int __init atstk1002_init(void) -{ - /* - * ATSTK1000 uses 32-bit SDRAM interface. Reserve the - * SDRAM-specific pins so that nobody messes with them. - */ - at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); - -#ifdef CONFIG_BOARD_ATSTK1006 - smc_set_timing(&nand_config, &nand_timing); - smc_set_configuration(3, &nand_config); - at32_add_device_nand(0, &atstk1006_nand_data); -#endif - -#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_add_device_usart(1); -#else - at32_add_device_usart(0); -#endif - at32_add_device_usart(2); - -#ifndef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM - set_hw_addr(at32_add_device_eth(0, ð_data[0])); -#endif -#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM - at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); -#endif -#ifdef CONFIG_BOARD_ATSTK100X_SPI1 - at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); -#endif -#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_add_device_mci(0, &mci0_data); -#endif -#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM - set_hw_addr(at32_add_device_eth(1, ð_data[1])); -#else - at32_add_device_lcdc(0, &atstk1000_lcdc_data, - fbmem_start, fbmem_size, - ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL); -#endif - at32_add_device_usba(0, NULL); -#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM - at32_add_device_ssc(0, ATMEL_SSC_TX); -#endif - - atstk1000_setup_j2_leds(); - atstk1002_setup_extdac(); - - return 0; -} -postcore_initcall(atstk1002_init); diff --git a/arch/avr32/boards/atstk1000/atstk1003.c b/arch/avr32/boards/atstk1000/atstk1003.c deleted file mode 100644 index ff7e23298827..000000000000 --- a/arch/avr32/boards/atstk1000/atstk1003.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * ATSTK1003 daughterboard-specific init code - * - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/string.h> -#include <linux/types.h> - -#include <linux/spi/at73c213.h> -#include <linux/spi/spi.h> -#include <linux/atmel-mci.h> - -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/board.h> -#include <mach/init.h> -#include <mach/portmux.h> - -#include "atstk1000.h" - -/* Oscillator frequencies. These are board specific */ -unsigned long at32_board_osc_rates[3] = { - [0] = 32768, /* 32.768 kHz on RTC osc */ - [1] = 20000000, /* 20 MHz on osc0 */ - [2] = 12000000, /* 12 MHz on osc1 */ -}; - -#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC -static struct at73c213_board_info at73c213_data = { - .ssc_id = 0, - .shortname = "AVR32 STK1000 external DAC", -}; -#endif - -#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM -static struct spi_board_info spi0_board_info[] __initdata = { -#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC - { - /* AT73C213 */ - .modalias = "at73c213", - .max_speed_hz = 200000, - .chip_select = 0, - .mode = SPI_MODE_1, - .platform_data = &at73c213_data, - }, -#endif - /* - * We can control the LTV350QV LCD panel, but it isn't much - * point since we don't have an LCD controller... - */ -}; -#endif - -#ifdef CONFIG_BOARD_ATSTK100X_SPI1 -static struct spi_board_info spi1_board_info[] __initdata = { { - /* patch in custom entries here */ -} }; -#endif - -#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = -ENODEV, - .wp_pin = -ENODEV, - }, -}; -#endif - -#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC -static void __init atstk1003_setup_extdac(void) -{ - struct clk *gclk; - struct clk *pll; - - gclk = clk_get(NULL, "gclk0"); - if (IS_ERR(gclk)) - goto err_gclk; - pll = clk_get(NULL, "pll0"); - if (IS_ERR(pll)) - goto err_pll; - - if (clk_set_parent(gclk, pll)) { - pr_debug("STK1000: failed to set pll0 as parent for DAC clock\n"); - goto err_set_clk; - } - - at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0); - at73c213_data.dac_clk = gclk; - -err_set_clk: - clk_put(pll); -err_pll: - clk_put(gclk); -err_gclk: - return; -} -#else -static void __init atstk1003_setup_extdac(void) -{ - -} -#endif /* CONFIG_BOARD_ATSTK1000_EXTDAC */ - -void __init setup_board(void) -{ -#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */ -#else - at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */ -#endif - /* USART 2/unused: expansion connector */ - at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */ - - at32_setup_serial_console(0); -} - -static int __init atstk1003_init(void) -{ - /* - * ATSTK1000 uses 32-bit SDRAM interface. Reserve the - * SDRAM-specific pins so that nobody messes with them. - */ - at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); - -#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_add_device_usart(1); -#else - at32_add_device_usart(0); -#endif - at32_add_device_usart(2); - -#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM - at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); -#endif -#ifdef CONFIG_BOARD_ATSTK100X_SPI1 - at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); -#endif -#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_add_device_mci(0, &mci0_data); -#endif - at32_add_device_usba(0, NULL); -#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM - at32_add_device_ssc(0, ATMEL_SSC_TX); -#endif - - atstk1000_setup_j2_leds(); - atstk1003_setup_extdac(); - - return 0; -} -postcore_initcall(atstk1003_init); diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c deleted file mode 100644 index 69a9f0f08c6e..000000000000 --- a/arch/avr32/boards/atstk1000/atstk1004.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * ATSTK1003 daughterboard-specific init code - * - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/string.h> -#include <linux/types.h> - -#include <linux/spi/at73c213.h> -#include <linux/spi/spi.h> -#include <linux/atmel-mci.h> - -#include <video/atmel_lcdc.h> - -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/board.h> -#include <mach/init.h> -#include <mach/portmux.h> - -#include "atstk1000.h" - -/* Oscillator frequencies. These are board specific */ -unsigned long at32_board_osc_rates[3] = { - [0] = 32768, /* 32.768 kHz on RTC osc */ - [1] = 20000000, /* 20 MHz on osc0 */ - [2] = 12000000, /* 12 MHz on osc1 */ -}; - -#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC -static struct at73c213_board_info at73c213_data = { - .ssc_id = 0, - .shortname = "AVR32 STK1000 external DAC", -}; -#endif - -#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM -static struct spi_board_info spi0_board_info[] __initdata = { -#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC - { - /* AT73C213 */ - .modalias = "at73c213", - .max_speed_hz = 200000, - .chip_select = 0, - .mode = SPI_MODE_1, - .platform_data = &at73c213_data, - }, -#endif - { - /* QVGA display */ - .modalias = "ltv350qv", - .max_speed_hz = 16000000, - .chip_select = 1, - .mode = SPI_MODE_3, - }, -}; -#endif - -#ifdef CONFIG_BOARD_ATSTK100X_SPI1 -static struct spi_board_info spi1_board_info[] __initdata = { { - /* patch in custom entries here */ -} }; -#endif - -#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = -ENODEV, - .wp_pin = -ENODEV, - }, -}; -#endif - -#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC -static void __init atstk1004_setup_extdac(void) -{ - struct clk *gclk; - struct clk *pll; - - gclk = clk_get(NULL, "gclk0"); - if (IS_ERR(gclk)) - goto err_gclk; - pll = clk_get(NULL, "pll0"); - if (IS_ERR(pll)) - goto err_pll; - - if (clk_set_parent(gclk, pll)) { - pr_debug("STK1000: failed to set pll0 as parent for DAC clock\n"); - goto err_set_clk; - } - - at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0); - at73c213_data.dac_clk = gclk; - -err_set_clk: - clk_put(pll); -err_pll: - clk_put(gclk); -err_gclk: - return; -} -#else -static void __init atstk1004_setup_extdac(void) -{ - -} -#endif /* CONFIG_BOARD_ATSTK1000_EXTDAC */ - -void __init setup_board(void) -{ -#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */ -#else - at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */ -#endif - /* USART 2/unused: expansion connector */ - at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */ - - at32_setup_serial_console(0); -} - -static int __init atstk1004_init(void) -{ -#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_add_device_usart(1); -#else - at32_add_device_usart(0); -#endif - at32_add_device_usart(2); - -#ifndef CONFIG_BOARD_ATSTK100X_SW1_CUSTOM - at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); -#endif -#ifdef CONFIG_BOARD_ATSTK100X_SPI1 - at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); -#endif -#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_add_device_mci(0, &mci0_data); -#endif - at32_add_device_lcdc(0, &atstk1000_lcdc_data, - fbmem_start, fbmem_size, - ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL); - at32_add_device_usba(0, NULL); -#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM - at32_add_device_ssc(0, ATMEL_SSC_TX); -#endif - - atstk1000_setup_j2_leds(); - atstk1004_setup_extdac(); - - return 0; -} -postcore_initcall(atstk1004_init); diff --git a/arch/avr32/boards/atstk1000/flash.c b/arch/avr32/boards/atstk1000/flash.c deleted file mode 100644 index 6e4d561977ff..000000000000 --- a/arch/avr32/boards/atstk1000/flash.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * ATSTK1000 board-specific flash initialization - * - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> - -#include <mach/smc.h> - -static struct smc_timing flash_timing __initdata = { - .ncs_read_setup = 0, - .nrd_setup = 40, - .ncs_write_setup = 0, - .nwe_setup = 10, - - .ncs_read_pulse = 80, - .nrd_pulse = 40, - .ncs_write_pulse = 65, - .nwe_pulse = 55, - - .read_cycle = 120, - .write_cycle = 120, -}; - -static struct smc_config flash_config __initdata = { - .bus_width = 2, - .nrd_controlled = 1, - .nwe_controlled = 1, - .byte_write = 1, -}; - -static struct mtd_partition flash_parts[] = { - { - .name = "u-boot", - .offset = 0x00000000, - .size = 0x00020000, /* 128 KiB */ - .mask_flags = MTD_WRITEABLE, - }, - { - .name = "root", - .offset = 0x00020000, - .size = 0x007d0000, - }, - { - .name = "env", - .offset = 0x007f0000, - .size = 0x00010000, - .mask_flags = MTD_WRITEABLE, - }, -}; - -static struct physmap_flash_data flash_data = { - .width = 2, - .nr_parts = ARRAY_SIZE(flash_parts), - .parts = flash_parts, -}; - -static struct resource flash_resource = { - .start = 0x00000000, - .end = 0x007fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device flash_device = { - .name = "physmap-flash", - .id = 0, - .resource = &flash_resource, - .num_resources = 1, - .dev = { - .platform_data = &flash_data, - }, -}; - -/* This needs to be called after the SMC has been initialized */ -static int __init atstk1000_flash_init(void) -{ - int ret; - - smc_set_timing(&flash_config, &flash_timing); - ret = smc_set_configuration(0, &flash_config); - if (ret < 0) { - printk(KERN_ERR "atstk1000: failed to set NOR flash timing\n"); - return ret; - } - - platform_device_register(&flash_device); - - return 0; -} -device_initcall(atstk1000_flash_init); diff --git a/arch/avr32/boards/atstk1000/setup.c b/arch/avr32/boards/atstk1000/setup.c deleted file mode 100644 index b6b88f5e0b43..000000000000 --- a/arch/avr32/boards/atstk1000/setup.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * ATSTK1000 board-specific setup code. - * - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/bootmem.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/linkage.h> - -#include <video/atmel_lcdc.h> - -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/board.h> -#include <mach/portmux.h> - -#include "atstk1000.h" - -/* Initialized by bootloader-specific startup code. */ -struct tag *bootloader_tags __initdata; - -static struct fb_videomode __initdata ltv350qv_modes[] = { - { - .name = "320x240 @ 75", - .refresh = 75, - .xres = 320, .yres = 240, - .pixclock = KHZ2PICOS(6891), - - .left_margin = 17, .right_margin = 33, - .upper_margin = 10, .lower_margin = 10, - .hsync_len = 16, .vsync_len = 1, - - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs __initdata atstk1000_default_monspecs = { - .manufacturer = "SNG", - .monitor = "LTV350QV", - .modedb = ltv350qv_modes, - .modedb_len = ARRAY_SIZE(ltv350qv_modes), - .hfmin = 14820, - .hfmax = 22230, - .vfmin = 60, - .vfmax = 90, - .dclkmax = 30000000, -}; - -struct atmel_lcdfb_pdata __initdata atstk1000_lcdc_data = { - .default_bpp = 24, - .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, - .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT - | ATMEL_LCDC_INVCLK - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE - | ATMEL_LCDC_MEMOR_BIG), - .default_monspecs = &atstk1000_default_monspecs, - .guard_time = 2, -}; - -#ifdef CONFIG_BOARD_ATSTK1000_J2_LED -#include <linux/leds.h> - -static struct gpio_led stk1000_j2_led[] = { -#ifdef CONFIG_BOARD_ATSTK1000_J2_LED8 -#define LEDSTRING "J2 jumpered to LED8" - { .name = "led0:amber", .gpio = GPIO_PIN_PB( 8), }, - { .name = "led1:amber", .gpio = GPIO_PIN_PB( 9), }, - { .name = "led2:amber", .gpio = GPIO_PIN_PB(10), }, - { .name = "led3:amber", .gpio = GPIO_PIN_PB(13), }, - { .name = "led4:amber", .gpio = GPIO_PIN_PB(14), }, - { .name = "led5:amber", .gpio = GPIO_PIN_PB(15), }, - { .name = "led6:amber", .gpio = GPIO_PIN_PB(16), }, - { .name = "led7:amber", .gpio = GPIO_PIN_PB(30), - .default_trigger = "heartbeat", }, -#else /* RGB */ -#define LEDSTRING "J2 jumpered to RGB LEDs" - { .name = "r1:red", .gpio = GPIO_PIN_PB( 8), }, - { .name = "g1:green", .gpio = GPIO_PIN_PB(10), }, - { .name = "b1:blue", .gpio = GPIO_PIN_PB(14), }, - - { .name = "r2:red", .gpio = GPIO_PIN_PB( 9), - .default_trigger = "heartbeat", }, - { .name = "g2:green", .gpio = GPIO_PIN_PB(13), }, - { .name = "b2:blue", .gpio = GPIO_PIN_PB(15), - .default_trigger = "heartbeat", }, - /* PB16, PB30 unused */ -#endif -}; - -static struct gpio_led_platform_data stk1000_j2_led_data = { - .num_leds = ARRAY_SIZE(stk1000_j2_led), - .leds = stk1000_j2_led, -}; - -static struct platform_device stk1000_j2_led_dev = { - .name = "leds-gpio", - .id = 2, /* gpio block J2 */ - .dev = { - .platform_data = &stk1000_j2_led_data, - }, -}; - -void __init atstk1000_setup_j2_leds(void) -{ - unsigned i; - - for (i = 0; i < ARRAY_SIZE(stk1000_j2_led); i++) - at32_select_gpio(stk1000_j2_led[i].gpio, AT32_GPIOF_OUTPUT); - - printk("STK1000: " LEDSTRING "\n"); - platform_device_register(&stk1000_j2_led_dev); -} -#else /* CONFIG_BOARD_ATSTK1000_J2_LED */ -void __init atstk1000_setup_j2_leds(void) -{ - -} -#endif /* CONFIG_BOARD_ATSTK1000_J2_LED */ diff --git a/arch/avr32/boards/favr-32/Kconfig b/arch/avr32/boards/favr-32/Kconfig deleted file mode 100644 index 2c83d1ddcaec..000000000000 --- a/arch/avr32/boards/favr-32/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -# Favr-32 customization - -if BOARD_FAVR_32 - -config BOARD_FAVR32_ABDAC_RATE - int "DAC target rate" - default 44100 - range 32000 50000 - help - Specify the target rate the internal DAC should try to match. This - will use PLL1 to generate a frequency as close as possible to this - rate. - - Must be within the range 32000 to 50000, which should be suitable to - generate most other frequencies in power of 2 steps. - - Ex: - 48000 will also suit 24000 and 12000 - 44100 will also suit 22050 and 11025 - 32000 will also suit 16000 and 8000 - -endif # BOARD_FAVR_32 diff --git a/arch/avr32/boards/favr-32/Makefile b/arch/avr32/boards/favr-32/Makefile deleted file mode 100644 index 234f21508e4b..000000000000 --- a/arch/avr32/boards/favr-32/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y += setup.o flash.o diff --git a/arch/avr32/boards/favr-32/flash.c b/arch/avr32/boards/favr-32/flash.c deleted file mode 100644 index 604bbd5e41d9..000000000000 --- a/arch/avr32/boards/favr-32/flash.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Favr-32 board-specific flash initialization - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> - -#include <mach/smc.h> - -static struct smc_timing flash_timing __initdata = { - .ncs_read_setup = 0, - .nrd_setup = 40, - .ncs_write_setup = 0, - .nwe_setup = 10, - - .ncs_read_pulse = 80, - .nrd_pulse = 40, - .ncs_write_pulse = 65, - .nwe_pulse = 55, - - .read_cycle = 120, - .write_cycle = 120, -}; - -static struct smc_config flash_config __initdata = { - .bus_width = 2, - .nrd_controlled = 1, - .nwe_controlled = 1, - .byte_write = 1, -}; - -static struct mtd_partition flash_parts[] = { - { - .name = "u-boot", - .offset = 0x00000000, - .size = 0x00020000, /* 128 KiB */ - .mask_flags = MTD_WRITEABLE, - }, - { - .name = "root", - .offset = 0x00020000, - .size = 0x007d0000, - }, - { - .name = "env", - .offset = 0x007f0000, - .size = 0x00010000, - .mask_flags = MTD_WRITEABLE, - }, -}; - -static struct physmap_flash_data flash_data = { - .width = 2, - .nr_parts = ARRAY_SIZE(flash_parts), - .parts = flash_parts, -}; - -static struct resource flash_resource = { - .start = 0x00000000, - .end = 0x007fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device flash_device = { - .name = "physmap-flash", - .id = 0, - .resource = &flash_resource, - .num_resources = 1, - .dev = { - .platform_data = &flash_data, - }, -}; - -/* This needs to be called after the SMC has been initialized */ -static int __init favr32_flash_init(void) -{ - int ret; - - smc_set_timing(&flash_config, &flash_timing); - ret = smc_set_configuration(0, &flash_config); - if (ret < 0) { - printk(KERN_ERR "Favr-32: failed to set NOR flash timing\n"); - return ret; - } - - platform_device_register(&flash_device); - - return 0; -} -device_initcall(favr32_flash_init); diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c deleted file mode 100644 index 234cb071c601..000000000000 --- a/arch/avr32/boards/favr-32/setup.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Favr-32 board-specific setup code. - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/etherdevice.h> -#include <linux/bootmem.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/linkage.h> -#include <linux/gpio.h> -#include <linux/leds.h> -#include <linux/atmel-mci.h> -#include <linux/pwm.h> -#include <linux/pwm_backlight.h> -#include <linux/regulator/fixed.h> -#include <linux/regulator/machine.h> -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> - -#include <sound/atmel-abdac.h> - -#include <video/atmel_lcdc.h> - -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/init.h> -#include <mach/board.h> -#include <mach/portmux.h> - -#define PWM_BL_CH 2 - -/* Oscillator frequencies. These are board-specific */ -unsigned long at32_board_osc_rates[3] = { - [0] = 32768, /* 32.768 kHz on RTC osc */ - [1] = 20000000, /* 20 MHz on osc0 */ - [2] = 12000000, /* 12 MHz on osc1 */ -}; - -/* Initialized by bootloader-specific startup code. */ -struct tag *bootloader_tags __initdata; - -static struct atmel_abdac_pdata __initdata abdac0_data = { -}; - -struct eth_addr { - u8 addr[6]; -}; -static struct eth_addr __initdata hw_addr[1]; -static struct macb_platform_data __initdata eth_data[1] = { - { - .phy_mask = ~(1U << 1), - }, -}; - -static int ads7843_get_pendown_state(void) -{ - return !gpio_get_value(GPIO_PIN_PB(3)); -} - -static struct ads7846_platform_data ads7843_data = { - .model = 7843, - .get_pendown_state = ads7843_get_pendown_state, - .pressure_max = 255, - /* - * Values below are for debounce filtering, these can be experimented - * with further. - */ - .debounce_max = 20, - .debounce_rep = 4, - .debounce_tol = 5, - - .keep_vref_on = true, - .settle_delay_usecs = 500, - .penirq_recheck_delay_usecs = 100, -}; - -static struct spi_board_info __initdata spi1_board_info[] = { - { - /* ADS7843 touch controller */ - .modalias = "ads7846", - .max_speed_hz = 2000000, - .chip_select = 0, - .bus_num = 1, - .platform_data = &ads7843_data, - }, -}; - -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = -ENODEV, - .wp_pin = -ENODEV, - }, -}; - -static struct fb_videomode __initdata lb104v03_modes[] = { - { - .name = "640x480 @ 50", - .refresh = 50, - .xres = 640, .yres = 480, - .pixclock = KHZ2PICOS(25100), - - .left_margin = 90, .right_margin = 70, - .upper_margin = 30, .lower_margin = 15, - .hsync_len = 12, .vsync_len = 2, - - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs __initdata favr32_default_monspecs = { - .manufacturer = "LG", - .monitor = "LB104V03", - .modedb = lb104v03_modes, - .modedb_len = ARRAY_SIZE(lb104v03_modes), - .hfmin = 27273, - .hfmax = 31111, - .vfmin = 45, - .vfmax = 60, - .dclkmax = 28000000, -}; - -struct atmel_lcdfb_pdata __initdata favr32_lcdc_data = { - .default_bpp = 16, - .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, - .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE - | ATMEL_LCDC_MEMOR_BIG), - .default_monspecs = &favr32_default_monspecs, - .guard_time = 2, -}; - -static struct gpio_led favr32_leds[] = { - { - .name = "green", - .gpio = GPIO_PIN_PE(19), - .default_trigger = "heartbeat", - .active_low = 1, - }, - { - .name = "red", - .gpio = GPIO_PIN_PE(20), - .active_low = 1, - }, -}; - -static struct gpio_led_platform_data favr32_led_data = { - .num_leds = ARRAY_SIZE(favr32_leds), - .leds = favr32_leds, -}; - -static struct platform_device favr32_led_dev = { - .name = "leds-gpio", - .id = 0, - .dev = { - .platform_data = &favr32_led_data, - }, -}; - -/* - * The next two functions should go away as the boot loader is - * supposed to initialize the macb address registers with a valid - * ethernet address. But we need to keep it around for a while until - * we can be reasonably sure the boot loader does this. - * - * The phy_id is ignored as the driver will probe for it. - */ -static int __init parse_tag_ethernet(struct tag *tag) -{ - int i; - - i = tag->u.ethernet.mac_index; - if (i < ARRAY_SIZE(hw_addr)) - memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, - sizeof(hw_addr[i].addr)); - - return 0; -} -__tagtable(ATAG_ETHERNET, parse_tag_ethernet); - -static void __init set_hw_addr(struct platform_device *pdev) -{ - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - const u8 *addr; - void __iomem *regs; - struct clk *pclk; - - if (!res) - return; - if (pdev->id >= ARRAY_SIZE(hw_addr)) - return; - - addr = hw_addr[pdev->id].addr; - if (!is_valid_ether_addr(addr)) - return; - - /* - * Since this is board-specific code, we'll cheat and use the - * physical address directly as we happen to know that it's - * the same as the virtual address. - */ - regs = (void __iomem __force *)res->start; - pclk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(pclk)) - return; - - clk_enable(pclk); - __raw_writel((addr[3] << 24) | (addr[2] << 16) - | (addr[1] << 8) | addr[0], regs + 0x98); - __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); - clk_disable(pclk); - clk_put(pclk); -} - -void __init favr32_setup_leds(void) -{ - unsigned i; - - for (i = 0; i < ARRAY_SIZE(favr32_leds); i++) - at32_select_gpio(favr32_leds[i].gpio, AT32_GPIOF_OUTPUT); - - platform_device_register(&favr32_led_dev); -} - -static struct pwm_lookup pwm_lookup[] = { - PWM_LOOKUP("at91sam9rl-pwm", PWM_BL_CH, "pwm-backlight.0", NULL, - 5000, PWM_POLARITY_INVERSED), -}; - -static struct regulator_consumer_supply fixed_power_consumers[] = { - REGULATOR_SUPPLY("power", "pwm-backlight.0"), -}; - -static struct platform_pwm_backlight_data pwm_bl_data = { - .enable_gpio = GPIO_PIN_PA(28), - .max_brightness = 255, - .dft_brightness = 255, - .lth_brightness = 50, -}; - -static struct platform_device pwm_bl_device = { - .name = "pwm-backlight", - .dev = { - .platform_data = &pwm_bl_data, - }, -}; - -static void __init favr32_setup_atmel_pwm_bl(void) -{ - pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup)); - regulator_register_always_on(0, "fixed", fixed_power_consumers, - ARRAY_SIZE(fixed_power_consumers), 3300000); - platform_device_register(&pwm_bl_device); - at32_select_gpio(pwm_bl_data.enable_gpio, 0); -} - -void __init setup_board(void) -{ - at32_map_usart(3, 0, 0); /* USART 3 => /dev/ttyS0 */ - at32_setup_serial_console(0); -} - -static int __init set_abdac_rate(struct platform_device *pdev) -{ - int retval; - struct clk *osc1; - struct clk *pll1; - struct clk *abdac; - - if (pdev == NULL) - return -ENXIO; - - osc1 = clk_get(NULL, "osc1"); - if (IS_ERR(osc1)) { - retval = PTR_ERR(osc1); - goto out; - } - - pll1 = clk_get(NULL, "pll1"); - if (IS_ERR(pll1)) { - retval = PTR_ERR(pll1); - goto out_osc1; - } - - abdac = clk_get(&pdev->dev, "sample_clk"); - if (IS_ERR(abdac)) { - retval = PTR_ERR(abdac); - goto out_pll1; - } - - retval = clk_set_parent(pll1, osc1); - if (retval != 0) - goto out_abdac; - - /* - * Rate is 32000 to 50000 and ABDAC oversamples 256x. Multiply, in - * power of 2, to a value above 80 MHz. Power of 2 so it is possible - * for the generic clock to divide it down again and 80 MHz is the - * lowest frequency for the PLL. - */ - retval = clk_round_rate(pll1, - CONFIG_BOARD_FAVR32_ABDAC_RATE * 256 * 16); - if (retval <= 0) { - retval = -EINVAL; - goto out_abdac; - } - - retval = clk_set_rate(pll1, retval); - if (retval != 0) - goto out_abdac; - - retval = clk_set_parent(abdac, pll1); - if (retval != 0) - goto out_abdac; - -out_abdac: - clk_put(abdac); -out_pll1: - clk_put(pll1); -out_osc1: - clk_put(osc1); -out: - return retval; -} - -static int __init favr32_init(void) -{ - /* - * Favr-32 uses 32-bit SDRAM interface. Reserve the SDRAM-specific - * pins so that nobody messes with them. - */ - at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); - - at32_select_gpio(GPIO_PIN_PB(3), 0); /* IRQ from ADS7843 */ - - at32_add_device_usart(0); - - set_hw_addr(at32_add_device_eth(0, ð_data[0])); - - spi1_board_info[0].irq = gpio_to_irq(GPIO_PIN_PB(3)); - - set_abdac_rate(at32_add_device_abdac(0, &abdac0_data)); - - at32_add_device_pwm(1 << PWM_BL_CH); - at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); - at32_add_device_mci(0, &mci0_data); - at32_add_device_usba(0, NULL); - at32_add_device_lcdc(0, &favr32_lcdc_data, fbmem_start, fbmem_size, 0); - - favr32_setup_leds(); - - favr32_setup_atmel_pwm_bl(); - - return 0; -} -postcore_initcall(favr32_init); diff --git a/arch/avr32/boards/hammerhead/Kconfig b/arch/avr32/boards/hammerhead/Kconfig deleted file mode 100644 index 5c13d785cc70..000000000000 --- a/arch/avr32/boards/hammerhead/Kconfig +++ /dev/null @@ -1,43 +0,0 @@ -# Hammerhead customization - -if BOARD_HAMMERHEAD - -config BOARD_HAMMERHEAD_USB - bool "Philips ISP116x-hcd USB support" - help - This enables USB support for Hammerheads internal ISP116x - controller from Philips. - - Choose 'Y' here if you want to have your board USB driven. - -config BOARD_HAMMERHEAD_LCD - bool "Atmel AT91/AT32 LCD support" - help - This enables LCD support for the Hammerhead board. You may - also add support for framebuffer devices (AT91/AT32 LCD Controller) - and framebuffer console support to get the most out of your LCD. - - Choose 'Y' here if you have ordered a Corona daugther board and - want to have support for your Hantronix HDA-351T-LV LCD. - -config BOARD_HAMMERHEAD_SND - bool "Atmel AC97 Sound support" - help - This enables Sound support for the Hammerhead board. You may - also go through the ALSA settings to get it working. - - Choose 'Y' here if you have ordered a Corona daugther board and - want to make your board funky. - -config BOARD_HAMMERHEAD_FPGA - bool "Hammerhead FPGA Support" - default y - help - This adds support for the Cyclone III FPGA from Altera - found on Miromico's Hammerhead board. - - Choose 'Y' here if you want to have FPGA support enabled. - You will have to choose the "Hammerhead FPGA Device Support" in - Device Drivers->Misc to be able to use FPGA functionality. - -endif # BOARD_ATNGW100 diff --git a/arch/avr32/boards/hammerhead/Makefile b/arch/avr32/boards/hammerhead/Makefile deleted file mode 100644 index c740aa116755..000000000000 --- a/arch/avr32/boards/hammerhead/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y += setup.o flash.o diff --git a/arch/avr32/boards/hammerhead/flash.c b/arch/avr32/boards/hammerhead/flash.c deleted file mode 100644 index e86280ccd8fa..000000000000 --- a/arch/avr32/boards/hammerhead/flash.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Hammerhead board-specific flash initialization - * - * Copyright (C) 2008 Miromico AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> -#include <linux/usb/isp116x.h> -#include <linux/dma-mapping.h> -#include <linux/delay.h> - -#include <mach/portmux.h> -#include <mach/at32ap700x.h> -#include <mach/smc.h> - -#include "../../mach-at32ap/clock.h" -#include "flash.h" - - -#define HAMMERHEAD_USB_PERIPH_GCLK0 0x40000000 -#define HAMMERHEAD_USB_PERIPH_CS2 0x02000000 -#define HAMMERHEAD_USB_PERIPH_EXTINT0 0x02000000 - -#define HAMMERHEAD_FPGA_PERIPH_MOSI 0x00000002 -#define HAMMERHEAD_FPGA_PERIPH_SCK 0x00000020 -#define HAMMERHEAD_FPGA_PERIPH_EXTINT3 0x10000000 - -static struct smc_timing flash_timing __initdata = { - .ncs_read_setup = 0, - .nrd_setup = 40, - .ncs_write_setup = 0, - .nwe_setup = 10, - - .ncs_read_pulse = 80, - .nrd_pulse = 40, - .ncs_write_pulse = 65, - .nwe_pulse = 55, - - .read_cycle = 120, - .write_cycle = 120, -}; - -static struct smc_config flash_config __initdata = { - .bus_width = 2, - .nrd_controlled = 1, - .nwe_controlled = 1, - .byte_write = 1, -}; - -static struct mtd_partition flash_parts[] = { - { - .name = "u-boot", - .offset = 0x00000000, - .size = 0x00020000, /* 128 KiB */ - .mask_flags = MTD_WRITEABLE, - }, - { - .name = "root", - .offset = 0x00020000, - .size = 0x007d0000, - }, - { - .name = "env", - .offset = 0x007f0000, - .size = 0x00010000, - .mask_flags = MTD_WRITEABLE, - }, -}; - -static struct physmap_flash_data flash_data = { - .width = 2, - .nr_parts = ARRAY_SIZE(flash_parts), - .parts = flash_parts, -}; - -static struct resource flash_resource = { - .start = 0x00000000, - .end = 0x007fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device flash_device = { - .name = "physmap-flash", - .id = 0, - .resource = &flash_resource, - .num_resources = 1, - .dev = { .platform_data = &flash_data, }, -}; - -#ifdef CONFIG_BOARD_HAMMERHEAD_USB - -static struct smc_timing isp1160_timing __initdata = { - .ncs_read_setup = 75, - .nrd_setup = 75, - .ncs_write_setup = 75, - .nwe_setup = 75, - - - /* We use conservative timing settings, as the minimal settings aren't - stable. There may be room for tweaking. */ - .ncs_read_pulse = 75, /* min. 33ns */ - .nrd_pulse = 75, /* min. 33ns */ - .ncs_write_pulse = 75, /* min. 26ns */ - .nwe_pulse = 75, /* min. 26ns */ - - .read_cycle = 225, /* min. 143ns */ - .write_cycle = 225, /* min. 136ns */ -}; - -static struct smc_config isp1160_config __initdata = { - .bus_width = 2, - .nrd_controlled = 1, - .nwe_controlled = 1, - .byte_write = 0, -}; - -/* - * The platform delay function is only used to enforce the strange - * read to write delay. This can not be configured in the SMC. All other - * timings are controlled by the SMC (see timings obove) - * So in isp116x-hcd.c we should comment out USE_PLATFORM_DELAY - */ -void isp116x_delay(struct device *dev, int delay) -{ - if (delay > 150) - ndelay(delay - 150); -} - -static struct isp116x_platform_data isp1160_data = { - .sel15Kres = 1, /* use internal downstream resistors */ - .oc_enable = 0, /* external overcurrent detection */ - .int_edge_triggered = 0, /* interrupt is level triggered */ - .int_act_high = 0, /* interrupt is active low */ - .delay = isp116x_delay, /* platform delay function */ -}; - -static struct resource isp1160_resource[] = { - { - .start = 0x08000000, - .end = 0x08000001, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x08000002, - .end = 0x08000003, - .flags = IORESOURCE_MEM, - }, - { - .start = 64, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device isp1160_device = { - .name = "isp116x-hcd", - .id = 0, - .resource = isp1160_resource, - .num_resources = 3, - .dev = { - .platform_data = &isp1160_data, - }, -}; -#endif - -#ifdef CONFIG_BOARD_HAMMERHEAD_USB -static int __init hammerhead_usbh_init(void) -{ - struct clk *gclk; - struct clk *osc; - - int ret; - - /* setup smc for usbh */ - smc_set_timing(&isp1160_config, &isp1160_timing); - ret = smc_set_configuration(2, &isp1160_config); - - if (ret < 0) { - printk(KERN_ERR - "hammerhead: failed to set ISP1160 USBH timing\n"); - return ret; - } - - /* setup gclk0 to run from osc1 */ - gclk = clk_get(NULL, "gclk0"); - if (IS_ERR(gclk)) { - ret = PTR_ERR(gclk); - goto err_gclk; - } - - osc = clk_get(NULL, "osc1"); - if (IS_ERR(osc)) { - ret = PTR_ERR(osc); - goto err_osc; - } - - ret = clk_set_parent(gclk, osc); - if (ret < 0) { - pr_debug("hammerhead: failed to set osc1 for USBH clock\n"); - goto err_set_clk; - } - - /* set clock to 6MHz */ - clk_set_rate(gclk, 6000000); - - /* and enable */ - clk_enable(gclk); - - /* select GCLK0 peripheral function */ - at32_select_periph(GPIO_PIOA_BASE, HAMMERHEAD_USB_PERIPH_GCLK0, - GPIO_PERIPH_A, 0); - - /* enable CS2 peripheral function */ - at32_select_periph(GPIO_PIOE_BASE, HAMMERHEAD_USB_PERIPH_CS2, - GPIO_PERIPH_A, 0); - - /* H_WAKEUP must be driven low */ - at32_select_gpio(GPIO_PIN_PA(8), AT32_GPIOF_OUTPUT); - - /* Select EXTINT0 for PB25 */ - at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_USB_PERIPH_EXTINT0, - GPIO_PERIPH_A, 0); - - /* register usbh device driver */ - platform_device_register(&isp1160_device); - - err_set_clk: - clk_put(osc); - err_osc: - clk_put(gclk); - err_gclk: - return ret; -} -#endif - -#ifdef CONFIG_BOARD_HAMMERHEAD_FPGA -static struct smc_timing fpga_timing __initdata = { - .ncs_read_setup = 16, - .nrd_setup = 32, - .ncs_read_pulse = 48, - .nrd_pulse = 32, - .read_cycle = 64, - - .ncs_write_setup = 16, - .nwe_setup = 16, - .ncs_write_pulse = 32, - .nwe_pulse = 32, - .write_cycle = 64, -}; - -static struct smc_config fpga_config __initdata = { - .bus_width = 4, - .nrd_controlled = 1, - .nwe_controlled = 1, - .byte_write = 0, -}; - -static struct resource hh_fpga0_resource[] = { - { - .start = 0xffe00400, - .end = 0xffe00400 + 0x3ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 4, - .end = 4, - .flags = IORESOURCE_IRQ, - }, - { - .start = 0x0c000000, - .end = 0x0c000100, - .flags = IORESOURCE_MEM, - }, - { - .start = 67, - .end = 67, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 hh_fpga0_dma_mask = DMA_BIT_MASK(32); -static struct platform_device hh_fpga0_device = { - .name = "hh_fpga", - .id = 0, - .dev = { - .dma_mask = &hh_fpga0_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .resource = hh_fpga0_resource, - .num_resources = ARRAY_SIZE(hh_fpga0_resource), -}; - -static struct clk hh_fpga0_spi_clk = { - .name = "spi_clk", - .dev = &hh_fpga0_device.dev, - .mode = pba_clk_mode, - .get_rate = pba_clk_get_rate, - .index = 1, -}; - -struct platform_device *__init at32_add_device_hh_fpga(void) -{ - /* Select peripheral functionallity for SPI SCK and MOSI */ - at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_SCK, - GPIO_PERIPH_B, 0); - at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_MOSI, - GPIO_PERIPH_B, 0); - - /* reserve all other needed gpio - * We have on board pull ups, so there is no need - * to enable gpio pull ups */ - /* INIT_DONE (input) */ - at32_select_gpio(GPIO_PIN_PB(0), 0); - - /* nSTATUS (input) */ - at32_select_gpio(GPIO_PIN_PB(2), 0); - - /* nCONFIG (output, low) */ - at32_select_gpio(GPIO_PIN_PB(3), AT32_GPIOF_OUTPUT); - - /* CONF_DONE (input) */ - at32_select_gpio(GPIO_PIN_PB(4), 0); - - /* Select EXTINT3 for PB28 (Interrupt from FPGA) */ - at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_EXTINT3, - GPIO_PERIPH_A, 0); - - /* Get our parent clock */ - hh_fpga0_spi_clk.parent = clk_get(NULL, "pba"); - clk_put(hh_fpga0_spi_clk.parent); - - /* Register clock in at32 clock tree */ - at32_clk_register(&hh_fpga0_spi_clk); - - platform_device_register(&hh_fpga0_device); - return &hh_fpga0_device; -} -#endif - -/* This needs to be called after the SMC has been initialized */ -static int __init hammerhead_flash_init(void) -{ - int ret; - - smc_set_timing(&flash_config, &flash_timing); - ret = smc_set_configuration(0, &flash_config); - - if (ret < 0) { - printk(KERN_ERR "hammerhead: failed to set NOR flash timing\n"); - return ret; - } - - platform_device_register(&flash_device); - -#ifdef CONFIG_BOARD_HAMMERHEAD_USB - hammerhead_usbh_init(); -#endif - -#ifdef CONFIG_BOARD_HAMMERHEAD_FPGA - /* Setup SMC for FPGA interface */ - smc_set_timing(&fpga_config, &fpga_timing); - ret = smc_set_configuration(3, &fpga_config); -#endif - - - if (ret < 0) { - printk(KERN_ERR "hammerhead: failed to set FPGA timing\n"); - return ret; - } - - return 0; -} - -device_initcall(hammerhead_flash_init); diff --git a/arch/avr32/boards/hammerhead/flash.h b/arch/avr32/boards/hammerhead/flash.h deleted file mode 100644 index ea70c626587b..000000000000 --- a/arch/avr32/boards/hammerhead/flash.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __BOARDS_HAMMERHEAD_FLASH_H -#define __BOARDS_HAMMERHEAD_FLASH_H - -struct platform_device *at32_add_device_hh_fpga(void); - -#endif /* __BOARDS_HAMMERHEAD_FLASH_H */ diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c deleted file mode 100644 index dc0e317f2ecd..000000000000 --- a/arch/avr32/boards/hammerhead/setup.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Board-specific setup code for the Miromico Hammerhead board - * - * Copyright (C) 2008 Miromico AG - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/atmel-mci.h> -#include <linux/clk.h> -#include <linux/fb.h> -#include <linux/etherdevice.h> -#include <linux/i2c.h> -#include <linux/i2c-gpio.h> -#include <linux/init.h> -#include <linux/linkage.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/spi/spi.h> - -#include <video/atmel_lcdc.h> - -#include <linux/io.h> -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/board.h> -#include <mach/init.h> -#include <mach/portmux.h> - -#include <sound/atmel-ac97c.h> - -#include "../../mach-at32ap/clock.h" -#include "flash.h" - -/* Oscillator frequencies. These are board-specific */ -unsigned long at32_board_osc_rates[3] = { - [0] = 32768, /* 32.768 kHz on RTC osc */ - [1] = 25000000, /* 25MHz on osc0 */ - [2] = 12000000, /* 12 MHz on osc1 */ -}; - -/* Initialized by bootloader-specific startup code. */ -struct tag *bootloader_tags __initdata; - -#ifdef CONFIG_BOARD_HAMMERHEAD_LCD -static struct fb_videomode __initdata hda350tlv_modes[] = { - { - .name = "320x240 @ 75", - .refresh = 75, - .xres = 320, - .yres = 240, - .pixclock = KHZ2PICOS(6891), - - .left_margin = 48, - .right_margin = 18, - .upper_margin = 18, - .lower_margin = 4, - .hsync_len = 20, - .vsync_len = 2, - - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs __initdata hammerhead_hda350t_monspecs = { - .manufacturer = "HAN", - .monitor = "HDA350T-LV", - .modedb = hda350tlv_modes, - .modedb_len = ARRAY_SIZE(hda350tlv_modes), - .hfmin = 14900, - .hfmax = 22350, - .vfmin = 60, - .vfmax = 90, - .dclkmax = 10000000, -}; - -struct atmel_lcdfb_pdata __initdata hammerhead_lcdc_data = { - .default_bpp = 24, - .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, - .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT - | ATMEL_LCDC_INVCLK - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE - | ATMEL_LCDC_MEMOR_BIG), - .default_monspecs = &hammerhead_hda350t_monspecs, - .guard_time = 2, -}; -#endif - -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = -ENODEV, - .wp_pin = -ENODEV, - }, -}; - -struct eth_addr { - u8 addr[6]; -}; - -static struct eth_addr __initdata hw_addr[1]; -static struct macb_platform_data __initdata eth_data[1]; - -/* - * The next two functions should go away as the boot loader is - * supposed to initialize the macb address registers with a valid - * ethernet address. But we need to keep it around for a while until - * we can be reasonably sure the boot loader does this. - * - * The phy_id is ignored as the driver will probe for it. - */ -static int __init parse_tag_ethernet(struct tag *tag) -{ - int i = tag->u.ethernet.mac_index; - - if (i < ARRAY_SIZE(hw_addr)) - memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, - sizeof(hw_addr[i].addr)); - - return 0; -} -__tagtable(ATAG_ETHERNET, parse_tag_ethernet); - -static void __init set_hw_addr(struct platform_device *pdev) -{ - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - const u8 *addr; - void __iomem *regs; - struct clk *pclk; - - if (!res) - return; - - if (pdev->id >= ARRAY_SIZE(hw_addr)) - return; - - addr = hw_addr[pdev->id].addr; - - if (!is_valid_ether_addr(addr)) - return; - - /* - * Since this is board-specific code, we'll cheat and use the - * physical address directly as we happen to know that it's - * the same as the virtual address. - */ - regs = (void __iomem __force *)res->start; - pclk = clk_get(&pdev->dev, "pclk"); - - if (IS_ERR(pclk)) - return; - - clk_enable(pclk); - - __raw_writel((addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | - addr[0], regs + 0x98); - __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); - - clk_disable(pclk); - clk_put(pclk); -} - -void __init setup_board(void) -{ - at32_map_usart(1, 0, 0); /* USART 1: /dev/ttyS0, DB9 */ - at32_setup_serial_console(0); -} - -static struct i2c_gpio_platform_data i2c_gpio_data = { - .sda_pin = GPIO_PIN_PA(6), - .scl_pin = GPIO_PIN_PA(7), - .sda_is_open_drain = 1, - .scl_is_open_drain = 1, - .udelay = 2, /* close to 100 kHz */ -}; - -static struct platform_device i2c_gpio_device = { - .name = "i2c-gpio", - .id = 0, - .dev = { .platform_data = &i2c_gpio_data, }, -}; - -static struct i2c_board_info __initdata i2c_info[] = {}; - -#ifdef CONFIG_BOARD_HAMMERHEAD_SND -static struct ac97c_platform_data ac97c_data = { - .reset_pin = GPIO_PIN_PA(16), -}; -#endif - -static int __init hammerhead_init(void) -{ - /* - * Hammerhead uses 32-bit SDRAM interface. Reserve the - * SDRAM-specific pins so that nobody messes with them. - */ - at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); - - at32_add_device_usart(0); - - /* Reserve PB29 (GCLK3). This pin is used as clock source - * for ETH PHY (25MHz). GCLK3 setup is done by U-Boot. - */ - at32_reserve_pin(GPIO_PIOB_BASE, (1<<29)); - - /* - * Hammerhead uses only one ethernet port, so we don't set - * address of second port - */ - set_hw_addr(at32_add_device_eth(0, ð_data[0])); - -#ifdef CONFIG_BOARD_HAMMERHEAD_FPGA - at32_add_device_hh_fpga(); -#endif - at32_add_device_mci(0, &mci0_data); - -#ifdef CONFIG_BOARD_HAMMERHEAD_USB - at32_add_device_usba(0, NULL); -#endif -#ifdef CONFIG_BOARD_HAMMERHEAD_LCD - at32_add_device_lcdc(0, &hammerhead_lcdc_data, fbmem_start, - fbmem_size, ATMEL_LCDC_PRI_24BIT); -#endif - - at32_select_gpio(i2c_gpio_data.sda_pin, - AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | - AT32_GPIOF_HIGH); - at32_select_gpio(i2c_gpio_data.scl_pin, - AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | - AT32_GPIOF_HIGH); - platform_device_register(&i2c_gpio_device); - i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info)); - -#ifdef CONFIG_BOARD_HAMMERHEAD_SND - at32_add_device_ac97c(0, &ac97c_data, AC97C_BOTH); -#endif - - /* Select the Touchscreen interrupt pin mode */ - at32_select_periph(GPIO_PIOB_BASE, 0x08000000, GPIO_PERIPH_A, 0); - - return 0; -} - -postcore_initcall(hammerhead_init); diff --git a/arch/avr32/boards/merisc/Kconfig b/arch/avr32/boards/merisc/Kconfig deleted file mode 100644 index 7e043275d5a9..000000000000 --- a/arch/avr32/boards/merisc/Kconfig +++ /dev/null @@ -1,5 +0,0 @@ -# Merisc customization - -if BOARD_MERISC - -endif # BOARD_MERISC diff --git a/arch/avr32/boards/merisc/Makefile b/arch/avr32/boards/merisc/Makefile deleted file mode 100644 index d24c78729bd1..000000000000 --- a/arch/avr32/boards/merisc/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y += setup.o flash.o display.o merisc_sysfs.o diff --git a/arch/avr32/boards/merisc/display.c b/arch/avr32/boards/merisc/display.c deleted file mode 100644 index e7683ee7ed40..000000000000 --- a/arch/avr32/boards/merisc/display.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Display setup code for the Merisc board - * - * Copyright (C) 2008 Martinsson Elektronik AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/fb.h> -#include <video/atmel_lcdc.h> -#include <asm/setup.h> -#include <mach/board.h> -#include "merisc.h" - -static struct fb_videomode merisc_fb_videomode[] = { - { - .refresh = 44, - .xres = 640, - .yres = 480, - .left_margin = 96, - .right_margin = 96, - .upper_margin = 34, - .lower_margin = 8, - .hsync_len = 64, - .vsync_len = 64, - .name = "640x480 @ 44", - .pixclock = KHZ2PICOS(25180), - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs merisc_fb_monspecs = { - .manufacturer = "Kyo", - .monitor = "TCG075VG2AD", - .modedb = merisc_fb_videomode, - .modedb_len = ARRAY_SIZE(merisc_fb_videomode), - .hfmin = 30000, - .hfmax = 33333, - .vfmin = 60, - .vfmax = 90, - .dclkmax = 30000000, -}; - -struct atmel_lcdfb_pdata merisc_lcdc_data = { - .default_bpp = 24, - .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, - .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE - | ATMEL_LCDC_MEMOR_BIG), - .default_monspecs = &merisc_fb_monspecs, - .guard_time = 2, -}; - -static int __init merisc_display_init(void) -{ - at32_add_device_lcdc(0, &merisc_lcdc_data, fbmem_start, - fbmem_size, 0); - - return 0; -} -device_initcall(merisc_display_init); diff --git a/arch/avr32/boards/merisc/flash.c b/arch/avr32/boards/merisc/flash.c deleted file mode 100644 index 8e856fd6f013..000000000000 --- a/arch/avr32/boards/merisc/flash.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Merisc board-specific flash initialization - * - * Copyright (C) 2008 Martinsson Elektronik AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> -#include <mach/smc.h> - -/* Will be translated to units of 14.3 ns, rounded up */ -static struct smc_timing flash_timing __initdata = { - .ncs_read_setup = 1 * 14, - .nrd_setup = 5 * 14, - .ncs_write_setup = 1 * 14, - .nwe_setup = 2 * 14, - - .ncs_read_pulse = 12 * 14, - .nrd_pulse = 7 * 14, - .ncs_write_pulse = 8 * 14, - .nwe_pulse = 4 * 14, - - .read_cycle = 14 * 14, - .write_cycle = 10 * 14, -}; - -static struct smc_config flash_config __initdata = { - .bus_width = 2, - .nrd_controlled = 1, - .nwe_controlled = 1, - .byte_write = 1, - .tdf_cycles = 3, -}; - -static struct mtd_partition flash_0_parts[] = { - { - .name = "boot", - .offset = 0x00000000, - .size = 0x00060000, - .mask_flags = 0, - }, - { - .name = "kernel", - .offset = 0x00060000, - .size = 0x00200000, - .mask_flags = 0, - }, - { - .name = "root", - .offset = 0x00260000, - .size = MTDPART_SIZ_FULL, - .mask_flags = 0, - }, -}; - -static struct mtd_partition flash_1_parts[] = { - { - .name = "2ndflash", - .offset = 0x00000000, - .size = MTDPART_SIZ_FULL, - .mask_flags = 0, - }, -}; - -static struct physmap_flash_data flash_data[] = { - { - .width = 2, - .nr_parts = ARRAY_SIZE(flash_0_parts), - .parts = flash_0_parts, - }, - { - .width = 2, - .nr_parts = ARRAY_SIZE(flash_1_parts), - .parts = flash_1_parts, - } -}; - -static struct resource flash_resource[] = { - { - .start = 0x00000000, - .end = 0x03ffffff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0x04000000, - .end = 0x07ffffff, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device flash_device[] = { - { - .name = "physmap-flash", - .id = 0, - .resource = &flash_resource[0], - .num_resources = 1, - .dev = { - .platform_data = &flash_data[0], - }, - }, - { - .name = "physmap-flash", - .id = 1, - .resource = &flash_resource[1], - .num_resources = 1, - .dev = { - .platform_data = &flash_data[1], - }, - }, -}; - -static int __init merisc_flash_init(void) -{ - int ret; - smc_set_timing(&flash_config, &flash_timing); - - ret = smc_set_configuration(0, &flash_config); - if (ret < 0) { - printk(KERN_ERR "Merisc: failed to set NOR flash timing #0\n"); - return ret; - } - - ret = smc_set_configuration(4, &flash_config); - if (ret < 0) { - printk(KERN_ERR "Merisc: failed to set NOR flash timing #1\n"); - return ret; - } - - platform_device_register(&flash_device[0]); - platform_device_register(&flash_device[1]); - return 0; -} -device_initcall(merisc_flash_init); diff --git a/arch/avr32/boards/merisc/merisc.h b/arch/avr32/boards/merisc/merisc.h deleted file mode 100644 index 50ffb2f3fcbf..000000000000 --- a/arch/avr32/boards/merisc/merisc.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Merisc exports - * - * Copyright (C) 2008 Martinsson Elektronik AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ARCH_AVR32_BOARDS_MERISC_MERISC_H -#define __ARCH_AVR32_BOARDS_MERISC_MERISC_H - -const char *merisc_revision(void); -const char *merisc_model(void); - -extern struct class merisc_class; - -#endif /* __ARCH_AVR32_BOARDS_MERISC_MERISC_H */ diff --git a/arch/avr32/boards/merisc/merisc_sysfs.c b/arch/avr32/boards/merisc/merisc_sysfs.c deleted file mode 100644 index 5a252318f4bd..000000000000 --- a/arch/avr32/boards/merisc/merisc_sysfs.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Merisc sysfs exports - * - * Copyright (C) 2008 Martinsson Elektronik AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/list.h> -#include <linux/spinlock.h> -#include <linux/device.h> -#include <linux/timer.h> -#include <linux/err.h> -#include <linux/ctype.h> -#include "merisc.h" - -static ssize_t merisc_model_show(struct class *class, char *buf) -{ - ssize_t ret = 0; - - sprintf(buf, "%s\n", merisc_model()); - ret = strlen(buf) + 1; - - return ret; -} - -static ssize_t merisc_revision_show(struct class *class, char *buf) -{ - ssize_t ret = 0; - - sprintf(buf, "%s\n", merisc_revision()); - ret = strlen(buf) + 1; - - return ret; -} - -static struct class_attribute merisc_class_attrs[] = { - __ATTR(model, S_IRUGO, merisc_model_show, NULL), - __ATTR(revision, S_IRUGO, merisc_revision_show, NULL), - __ATTR_NULL, -}; - -struct class merisc_class = { - .name = "merisc", - .owner = THIS_MODULE, - .class_attrs = merisc_class_attrs, -}; - -static int __init merisc_sysfs_init(void) -{ - int status; - - status = class_register(&merisc_class); - if (status < 0) - return status; - - return 0; -} - -postcore_initcall(merisc_sysfs_init); diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c deleted file mode 100644 index 718a6d7eb808..000000000000 --- a/arch/avr32/boards/merisc/setup.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Board-specific setup code for the Merisc - * - * Copyright (C) 2008 Martinsson Elektronik AB - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/etherdevice.h> -#include <linux/i2c.h> -#include <linux/i2c-gpio.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/linkage.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/leds.h> -#include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> -#include <linux/irq.h> -#include <linux/fb.h> -#include <linux/atmel-mci.h> -#include <linux/pwm.h> -#include <linux/leds_pwm.h> - -#include <asm/io.h> -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/board.h> -#include <mach/init.h> -#include <mach/portmux.h> - -#include "merisc.h" - -/* Holds the autodetected board model and revision */ -static int merisc_board_id; - -/* Initialized by bootloader-specific startup code. */ -struct tag *bootloader_tags __initdata; - -/* Oscillator frequencies. These are board specific */ -unsigned long at32_board_osc_rates[3] = { - [0] = 32768, /* 32.768 kHz on RTC osc */ - [1] = 20000000, /* 20 MHz on osc0 */ - [2] = 12000000, /* 12 MHz on osc1 */ -}; - -struct eth_addr { - u8 addr[6]; -}; - -static struct eth_addr __initdata hw_addr[2]; -static struct macb_platform_data __initdata eth_data[2]; - -static int ads7846_get_pendown_state_PB26(void) -{ - return !gpio_get_value(GPIO_PIN_PB(26)); -} - -static int ads7846_get_pendown_state_PB28(void) -{ - return !gpio_get_value(GPIO_PIN_PB(28)); -} - -static struct ads7846_platform_data __initdata ads7846_data = { - .model = 7846, - .vref_delay_usecs = 100, - .vref_mv = 0, - .keep_vref_on = 0, - .settle_delay_usecs = 150, - .penirq_recheck_delay_usecs = 1, - .x_plate_ohms = 800, - .debounce_rep = 4, - .debounce_max = 10, - .debounce_tol = 50, - .get_pendown_state = ads7846_get_pendown_state_PB26, - .filter_init = NULL, - .filter = NULL, - .filter_cleanup = NULL, -}; - -static struct spi_board_info __initdata spi0_board_info[] = { - { - .modalias = "ads7846", - .max_speed_hz = 3250000, - .chip_select = 0, - .bus_num = 0, - .platform_data = &ads7846_data, - .mode = SPI_MODE_0, - }, -}; - -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = GPIO_PIN_PE(19), - .wp_pin = GPIO_PIN_PE(20), - .detect_is_active_high = true, - }, -}; - -static int __init parse_tag_ethernet(struct tag *tag) -{ - int i; - - i = tag->u.ethernet.mac_index; - if (i < ARRAY_SIZE(hw_addr)) { - memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, - sizeof(hw_addr[i].addr)); - } - - return 0; -} -__tagtable(ATAG_ETHERNET, parse_tag_ethernet); - -static void __init set_hw_addr(struct platform_device *pdev) -{ - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - const u8 *addr; - void __iomem *regs; - struct clk *pclk; - - if (!res) - return; - - if (pdev->id >= ARRAY_SIZE(hw_addr)) - return; - - addr = hw_addr[pdev->id].addr; - if (!is_valid_ether_addr(addr)) - return; - - regs = (void __iomem __force *)res->start; - pclk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(pclk)) - return; - - clk_enable(pclk); - __raw_writel((addr[3] << 24) | (addr[2] << 16) - | (addr[1] << 8) | addr[0], regs + 0x98); - __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); - clk_disable(pclk); - clk_put(pclk); -} - -static struct i2c_gpio_platform_data i2c_gpio_data = { - .sda_pin = GPIO_PIN_PA(6), - .scl_pin = GPIO_PIN_PA(7), - .sda_is_open_drain = 1, - .scl_is_open_drain = 1, - .udelay = 2, -}; - -static struct platform_device i2c_gpio_device = { - .name = "i2c-gpio", - .id = 0, - .dev = { - .platform_data = &i2c_gpio_data, - }, -}; - -static struct i2c_board_info __initdata i2c_info[] = { - { - I2C_BOARD_INFO("pcf8563", 0x51) - }, -}; - -#if IS_ENABLED(CONFIG_LEDS_PWM) -static struct pwm_lookup pwm_lookup[] = { - PWM_LOOKUP("at91sam9rl-pwm", 0, "leds_pwm", "backlight", - 5000, PWM_POLARITY_NORMAL), -}; - -static struct led_pwm pwm_leds[] = { - { - .name = "backlight", - .max_brightness = 255, - }, -}; - -static struct led_pwm_platform_data pwm_data = { - .num_leds = ARRAY_SIZE(pwm_leds), - .leds = pwm_leds, -}; - -static struct platform_device leds_pwm = { - .name = "leds_pwm", - .id = -1, - .dev = { - .platform_data = &pwm_data, - }, -}; -#endif - -const char *merisc_model(void) -{ - switch (merisc_board_id) { - case 0: - case 1: - return "500-01"; - case 2: - return "BT"; - default: - return "Unknown"; - } -} - -const char *merisc_revision(void) -{ - switch (merisc_board_id) { - case 0: - return "B"; - case 1: - return "D"; - case 2: - return "A"; - default: - return "Unknown"; - } -} - -static void detect_merisc_board_id(void) -{ - /* Board ID pins MUST be set as input or the board may be damaged */ - at32_select_gpio(GPIO_PIN_PA(24), AT32_GPIOF_PULLUP); - at32_select_gpio(GPIO_PIN_PA(25), AT32_GPIOF_PULLUP); - at32_select_gpio(GPIO_PIN_PA(26), AT32_GPIOF_PULLUP); - at32_select_gpio(GPIO_PIN_PA(27), AT32_GPIOF_PULLUP); - - merisc_board_id = !gpio_get_value(GPIO_PIN_PA(24)) + - !gpio_get_value(GPIO_PIN_PA(25)) * 2 + - !gpio_get_value(GPIO_PIN_PA(26)) * 4 + - !gpio_get_value(GPIO_PIN_PA(27)) * 8; -} - -void __init setup_board(void) -{ - at32_map_usart(0, 0, 0); - at32_map_usart(1, 1, 0); - at32_map_usart(3, 3, 0); - at32_setup_serial_console(1); -} - -static int __init merisc_init(void) -{ - detect_merisc_board_id(); - - printk(KERN_NOTICE "BOARD: Merisc %s revision %s\n", merisc_model(), - merisc_revision()); - - /* Reserve pins for SDRAM */ - at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL | (1 << 26)); - - if (merisc_board_id >= 1) - at32_map_usart(2, 2, 0); - - at32_add_device_usart(0); - at32_add_device_usart(1); - if (merisc_board_id >= 1) - at32_add_device_usart(2); - at32_add_device_usart(3); - set_hw_addr(at32_add_device_eth(0, ð_data[0])); - - /* ADS7846 PENIRQ */ - if (merisc_board_id == 0) { - ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB26; - at32_select_periph(GPIO_PIOB_BASE, 1 << 26, - GPIO_PERIPH_A, AT32_GPIOF_PULLUP); - spi0_board_info[0].irq = AT32_EXTINT(1); - } else { - ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB28; - at32_select_periph(GPIO_PIOB_BASE, 1 << 28, GPIO_PERIPH_A, - AT32_GPIOF_PULLUP); - spi0_board_info[0].irq = AT32_EXTINT(3); - } - - /* ADS7846 busy pin */ - at32_select_gpio(GPIO_PIN_PA(4), AT32_GPIOF_PULLUP); - - at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); - - at32_add_device_mci(0, &mci0_data); - -#if IS_ENABLED(CONFIG_LEDS_PWM) - pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup)); - at32_add_device_pwm((1 << 0) | (1 << 2)); - platform_device_register(&leds_pwm); -#else - at32_add_device_pwm((1 << 2)); -#endif - - at32_select_gpio(i2c_gpio_data.sda_pin, - AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(i2c_gpio_data.scl_pin, - AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - platform_device_register(&i2c_gpio_device); - - i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info)); - - return 0; -} -postcore_initcall(merisc_init); diff --git a/arch/avr32/boards/mimc200/Makefile b/arch/avr32/boards/mimc200/Makefile deleted file mode 100644 index c740aa116755..000000000000 --- a/arch/avr32/boards/mimc200/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y += setup.o flash.o diff --git a/arch/avr32/boards/mimc200/flash.c b/arch/avr32/boards/mimc200/flash.c deleted file mode 100644 index d83d650fc13f..000000000000 --- a/arch/avr32/boards/mimc200/flash.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * MIMC200 board-specific flash initialization - * - * Copyright (C) 2008 Mercury IMC Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> - -#include <mach/smc.h> - -static struct smc_timing flash_timing __initdata = { - .ncs_read_setup = 0, - .nrd_setup = 15, - .ncs_write_setup = 0, - .nwe_setup = 0, - - .ncs_read_pulse = 115, - .nrd_pulse = 110, - .ncs_write_pulse = 60, - .nwe_pulse = 60, - - .read_cycle = 115, - .write_cycle = 100, -}; - -static struct smc_config flash_config __initdata = { - .bus_width = 2, - .nrd_controlled = 1, - .nwe_controlled = 1, - .byte_write = 1, -}; - -/* system flash definition */ - -static struct mtd_partition flash_parts_system[] = { - { - .name = "u-boot", - .offset = 0x00000000, - .size = 0x00020000, /* 128 KiB */ - .mask_flags = MTD_WRITEABLE, - }, - { - .name = "root", - .offset = 0x00020000, - .size = 0x007c0000, - }, - { - .name = "splash", - .offset = 0x007e0000, - .size = 0x00010000, /* 64KiB */ - }, - { - .name = "env", - .offset = 0x007f0000, - .size = 0x00010000, - .mask_flags = MTD_WRITEABLE, - }, -}; - -static struct physmap_flash_data flash_system = { - .width = 2, - .nr_parts = ARRAY_SIZE(flash_parts_system), - .parts = flash_parts_system, -}; - -static struct resource flash_resource_system = { - .start = 0x00000000, - .end = 0x007fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device flash_device_system = { - .name = "physmap-flash", - .id = 0, - .resource = &flash_resource_system, - .num_resources = 1, - .dev = { - .platform_data = &flash_system, - }, -}; - -/* data flash definition */ - -static struct mtd_partition flash_parts_data[] = { - { - .name = "data", - .offset = 0x00000000, - .size = 0x00800000, - }, -}; - -static struct physmap_flash_data flash_data = { - .width = 2, - .nr_parts = ARRAY_SIZE(flash_parts_data), - .parts = flash_parts_data, -}; - -static struct resource flash_resource_data = { - .start = 0x08000000, - .end = 0x087fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device flash_device_data = { - .name = "physmap-flash", - .id = 1, - .resource = &flash_resource_data, - .num_resources = 1, - .dev = { - .platform_data = &flash_data, - }, -}; - -/* This needs to be called after the SMC has been initialized */ -static int __init mimc200_flash_init(void) -{ - int ret; - - smc_set_timing(&flash_config, &flash_timing); - ret = smc_set_configuration(0, &flash_config); - if (ret < 0) { - printk(KERN_ERR "mimc200: failed to set 'System' NOR flash timing\n"); - return ret; - } - ret = smc_set_configuration(1, &flash_config); - if (ret < 0) { - printk(KERN_ERR "mimc200: failed to set 'Data' NOR flash timing\n"); - return ret; - } - - platform_device_register(&flash_device_system); - platform_device_register(&flash_device_data); - - return 0; -} -device_initcall(mimc200_flash_init); diff --git a/arch/avr32/boards/mimc200/setup.c b/arch/avr32/boards/mimc200/setup.c deleted file mode 100644 index 1cb8e9cc5cfa..000000000000 --- a/arch/avr32/boards/mimc200/setup.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Board-specific setup code for the MIMC200 - * - * Copyright (C) 2008 Mercury IMC Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -extern struct atmel_lcdfb_pdata mimc200_lcdc_data; - -#include <linux/clk.h> -#include <linux/etherdevice.h> -#include <linux/i2c-gpio.h> -#include <linux/init.h> -#include <linux/linkage.h> -#include <linux/platform_device.h> -#include <linux/types.h> -#include <linux/leds.h> -#include <linux/spi/spi.h> -#include <linux/spi/eeprom.h> - -#include <video/atmel_lcdc.h> -#include <linux/fb.h> - -#include <linux/atmel-mci.h> -#include <linux/io.h> -#include <asm/setup.h> - -#include <mach/at32ap700x.h> -#include <mach/board.h> -#include <mach/init.h> -#include <mach/portmux.h> - -/* Oscillator frequencies. These are board-specific */ -unsigned long at32_board_osc_rates[3] = { - [0] = 32768, /* 32.768 kHz on RTC osc */ - [1] = 10000000, /* 10 MHz on osc0 */ - [2] = 12000000, /* 12 MHz on osc1 */ -}; - -/* Initialized by bootloader-specific startup code. */ -struct tag *bootloader_tags __initdata; - -static struct fb_videomode __initdata pt0434827_modes[] = { - { - .name = "480x272 @ 72", - .refresh = 72, - .xres = 480, .yres = 272, - .pixclock = KHZ2PICOS(10000), - - .left_margin = 1, .right_margin = 1, - .upper_margin = 12, .lower_margin = 1, - .hsync_len = 42, .vsync_len = 1, - - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - }, -}; - -static struct fb_monspecs __initdata mimc200_default_monspecs = { - .manufacturer = "PT", - .monitor = "PT0434827-A401", - .modedb = pt0434827_modes, - .modedb_len = ARRAY_SIZE(pt0434827_modes), - .hfmin = 14820, - .hfmax = 22230, - .vfmin = 60, - .vfmax = 85, - .dclkmax = 25200000, -}; - -struct atmel_lcdfb_pdata __initdata mimc200_lcdc_data = { - .default_bpp = 16, - .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, - .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT - | ATMEL_LCDC_INVCLK - | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE - | ATMEL_LCDC_MEMOR_BIG), - .default_monspecs = &mimc200_default_monspecs, - .guard_time = 2, -}; - -struct eth_addr { - u8 addr[6]; -}; -static struct eth_addr __initdata hw_addr[2]; -static struct macb_platform_data __initdata eth_data[2]; - -static struct spi_eeprom eeprom_25lc010 = { - .name = "25lc010", - .byte_len = 128, - .page_size = 16, - .flags = EE_ADDR1, -}; - -static struct spi_board_info spi0_board_info[] __initdata = { - { - .modalias = "rtc-ds1390", - .max_speed_hz = 4000000, - .chip_select = 2, - }, - { - .modalias = "at25", - .max_speed_hz = 1000000, - .chip_select = 1, - .mode = SPI_MODE_3, - .platform_data = &eeprom_25lc010, - }, -}; - -static struct mci_platform_data __initdata mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = GPIO_PIN_PA(26), - .wp_pin = GPIO_PIN_PA(27), - }, -}; - -/* - * The next two functions should go away as the boot loader is - * supposed to initialize the macb address registers with a valid - * ethernet address. But we need to keep it around for a while until - * we can be reasonably sure the boot loader does this. - * - * The phy_id is ignored as the driver will probe for it. - */ -static int __init parse_tag_ethernet(struct tag *tag) -{ - int i; - - i = tag->u.ethernet.mac_index; - if (i < ARRAY_SIZE(hw_addr)) - memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, - sizeof(hw_addr[i].addr)); - - return 0; -} -__tagtable(ATAG_ETHERNET, parse_tag_ethernet); - -static void __init set_hw_addr(struct platform_device *pdev) -{ - struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - const u8 *addr; - void __iomem *regs; - struct clk *pclk; - - if (!res) - return; - if (pdev->id >= ARRAY_SIZE(hw_addr)) - return; - - addr = hw_addr[pdev->id].addr; - if (!is_valid_ether_addr(addr)) - return; - - /* - * Since this is board-specific code, we'll cheat and use the - * physical address directly as we happen to know that it's - * the same as the virtual address. - */ - regs = (void __iomem __force *)res->start; - pclk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(pclk)) - return; - - clk_enable(pclk); - __raw_writel((addr[3] << 24) | (addr[2] << 16) - | (addr[1] << 8) | addr[0], regs + 0x98); - __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); - clk_disable(pclk); - clk_put(pclk); -} - -void __init setup_board(void) -{ - at32_map_usart(0, 0, 0); /* USART 0: /dev/ttyS0 (TTL --> Altera) */ - at32_map_usart(1, 1, 0); /* USART 1: /dev/ttyS1 (RS232) */ - at32_map_usart(2, 2, 0); /* USART 2: /dev/ttyS2 (RS485) */ - at32_map_usart(3, 3, 0); /* USART 3: /dev/ttyS3 (RS422 Multidrop) */ -} - -static struct i2c_gpio_platform_data i2c_gpio_data = { - .sda_pin = GPIO_PIN_PA(6), - .scl_pin = GPIO_PIN_PA(7), - .sda_is_open_drain = 1, - .scl_is_open_drain = 1, - .udelay = 2, /* close to 100 kHz */ -}; - -static struct platform_device i2c_gpio_device = { - .name = "i2c-gpio", - .id = 0, - .dev = { - .platform_data = &i2c_gpio_data, - }, -}; - -static struct i2c_board_info __initdata i2c_info[] = { -}; - -static int __init mimc200_init(void) -{ - /* - * MIMC200 uses 16-bit SDRAM interface, so we don't need to - * reserve any pins for it. - */ - - at32_add_device_usart(0); - at32_add_device_usart(1); - at32_add_device_usart(2); - at32_add_device_usart(3); - - set_hw_addr(at32_add_device_eth(0, ð_data[0])); - set_hw_addr(at32_add_device_eth(1, ð_data[1])); - - at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); - at32_add_device_mci(0, &mci0_data); - at32_add_device_usba(0, NULL); - - at32_select_periph(GPIO_PIOB_BASE, 1 << 28, 0, AT32_GPIOF_PULLUP); - at32_select_gpio(i2c_gpio_data.sda_pin, - AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(i2c_gpio_data.scl_pin, - AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - platform_device_register(&i2c_gpio_device); - i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info)); - - at32_add_device_lcdc(0, &mimc200_lcdc_data, - fbmem_start, fbmem_size, - ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_CONTROL | ATMEL_LCDC_ALT_24B_DATA); - - return 0; -} -postcore_initcall(mimc200_init); diff --git a/arch/avr32/boot/images/.gitignore b/arch/avr32/boot/images/.gitignore deleted file mode 100644 index 64ea9d0141d2..000000000000 --- a/arch/avr32/boot/images/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -uImage -uImage.srec -vmlinux.cso -sfdwarf.log diff --git a/arch/avr32/boot/images/Makefile b/arch/avr32/boot/images/Makefile deleted file mode 100644 index 2a3b53978a3b..000000000000 --- a/arch/avr32/boot/images/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# -# Copyright (C) 2004-2006 Atmel Corporation -# -# 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. -# - -extra-y := vmlinux.bin vmlinux.gz - -OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note.gnu.build-id -$(obj)/vmlinux.bin: vmlinux FORCE - $(call if_changed,objcopy) - -$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE - $(call if_changed,gzip) - -UIMAGE_LOADADDR = $(CONFIG_LOAD_ADDRESS) -UIMAGE_ENTRYADDR = $(CONFIG_ENTRY_ADDRESS) -UIMAGE_COMPRESSION = gzip - -targets += uImage uImage.srec -$(obj)/uImage: $(obj)/vmlinux.gz - $(call if_changed,uimage) - @echo ' Image $@ is ready' - -OBJCOPYFLAGS_uImage.srec := -I binary -O srec -$(obj)/uImage.srec: $(obj)/uImage - $(call if_changed,objcopy) - -OBJCOPYFLAGS_vmlinux.elf := --change-section-lma .text-0x80000000 \ - --change-section-lma __ex_table-0x80000000 \ - --change-section-lma .rodata-0x80000000 \ - --change-section-lma .data-0x80000000 \ - --change-section-lma .init-0x80000000 \ - --change-section-lma .bss-0x80000000 \ - --change-section-lma __param-0x80000000 \ - --change-section-lma __ksymtab-0x80000000 \ - --change-section-lma __ksymtab_gpl-0x80000000 \ - --change-section-lma __kcrctab-0x80000000 \ - --change-section-lma __kcrctab_gpl-0x80000000 \ - --change-section-lma __ksymtab_strings-0x80000000 \ - --set-start 0xa0000000 -$(obj)/vmlinux.elf: vmlinux FORCE - $(call if_changed,objcopy) - -quiet_cmd_sfdwarf = SFDWARF $@ - cmd_sfdwarf = sfdwarf $< TO $@ GNUAVR IW $(SFDWARF_FLAGS) > $(obj)/sfdwarf.log - -$(obj)/vmlinux.cso: $(obj)/vmlinux.elf FORCE - $(call if_changed,sfdwarf) - -install: $(BOOTIMAGE) - sh $(srctree)/install-kernel.sh $< - -# Generated files to be removed upon make clean -clean-files := vmlinux.elf vmlinux.bin vmlinux.gz uImage uImage.srec diff --git a/arch/avr32/boot/u-boot/Makefile b/arch/avr32/boot/u-boot/Makefile deleted file mode 100644 index 125ddc96c275..000000000000 --- a/arch/avr32/boot/u-boot/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -extra-y := head.o - -obj-y := empty.o diff --git a/arch/avr32/boot/u-boot/empty.S b/arch/avr32/boot/u-boot/empty.S deleted file mode 100644 index 8ac91a5f12f0..000000000000 --- a/arch/avr32/boot/u-boot/empty.S +++ /dev/null @@ -1 +0,0 @@ -/* Empty file */ diff --git a/arch/avr32/boot/u-boot/head.S b/arch/avr32/boot/u-boot/head.S deleted file mode 100644 index 2ffc298f061b..000000000000 --- a/arch/avr32/boot/u-boot/head.S +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Startup code for use with the u-boot bootloader. - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <asm/setup.h> -#include <asm/thread_info.h> -#include <asm/sysreg.h> - - /* - * The kernel is loaded where we want it to be and all caches - * have just been flushed. We get two parameters from u-boot: - * - * r12 contains a magic number (ATAG_MAGIC) - * r11 points to a tag table providing information about - * the system. - */ - .section .init.text,"ax" - .global _start -_start: - /* Initialize .bss */ - lddpc r2, bss_start_addr - lddpc r3, end_addr - mov r0, 0 - mov r1, 0 -1: st.d r2++, r0 - cp r2, r3 - brlo 1b - - /* Initialize status register */ - lddpc r0, init_sr - mtsr SYSREG_SR, r0 - - /* Set initial stack pointer */ - lddpc sp, stack_addr - sub sp, -THREAD_SIZE - -#ifdef CONFIG_FRAME_POINTER - /* Mark last stack frame */ - mov lr, 0 - mov r7, 0 -#endif - - /* Check if the boot loader actually provided a tag table */ - lddpc r0, magic_number - cp.w r12, r0 - brne no_tag_table - - /* - * Save the tag table address for later use. This must be done - * _after_ .bss has been initialized... - */ - lddpc r0, tag_table_addr - st.w r0[0], r11 - - /* Jump to loader-independent setup code */ - rjmp kernel_entry - - .align 2 -magic_number: - .long ATAG_MAGIC -tag_table_addr: - .long bootloader_tags -bss_start_addr: - .long __bss_start -end_addr: - .long _end -init_sr: - .long 0x007f0000 /* Supervisor mode, everything masked */ -stack_addr: - .long init_thread_union -panic_addr: - .long panic - -no_tag_table: - sub r12, pc, (. - 2f) - /* branch to panic() which can be far away with that construct */ - lddpc pc, panic_addr -2: .asciz "Boot loader didn't provide correct magic number\n" diff --git a/arch/avr32/configs/atngw100_defconfig b/arch/avr32/configs/atngw100_defconfig deleted file mode 100644 index ce0030020c25..000000000000 --- a/arch/avr32/configs/atngw100_defconfig +++ /dev/null @@ -1,142 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_ATNGW100_MKI=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_ADVANCED is not set -CONFIG_NETFILTER_XTABLES=y -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_NETDEVICES=y -CONFIG_TUN=m -CONFIG_MACB=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_VBUS_DRAW=350 -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_TEST=m -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_UBIFS_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_CIFS=m -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/avr32/configs/atngw100_evklcd100_defconfig b/arch/avr32/configs/atngw100_evklcd100_defconfig deleted file mode 100644 index 01ff632249c0..000000000000 --- a/arch/avr32/configs/atngw100_evklcd100_defconfig +++ /dev/null @@ -1,158 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_ATNGW100_MKI=y -CONFIG_BOARD_ATNGW100_EVKLCD10X=y -CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_ADVANCED is not set -CONFIG_NETFILTER_XTABLES=y -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_NETDEVICES=y -CONFIG_TUN=m -CONFIG_MACB=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_WM97XX=m -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_HRTIMER=y -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_ATMEL_AC97C=m -# CONFIG_SND_SPI is not set -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_VBUS_DRAW=350 -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_TEST=m -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_UBIFS_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_CIFS=m -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/avr32/configs/atngw100_evklcd101_defconfig b/arch/avr32/configs/atngw100_evklcd101_defconfig deleted file mode 100644 index c4021dfd5347..000000000000 --- a/arch/avr32/configs/atngw100_evklcd101_defconfig +++ /dev/null @@ -1,157 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_ATNGW100_MKI=y -CONFIG_BOARD_ATNGW100_EVKLCD10X=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_ADVANCED is not set -CONFIG_NETFILTER_XTABLES=y -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_NETDEVICES=y -CONFIG_TUN=m -CONFIG_MACB=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_WM97XX=m -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_HRTIMER=y -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_ATMEL_AC97C=m -# CONFIG_SND_SPI is not set -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_VBUS_DRAW=350 -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_TEST=m -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_UBIFS_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_CIFS=m -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/avr32/configs/atngw100_mrmt_defconfig b/arch/avr32/configs/atngw100_mrmt_defconfig deleted file mode 100644 index ffcc28df9dbc..000000000000 --- a/arch/avr32/configs/atngw100_mrmt_defconfig +++ /dev/null @@ -1,136 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_SLUB_DEBUG is not set -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_OWNERSHIP_TRACE is not set -# CONFIG_SUSPEND is not set -CONFIG_PM=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_SYN_COOKIES=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_IPV6 is not set -CONFIG_BT=m -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_HIDP=m -CONFIG_BT_HCIUART=m -CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_BCSP=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_NETDEVICES=y -CONFIG_MACB=y -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=m -# CONFIG_SERIO is not set -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=y -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_VERBOSE_PROCFS is not set -CONFIG_SND_ATMEL_AC97C=m -# CONFIG_SND_SPI is not set -CONFIG_USB_GADGET=m -CONFIG_USB_GADGET_DEBUG_FILES=y -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_MMC=y -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_PWM=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_S35390A=m -CONFIG_RTC_DRV_AT32AP700X=m -CONFIG_DMADEVICES=y -CONFIG_UIO=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_DNOTIFY is not set -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_NTFS_FS=m -CONFIG_NTFS_RW=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_CIFS=m -CONFIG_CIFS_STATS=y -CONFIG_CIFS_WEAK_PW_HASH=y -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=y -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_CRC_CCITT=y diff --git a/arch/avr32/configs/atngw100mkii_defconfig b/arch/avr32/configs/atngw100mkii_defconfig deleted file mode 100644 index 04962641c936..000000000000 --- a/arch/avr32/configs/atngw100mkii_defconfig +++ /dev/null @@ -1,144 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_ATNGW100_MKII=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_ADVANCED is not set -CONFIG_NETFILTER_XTABLES=y -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_NETDEVICES=y -CONFIG_TUN=m -CONFIG_MACB=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_VBUS_DRAW=350 -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_TEST=m -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_UBIFS_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_CIFS=m -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/avr32/configs/atngw100mkii_evklcd100_defconfig b/arch/avr32/configs/atngw100mkii_evklcd100_defconfig deleted file mode 100644 index 89c2cda573da..000000000000 --- a/arch/avr32/configs/atngw100mkii_evklcd100_defconfig +++ /dev/null @@ -1,161 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_ATNGW100_MKII=y -CONFIG_BOARD_ATNGW100_MKII_LCD=y -CONFIG_BOARD_ATNGW100_EVKLCD10X=y -CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_ADVANCED is not set -CONFIG_NETFILTER_XTABLES=y -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_NETDEVICES=y -CONFIG_TUN=m -CONFIG_MACB=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_WM97XX=m -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_HRTIMER=y -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_ATMEL_AC97C=m -# CONFIG_SND_SPI is not set -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_VBUS_DRAW=350 -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_TEST=m -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_UBIFS_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_CIFS=m -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/avr32/configs/atngw100mkii_evklcd101_defconfig b/arch/avr32/configs/atngw100mkii_evklcd101_defconfig deleted file mode 100644 index 1b4d4a87a356..000000000000 --- a/arch/avr32/configs/atngw100mkii_evklcd101_defconfig +++ /dev/null @@ -1,160 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_ATNGW100_MKII=y -CONFIG_BOARD_ATNGW100_MKII_LCD=y -CONFIG_BOARD_ATNGW100_EVKLCD10X=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_ADVANCED is not set -CONFIG_NETFILTER_XTABLES=y -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_NETDEVICES=y -CONFIG_TUN=m -CONFIG_MACB=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_WM97XX=m -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_HRTIMER=y -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_ATMEL_AC97C=m -# CONFIG_SND_SPI is not set -CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_VBUS_DRAW=350 -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_TEST=m -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_UBIFS_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_CIFS=m -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/avr32/configs/atstk1002_defconfig b/arch/avr32/configs/atstk1002_defconfig deleted file mode 100644 index 9b8b52e54b79..000000000000 --- a/arch/avr32/configs/atstk1002_defconfig +++ /dev/null @@ -1,157 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=m -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE_DEMUX=m -CONFIG_NET_IPGRE=m -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_TUNNEL=m -CONFIG_BRIDGE=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_ATMEL_SSC=m -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=m -CONFIG_BLK_DEV_SR=m -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_ATA=m -# CONFIG_SATA_PMP is not set -CONFIG_PATA_AT32=m -CONFIG_NETDEVICES=y -CONFIG_TUN=m -CONFIG_MACB=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_ASYNC=m -CONFIG_INPUT=m -CONFIG_INPUT_EVDEV=m -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=m -# CONFIG_MOUSE_PS2 is not set -CONFIG_MOUSE_GPIO=m -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_LCD_LTV350QV=y -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_VERBOSE_PROCFS is not set -CONFIG_SND_AT73C213=m -CONFIG_USB_GADGET=y -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_TEST=m -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=m -CONFIG_LEDS_PWM=m -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=m -CONFIG_LEDS_TRIGGER_HEARTBEAT=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=m -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_UBIFS_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_CIFS=m -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/avr32/configs/atstk1003_defconfig b/arch/avr32/configs/atstk1003_defconfig deleted file mode 100644 index ccce1a0b7917..000000000000 --- a/arch/avr32/configs/atstk1003_defconfig +++ /dev/null @@ -1,137 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_ATSTK1003=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_ATMEL_SSC=m -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=m -CONFIG_BLK_DEV_SR=m -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_ATA=m -# CONFIG_SATA_PMP is not set -CONFIG_PATA_AT32=m -CONFIG_NETDEVICES=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_ASYNC=m -CONFIG_INPUT=m -CONFIG_INPUT_EVDEV=m -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=m -# CONFIG_MOUSE_PS2 is not set -CONFIG_MOUSE_GPIO=m -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_AT73C213=m -CONFIG_USB_GADGET=y -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_TEST=m -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=m -CONFIG_LEDS_PWM=m -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=m -CONFIG_LEDS_TRIGGER_HEARTBEAT=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=m -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_UBIFS_FS=y -# CONFIG_NETWORK_FILESYSTEMS is not set -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/avr32/configs/atstk1004_defconfig b/arch/avr32/configs/atstk1004_defconfig deleted file mode 100644 index e64288fc794d..000000000000 --- a/arch/avr32/configs/atstk1004_defconfig +++ /dev/null @@ -1,135 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_ATSTK1004=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_ATMEL_SSC=m -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=m -CONFIG_BLK_DEV_SR=m -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_ATA=m -# CONFIG_SATA_PMP is not set -CONFIG_PATA_AT32=m -CONFIG_NETDEVICES=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_ASYNC=m -CONFIG_INPUT=m -CONFIG_INPUT_EVDEV=m -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=m -# CONFIG_MOUSE_PS2 is not set -CONFIG_MOUSE_GPIO=m -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_LCD_LTV350QV=y -CONFIG_USB_GADGET=y -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_TEST=m -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=m -CONFIG_LEDS_PWM=m -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=m -CONFIG_LEDS_TRIGGER_HEARTBEAT=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=m -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_UBIFS_FS=y -# CONFIG_NETWORK_FILESYSTEMS is not set -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/avr32/configs/atstk1006_defconfig b/arch/avr32/configs/atstk1006_defconfig deleted file mode 100644 index 7d669f79ff74..000000000000 --- a/arch/avr32/configs/atstk1006_defconfig +++ /dev/null @@ -1,160 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_ATSTK1006=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=m -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE_DEMUX=m -CONFIG_NET_IPGRE=m -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_TUNNEL=m -CONFIG_BRIDGE=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_MTD_UBI=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_ATMEL_SSC=m -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=m -CONFIG_BLK_DEV_SR=m -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_ATA=m -# CONFIG_SATA_PMP is not set -CONFIG_PATA_AT32=m -CONFIG_NETDEVICES=y -CONFIG_TUN=m -CONFIG_MACB=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_ASYNC=m -CONFIG_INPUT=m -CONFIG_INPUT_EVDEV=m -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=m -# CONFIG_MOUSE_PS2 is not set -CONFIG_MOUSE_GPIO=m -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_LCD_LTV350QV=y -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_VERBOSE_PROCFS is not set -CONFIG_SND_AT73C213=m -CONFIG_USB_GADGET=y -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_TEST=m -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=m -CONFIG_LEDS_PWM=m -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=m -CONFIG_LEDS_TRIGGER_HEARTBEAT=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=m -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_UBIFS_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_CIFS=m -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig deleted file mode 100644 index 560c52f87d45..000000000000 --- a/arch/avr32/configs/favr-32_defconfig +++ /dev/null @@ -1,143 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_FAVR_32=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=m -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_NET_IPIP=m -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_IPV6_SIT=m -CONFIG_IPV6_TUNNEL=m -CONFIG_BRIDGE=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_ATMEL_SSC=m -CONFIG_NETDEVICES=y -CONFIG_MACB=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_ASYNC=m -CONFIG_INPUT_MOUSEDEV=m -CONFIG_INPUT_EVDEV=m -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=m -# CONFIG_MOUSE_PS2 is not set -CONFIG_MOUSE_GPIO=m -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=m -# CONFIG_SERIO is not set -# CONFIG_CONSOLE_TRANSLATIONS is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_PWM=m -CONFIG_SOUND=m -CONFIG_SOUND_PRIME=m -CONFIG_USB_GADGET=y -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_USB_CDC_COMPOSITE=m -CONFIG_MMC=y -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_DMADEVICES=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_FS_XATTR is not set -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -# CONFIG_JFFS2_FS_WRITEBUFFER is not set -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_FS=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_CRYPTO_HW is not set diff --git a/arch/avr32/configs/hammerhead_defconfig b/arch/avr32/configs/hammerhead_defconfig deleted file mode 100644 index d57fadb9e6b6..000000000000 --- a/arch/avr32/configs/hammerhead_defconfig +++ /dev/null @@ -1,145 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_HAMMERHEAD=y -CONFIG_BOARD_HAMMERHEAD_USB=y -CONFIG_BOARD_HAMMERHEAD_LCD=y -CONFIG_BOARD_HAMMERHEAD_SND=y -# CONFIG_BOARD_HAMMERHEAD_FPGA is not set -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set -# CONFIG_IPV6 is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_ADVANCED is not set -CONFIG_NETFILTER_XTABLES=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_BLK_DEV_RAM=m -CONFIG_ATMEL_TCLIB=y -CONFIG_SCSI=m -CONFIG_BLK_DEV_SD=m -CONFIG_NETDEVICES=y -CONFIG_MACB=y -CONFIG_INPUT_FF_MEMLESS=m -CONFIG_INPUT_EVDEV=m -CONFIG_INPUT_TOUCHSCREEN=y -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_GPIO=m -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=m -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_SUPPORT_OLD_API is not set -CONFIG_HID_A4TECH=m -CONFIG_HID_APPLE=m -CONFIG_HID_BELKIN=m -CONFIG_HID_CHERRY=m -CONFIG_HID_CHICONY=m -CONFIG_HID_CYPRESS=m -CONFIG_HID_EZKEY=m -CONFIG_HID_GYRATION=m -CONFIG_HID_LOGITECH=m -CONFIG_HID_MICROSOFT=m -CONFIG_HID_MONTEREY=m -CONFIG_HID_PANTHERLORD=m -CONFIG_HID_PETALYNX=m -CONFIG_HID_SAMSUNG=m -CONFIG_HID_SUNPLUS=m -CONFIG_USB=m -CONFIG_USB_MON=m -CONFIG_USB_ISP116X_HCD=m -CONFIG_USB_STORAGE=m -CONFIG_USB_GADGET=y -CONFIG_USB_ZERO=m -CONFIG_USB_ETH=m -CONFIG_USB_GADGETFS=m -CONFIG_USB_MASS_STORAGE=m -CONFIG_USB_G_SERIAL=m -CONFIG_MMC=m -CONFIG_MMC_ATMELMCI=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT32AP700X=y -CONFIG_EXT2_FS=m -# CONFIG_DNOTIFY is not set -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_UTF8=m -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_ARC4=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRC_CCITT=m -CONFIG_CRC_ITU_T=m -CONFIG_CRC7=m diff --git a/arch/avr32/configs/merisc_defconfig b/arch/avr32/configs/merisc_defconfig deleted file mode 100644 index e6a9cb7d574e..000000000000 --- a/arch/avr32/configs/merisc_defconfig +++ /dev/null @@ -1,115 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_MERISC=y -CONFIG_AP700X_32_BIT_SMC=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set -# CONFIG_IPV6 is not set -CONFIG_CAN=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_ABSENT=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_BLOCK2MTD=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_ATMEL_SSC=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_NETDEVICES=y -CONFIG_MACB=y -# CONFIG_INPUT_MOUSEDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=y -CONFIG_INPUT_MISC=y -CONFIG_INPUT_UINPUT=y -# CONFIG_SERIO is not set -# CONFIG_CONSOLE_TRANSLATIONS is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_SPI_SPIDEV=y -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_LOGO=y -CONFIG_MMC=y -CONFIG_MMC_ATMELMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_PWM=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_HCTOSYS is not set -CONFIG_RTC_DRV_PCF8563=y -CONFIG_DMADEVICES=y -CONFIG_UIO=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=m -CONFIG_EXT2_FS=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_WBUF_VERIFY=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/arch/avr32/configs/mimc200_defconfig b/arch/avr32/configs/mimc200_defconfig deleted file mode 100644 index 49c7e890af7b..000000000000 --- a/arch/avr32/configs/mimc200_defconfig +++ /dev/null @@ -1,114 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_BASE_FULL is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_BOARD_MIMC200=y -# CONFIG_OWNERSHIP_TRACE is not set -CONFIG_NMI_DEBUGGING=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_AVR32_AT32AP_CPUFREQ=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set -CONFIG_INET6_AH=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_ATMEL_TCLIB=y -CONFIG_EEPROM_AT24=y -CONFIG_EEPROM_AT25=y -CONFIG_NETDEVICES=y -CONFIG_MACB=y -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -CONFIG_GPIO_SYSFS=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_AT32AP700X_WDT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -# CONFIG_USB_SUPPORT is not set -CONFIG_MMC=y -CONFIG_MMC_TEST=y -CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_SPI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_DS1390=y -CONFIG_DMADEVICES=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_FS_XATTR is not set -# CONFIG_DNOTIFY is not set -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_TMPFS=y -CONFIG_CONFIGFS_FS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=y -CONFIG_FRAME_POINTER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_PCBC=y -CONFIG_CRYPTO_ARC4=y -CONFIG_CRC_CCITT=y diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild deleted file mode 100644 index 3d7ef2c17a7c..000000000000 --- a/arch/avr32/include/asm/Kbuild +++ /dev/null @@ -1,23 +0,0 @@ - -generic-y += clkdev.h -generic-y += delay.h -generic-y += device.h -generic-y += div64.h -generic-y += emergency-restart.h -generic-y += exec.h -generic-y += futex.h -generic-y += irq_regs.h -generic-y += irq_work.h -generic-y += local.h -generic-y += local64.h -generic-y += mcs_spinlock.h -generic-y += mm-arch-hooks.h -generic-y += param.h -generic-y += percpu.h -generic-y += preempt.h -generic-y += sections.h -generic-y += topology.h -generic-y += trace_clock.h -generic-y += vga.h -generic-y += word-at-a-time.h -generic-y += xor.h diff --git a/arch/avr32/include/asm/addrspace.h b/arch/avr32/include/asm/addrspace.h deleted file mode 100644 index 5a47a7979648..000000000000 --- a/arch/avr32/include/asm/addrspace.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Definitions for the address spaces of the AVR32 CPUs. Heavily based on - * include/asm-sh/addrspace.h - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_ADDRSPACE_H -#define __ASM_AVR32_ADDRSPACE_H - -#ifdef CONFIG_MMU - -/* Memory segments when segmentation is enabled */ -#define P0SEG 0x00000000 -#define P1SEG 0x80000000 -#define P2SEG 0xa0000000 -#define P3SEG 0xc0000000 -#define P4SEG 0xe0000000 - -/* Returns the privileged segment base of a given address */ -#define PXSEG(a) (((unsigned long)(a)) & 0xe0000000) - -/* Returns the physical address of a PnSEG (n=1,2) address */ -#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff) - -/* - * Map an address to a certain privileged segment - */ -#define P1SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) \ - | P1SEG)) -#define P2SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) \ - | P2SEG)) -#define P3SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) \ - | P3SEG)) -#define P4SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) \ - | P4SEG)) - -#endif /* CONFIG_MMU */ - -#endif /* __ASM_AVR32_ADDRSPACE_H */ diff --git a/arch/avr32/include/asm/asm-offsets.h b/arch/avr32/include/asm/asm-offsets.h deleted file mode 100644 index d370ee36a182..000000000000 --- a/arch/avr32/include/asm/asm-offsets.h +++ /dev/null @@ -1 +0,0 @@ -#include <generated/asm-offsets.h> diff --git a/arch/avr32/include/asm/asm.h b/arch/avr32/include/asm/asm.h deleted file mode 100644 index a2c64f404b98..000000000000 --- a/arch/avr32/include/asm/asm.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_ASM_H__ -#define __ASM_AVR32_ASM_H__ - -#include <asm/sysreg.h> -#include <asm/asm-offsets.h> -#include <asm/thread_info.h> - -#define mask_interrupts ssrf SYSREG_GM_OFFSET -#define mask_exceptions ssrf SYSREG_EM_OFFSET -#define unmask_interrupts csrf SYSREG_GM_OFFSET -#define unmask_exceptions csrf SYSREG_EM_OFFSET - -#ifdef CONFIG_FRAME_POINTER - .macro save_fp - st.w --sp, r7 - .endm - .macro restore_fp - ld.w r7, sp++ - .endm - .macro zero_fp - mov r7, 0 - .endm -#else - .macro save_fp - .endm - .macro restore_fp - .endm - .macro zero_fp - .endm -#endif - .macro get_thread_info reg - mov \reg, sp - andl \reg, ~(THREAD_SIZE - 1) & 0xffff - .endm - - /* Save and restore registers */ - .macro save_min sr, tmp=lr - pushm lr - mfsr \tmp, \sr - zero_fp - st.w --sp, \tmp - .endm - - .macro restore_min sr, tmp=lr - ld.w \tmp, sp++ - mtsr \sr, \tmp - popm lr - .endm - - .macro save_half sr, tmp=lr - save_fp - pushm r8-r9,r10,r11,r12,lr - zero_fp - mfsr \tmp, \sr - st.w --sp, \tmp - .endm - - .macro restore_half sr, tmp=lr - ld.w \tmp, sp++ - mtsr \sr, \tmp - popm r8-r9,r10,r11,r12,lr - restore_fp - .endm - - .macro save_full_user sr, tmp=lr - stmts --sp, r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,sp,lr - st.w --sp, lr - zero_fp - mfsr \tmp, \sr - st.w --sp, \tmp - .endm - - .macro restore_full_user sr, tmp=lr - ld.w \tmp, sp++ - mtsr \sr, \tmp - ld.w lr, sp++ - ldmts sp++, r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,sp,lr - .endm - - /* uaccess macros */ - .macro branch_if_kernel scratch, label - get_thread_info \scratch - ld.w \scratch, \scratch[TI_flags] - bld \scratch, TIF_USERSPACE - brcc \label - .endm - - .macro ret_if_privileged scratch, addr, size, ret - sub \scratch, \size, 1 - add \scratch, \addr - retcs \ret - retmi \ret - .endm - -#endif /* __ASM_AVR32_ASM_H__ */ diff --git a/arch/avr32/include/asm/atomic.h b/arch/avr32/include/asm/atomic.h deleted file mode 100644 index 3d5ce38a6f0b..000000000000 --- a/arch/avr32/include/asm/atomic.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Atomic operations that C can't guarantee us. Useful for - * resource counting etc. - * - * But use these as seldom as possible since they are slower than - * regular operations. - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_ATOMIC_H -#define __ASM_AVR32_ATOMIC_H - -#include <linux/types.h> -#include <asm/cmpxchg.h> - -#define ATOMIC_INIT(i) { (i) } - -#define atomic_read(v) READ_ONCE((v)->counter) -#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i)) - -#define ATOMIC_OP_RETURN(op, asm_op, asm_con) \ -static inline int __atomic_##op##_return(int i, atomic_t *v) \ -{ \ - int result; \ - \ - asm volatile( \ - "/* atomic_" #op "_return */\n" \ - "1: ssrf 5\n" \ - " ld.w %0, %2\n" \ - " " #asm_op " %0, %3\n" \ - " stcond %1, %0\n" \ - " brne 1b" \ - : "=&r" (result), "=o" (v->counter) \ - : "m" (v->counter), #asm_con (i) \ - : "cc"); \ - \ - return result; \ -} - -#define ATOMIC_FETCH_OP(op, asm_op, asm_con) \ -static inline int __atomic_fetch_##op(int i, atomic_t *v) \ -{ \ - int result, val; \ - \ - asm volatile( \ - "/* atomic_fetch_" #op " */\n" \ - "1: ssrf 5\n" \ - " ld.w %0, %3\n" \ - " mov %1, %0\n" \ - " " #asm_op " %1, %4\n" \ - " stcond %2, %1\n" \ - " brne 1b" \ - : "=&r" (result), "=&r" (val), "=o" (v->counter) \ - : "m" (v->counter), #asm_con (i) \ - : "cc"); \ - \ - return result; \ -} - -ATOMIC_OP_RETURN(sub, sub, rKs21) -ATOMIC_OP_RETURN(add, add, r) -ATOMIC_FETCH_OP (sub, sub, rKs21) -ATOMIC_FETCH_OP (add, add, r) - -#define ATOMIC_OPS(op, asm_op) \ -ATOMIC_OP_RETURN(op, asm_op, r) \ -static inline void atomic_##op(int i, atomic_t *v) \ -{ \ - (void)__atomic_##op##_return(i, v); \ -} \ -ATOMIC_FETCH_OP(op, asm_op, r) \ -static inline int atomic_fetch_##op(int i, atomic_t *v) \ -{ \ - return __atomic_fetch_##op(i, v); \ -} - -ATOMIC_OPS(and, and) -ATOMIC_OPS(or, or) -ATOMIC_OPS(xor, eor) - -#undef ATOMIC_OPS -#undef ATOMIC_FETCH_OP -#undef ATOMIC_OP_RETURN - -/* - * Probably found the reason why we want to use sub with the signed 21-bit - * limit, it uses one less register than the add instruction that can add up to - * 32-bit values. - * - * Both instructions are 32-bit, to use a 16-bit instruction the immediate is - * very small; 4 bit. - * - * sub 32-bit, type IV, takes a register and subtracts a 21-bit immediate. - * add 32-bit, type II, adds two register values together. - */ -#define IS_21BIT_CONST(i) \ - (__builtin_constant_p(i) && ((i) >= -1048575) && ((i) <= 1048576)) - -/* - * atomic_add_return - add integer to atomic variable - * @i: integer value to add - * @v: pointer of type atomic_t - * - * Atomically adds @i to @v. Returns the resulting value. - */ -static inline int atomic_add_return(int i, atomic_t *v) -{ - if (IS_21BIT_CONST(i)) - return __atomic_sub_return(-i, v); - - return __atomic_add_return(i, v); -} - -static inline int atomic_fetch_add(int i, atomic_t *v) -{ - if (IS_21BIT_CONST(i)) - return __atomic_fetch_sub(-i, v); - - return __atomic_fetch_add(i, v); -} - -/* - * atomic_sub_return - subtract the atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v. Returns the resulting value. - */ -static inline int atomic_sub_return(int i, atomic_t *v) -{ - if (IS_21BIT_CONST(i)) - return __atomic_sub_return(i, v); - - return __atomic_add_return(-i, v); -} - -static inline int atomic_fetch_sub(int i, atomic_t *v) -{ - if (IS_21BIT_CONST(i)) - return __atomic_fetch_sub(i, v); - - return __atomic_fetch_add(-i, v); -} - -/* - * __atomic_add_unless - add unless the number is a given value - * @v: pointer of type atomic_t - * @a: the amount to add to v... - * @u: ...unless v is equal to u. - * - * Atomically adds @a to @v, so long as it was not @u. - * Returns the old value of @v. -*/ -static inline int __atomic_add_unless(atomic_t *v, int a, int u) -{ - int tmp, old = atomic_read(v); - - if (IS_21BIT_CONST(a)) { - asm volatile( - "/* __atomic_sub_unless */\n" - "1: ssrf 5\n" - " ld.w %0, %2\n" - " cp.w %0, %4\n" - " breq 1f\n" - " sub %0, %3\n" - " stcond %1, %0\n" - " brne 1b\n" - "1:" - : "=&r"(tmp), "=o"(v->counter) - : "m"(v->counter), "rKs21"(-a), "rKs21"(u) - : "cc", "memory"); - } else { - asm volatile( - "/* __atomic_add_unless */\n" - "1: ssrf 5\n" - " ld.w %0, %2\n" - " cp.w %0, %4\n" - " breq 1f\n" - " add %0, %3\n" - " stcond %1, %0\n" - " brne 1b\n" - "1:" - : "=&r"(tmp), "=o"(v->counter) - : "m"(v->counter), "r"(a), "ir"(u) - : "cc", "memory"); - } - - return old; -} - -#undef IS_21BIT_CONST - -/* - * atomic_sub_if_positive - conditionally subtract integer from atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically test @v and subtract @i if @v is greater or equal than @i. - * The function returns the old value of @v minus @i. - */ -static inline int atomic_sub_if_positive(int i, atomic_t *v) -{ - int result; - - asm volatile( - "/* atomic_sub_if_positive */\n" - "1: ssrf 5\n" - " ld.w %0, %2\n" - " sub %0, %3\n" - " brlt 1f\n" - " stcond %1, %0\n" - " brne 1b\n" - "1:" - : "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "ir"(i) - : "cc", "memory"); - - return result; -} - -#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) -#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) - -#define atomic_sub(i, v) (void)atomic_sub_return(i, v) -#define atomic_add(i, v) (void)atomic_add_return(i, v) -#define atomic_dec(v) atomic_sub(1, (v)) -#define atomic_inc(v) atomic_add(1, (v)) - -#define atomic_dec_return(v) atomic_sub_return(1, v) -#define atomic_inc_return(v) atomic_add_return(1, v) - -#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0) -#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0) -#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0) -#define atomic_add_negative(i, v) (atomic_add_return(i, v) < 0) - -#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v) - -#endif /* __ASM_AVR32_ATOMIC_H */ diff --git a/arch/avr32/include/asm/barrier.h b/arch/avr32/include/asm/barrier.h deleted file mode 100644 index 715100790fd0..000000000000 --- a/arch/avr32/include/asm/barrier.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_BARRIER_H -#define __ASM_AVR32_BARRIER_H - -/* - * Weirdest thing ever.. no full barrier, but it has a write barrier! - */ -#define wmb() asm volatile("sync 0" : : : "memory") - -#ifdef CONFIG_SMP -# error "The AVR32 port does not support SMP" -#endif - -#include <asm-generic/barrier.h> - -#endif /* __ASM_AVR32_BARRIER_H */ diff --git a/arch/avr32/include/asm/bitops.h b/arch/avr32/include/asm/bitops.h deleted file mode 100644 index 910d5374ce59..000000000000 --- a/arch/avr32/include/asm/bitops.h +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_BITOPS_H -#define __ASM_AVR32_BITOPS_H - -#ifndef _LINUX_BITOPS_H -#error only <linux/bitops.h> can be included directly -#endif - -#include <asm/byteorder.h> -#include <asm/barrier.h> - -/* - * set_bit - Atomically set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * This function is atomic and may not be reordered. See __set_bit() - * if you do not require the atomic guarantees. - * - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ -static inline void set_bit(int nr, volatile void * addr) -{ - unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG; - unsigned long tmp; - - if (__builtin_constant_p(nr)) { - asm volatile( - "1: ssrf 5\n" - " ld.w %0, %2\n" - " sbr %0, %3\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(tmp), "=o"(*p) - : "m"(*p), "i"(nr) - : "cc"); - } else { - unsigned long mask = 1UL << (nr % BITS_PER_LONG); - asm volatile( - "1: ssrf 5\n" - " ld.w %0, %2\n" - " or %0, %3\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(tmp), "=o"(*p) - : "m"(*p), "r"(mask) - : "cc"); - } -} - -/* - * clear_bit - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit() is atomic and may not be reordered. However, it does - * not contain a memory barrier, so if it is used for locking purposes, - * you should call smp_mb__before_atomic() and/or smp_mb__after_atomic() - * in order to ensure changes are visible on other processors. - */ -static inline void clear_bit(int nr, volatile void * addr) -{ - unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG; - unsigned long tmp; - - if (__builtin_constant_p(nr)) { - asm volatile( - "1: ssrf 5\n" - " ld.w %0, %2\n" - " cbr %0, %3\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(tmp), "=o"(*p) - : "m"(*p), "i"(nr) - : "cc"); - } else { - unsigned long mask = 1UL << (nr % BITS_PER_LONG); - asm volatile( - "1: ssrf 5\n" - " ld.w %0, %2\n" - " andn %0, %3\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(tmp), "=o"(*p) - : "m"(*p), "r"(mask) - : "cc"); - } -} - -/* - * change_bit - Toggle a bit in memory - * @nr: Bit to change - * @addr: Address to start counting from - * - * change_bit() is atomic and may not be reordered. - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ -static inline void change_bit(int nr, volatile void * addr) -{ - unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG; - unsigned long mask = 1UL << (nr % BITS_PER_LONG); - unsigned long tmp; - - asm volatile( - "1: ssrf 5\n" - " ld.w %0, %2\n" - " eor %0, %3\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(tmp), "=o"(*p) - : "m"(*p), "r"(mask) - : "cc"); -} - -/* - * test_and_set_bit - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static inline int test_and_set_bit(int nr, volatile void * addr) -{ - unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG; - unsigned long mask = 1UL << (nr % BITS_PER_LONG); - unsigned long tmp, old; - - if (__builtin_constant_p(nr)) { - asm volatile( - "1: ssrf 5\n" - " ld.w %0, %3\n" - " mov %2, %0\n" - " sbr %0, %4\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(tmp), "=o"(*p), "=&r"(old) - : "m"(*p), "i"(nr) - : "memory", "cc"); - } else { - asm volatile( - "1: ssrf 5\n" - " ld.w %2, %3\n" - " or %0, %2, %4\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(tmp), "=o"(*p), "=&r"(old) - : "m"(*p), "r"(mask) - : "memory", "cc"); - } - - return (old & mask) != 0; -} - -/* - * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to clear - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static inline int test_and_clear_bit(int nr, volatile void * addr) -{ - unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG; - unsigned long mask = 1UL << (nr % BITS_PER_LONG); - unsigned long tmp, old; - - if (__builtin_constant_p(nr)) { - asm volatile( - "1: ssrf 5\n" - " ld.w %0, %3\n" - " mov %2, %0\n" - " cbr %0, %4\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(tmp), "=o"(*p), "=&r"(old) - : "m"(*p), "i"(nr) - : "memory", "cc"); - } else { - asm volatile( - "1: ssrf 5\n" - " ld.w %0, %3\n" - " mov %2, %0\n" - " andn %0, %4\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(tmp), "=o"(*p), "=&r"(old) - : "m"(*p), "r"(mask) - : "memory", "cc"); - } - - return (old & mask) != 0; -} - -/* - * test_and_change_bit - Change a bit and return its old value - * @nr: Bit to change - * @addr: Address to count from - * - * This operation is atomic and cannot be reordered. - * It also implies a memory barrier. - */ -static inline int test_and_change_bit(int nr, volatile void * addr) -{ - unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG; - unsigned long mask = 1UL << (nr % BITS_PER_LONG); - unsigned long tmp, old; - - asm volatile( - "1: ssrf 5\n" - " ld.w %2, %3\n" - " eor %0, %2, %4\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(tmp), "=o"(*p), "=&r"(old) - : "m"(*p), "r"(mask) - : "memory", "cc"); - - return (old & mask) != 0; -} - -#include <asm-generic/bitops/non-atomic.h> - -/* Find First bit Set */ -static inline unsigned long __ffs(unsigned long word) -{ - unsigned long result; - - asm("brev %1\n\t" - "clz %0,%1" - : "=r"(result), "=&r"(word) - : "1"(word)); - return result; -} - -/* Find First Zero */ -static inline unsigned long ffz(unsigned long word) -{ - return __ffs(~word); -} - -/* Find Last bit Set */ -static inline int fls(unsigned long word) -{ - unsigned long result; - - asm("clz %0,%1" : "=r"(result) : "r"(word)); - return 32 - result; -} - -static inline int __fls(unsigned long word) -{ - return fls(word) - 1; -} - -unsigned long find_first_zero_bit(const unsigned long *addr, - unsigned long size); -#define find_first_zero_bit find_first_zero_bit - -unsigned long find_next_zero_bit(const unsigned long *addr, - unsigned long size, - unsigned long offset); -#define find_next_zero_bit find_next_zero_bit - -unsigned long find_first_bit(const unsigned long *addr, - unsigned long size); -#define find_first_bit find_first_bit - -unsigned long find_next_bit(const unsigned long *addr, - unsigned long size, - unsigned long offset); -#define find_next_bit find_next_bit - -/* - * ffs: find first bit set. This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). - * - * The difference is that bit numbering starts at 1, and if no bit is set, - * the function returns 0. - */ -static inline int ffs(unsigned long word) -{ - if(word == 0) - return 0; - return __ffs(word) + 1; -} - -#include <asm-generic/bitops/fls64.h> -#include <asm-generic/bitops/sched.h> -#include <asm-generic/bitops/hweight.h> -#include <asm-generic/bitops/lock.h> - -extern unsigned long find_next_zero_bit_le(const void *addr, - unsigned long size, unsigned long offset); -#define find_next_zero_bit_le find_next_zero_bit_le - -extern unsigned long find_next_bit_le(const void *addr, - unsigned long size, unsigned long offset); -#define find_next_bit_le find_next_bit_le - -#include <asm-generic/bitops/le.h> -#include <asm-generic/bitops/ext2-atomic.h> - -#endif /* __ASM_AVR32_BITOPS_H */ diff --git a/arch/avr32/include/asm/bug.h b/arch/avr32/include/asm/bug.h deleted file mode 100644 index 85a92d099adb..000000000000 --- a/arch/avr32/include/asm/bug.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_BUG_H -#define __ASM_AVR32_BUG_H - -#ifdef CONFIG_BUG - -/* - * According to our Chief Architect, this compact opcode is very - * unlikely to ever be implemented. - */ -#define AVR32_BUG_OPCODE 0x5df0 - -#ifdef CONFIG_DEBUG_BUGVERBOSE - -#define _BUG_OR_WARN(flags) \ - asm volatile( \ - "1: .hword %0\n" \ - " .section __bug_table,\"a\",@progbits\n" \ - "2: .long 1b\n" \ - " .long %1\n" \ - " .short %2\n" \ - " .short %3\n" \ - " .org 2b + %4\n" \ - " .previous" \ - : \ - : "i"(AVR32_BUG_OPCODE), "i"(__FILE__), \ - "i"(__LINE__), "i"(flags), \ - "i"(sizeof(struct bug_entry))) - -#else - -#define _BUG_OR_WARN(flags) \ - asm volatile( \ - "1: .hword %0\n" \ - " .section __bug_table,\"a\",@progbits\n" \ - "2: .long 1b\n" \ - " .short %1\n" \ - " .org 2b + %2\n" \ - " .previous" \ - : \ - : "i"(AVR32_BUG_OPCODE), "i"(flags), \ - "i"(sizeof(struct bug_entry))) - -#endif /* CONFIG_DEBUG_BUGVERBOSE */ - -#define BUG() \ - do { \ - _BUG_OR_WARN(0); \ - unreachable(); \ - } while (0) - -#define WARN_ON(condition) \ - ({ \ - int __ret_warn_on = !!(condition); \ - if (unlikely(__ret_warn_on)) \ - _BUG_OR_WARN(BUGFLAG_WARNING); \ - unlikely(__ret_warn_on); \ - }) - -#define HAVE_ARCH_BUG -#define HAVE_ARCH_WARN_ON - -#endif /* CONFIG_BUG */ - -#include <asm-generic/bug.h> - -struct pt_regs; -void die(const char *str, struct pt_regs *regs, long err); -void _exception(long signr, struct pt_regs *regs, int code, - unsigned long addr); - -#endif /* __ASM_AVR32_BUG_H */ diff --git a/arch/avr32/include/asm/bugs.h b/arch/avr32/include/asm/bugs.h deleted file mode 100644 index 278661bbd1b0..000000000000 --- a/arch/avr32/include/asm/bugs.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This is included by init/main.c to check for architecture-dependent bugs. - * - * Needs: - * void check_bugs(void); - */ -#ifndef __ASM_AVR32_BUGS_H -#define __ASM_AVR32_BUGS_H - -static void __init check_bugs(void) -{ - boot_cpu_data.loops_per_jiffy = loops_per_jiffy; -} - -#endif /* __ASM_AVR32_BUGS_H */ diff --git a/arch/avr32/include/asm/cache.h b/arch/avr32/include/asm/cache.h deleted file mode 100644 index c3a58a189a91..000000000000 --- a/arch/avr32/include/asm/cache.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __ASM_AVR32_CACHE_H -#define __ASM_AVR32_CACHE_H - -#define L1_CACHE_SHIFT 5 -#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) - -/* - * Memory returned by kmalloc() may be used for DMA, so we must make - * sure that all such allocations are cache aligned. Otherwise, - * unrelated code may cause parts of the buffer to be read into the - * cache before the transfer is done, causing old data to be seen by - * the CPU. - */ -#define ARCH_DMA_MINALIGN L1_CACHE_BYTES - -#ifndef __ASSEMBLER__ -struct cache_info { - unsigned int ways; - unsigned int sets; - unsigned int linesz; -}; -#endif /* __ASSEMBLER */ - -/* Cache operation constants */ -#define ICACHE_FLUSH 0x00 -#define ICACHE_INVALIDATE 0x01 -#define ICACHE_LOCK 0x02 -#define ICACHE_UNLOCK 0x03 -#define ICACHE_PREFETCH 0x04 - -#define DCACHE_FLUSH 0x08 -#define DCACHE_LOCK 0x09 -#define DCACHE_UNLOCK 0x0a -#define DCACHE_INVALIDATE 0x0b -#define DCACHE_CLEAN 0x0c -#define DCACHE_CLEAN_INVAL 0x0d - -#endif /* __ASM_AVR32_CACHE_H */ diff --git a/arch/avr32/include/asm/cacheflush.h b/arch/avr32/include/asm/cacheflush.h deleted file mode 100644 index 96e53820bbbd..000000000000 --- a/arch/avr32/include/asm/cacheflush.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_CACHEFLUSH_H -#define __ASM_AVR32_CACHEFLUSH_H - -/* Keep includes the same across arches. */ -#include <linux/mm.h> - -#define CACHE_OP_ICACHE_INVALIDATE 0x01 -#define CACHE_OP_DCACHE_INVALIDATE 0x0b -#define CACHE_OP_DCACHE_CLEAN 0x0c -#define CACHE_OP_DCACHE_CLEAN_INVAL 0x0d - -/* - * Invalidate any cacheline containing virtual address vaddr without - * writing anything back to memory. - * - * Note that this function may corrupt unrelated data structures when - * applied on buffers that are not cacheline aligned in both ends. - */ -static inline void invalidate_dcache_line(void *vaddr) -{ - asm volatile("cache %0[0], %1" - : - : "r"(vaddr), "n"(CACHE_OP_DCACHE_INVALIDATE) - : "memory"); -} - -/* - * Make sure any cacheline containing virtual address vaddr is written - * to memory. - */ -static inline void clean_dcache_line(void *vaddr) -{ - asm volatile("cache %0[0], %1" - : - : "r"(vaddr), "n"(CACHE_OP_DCACHE_CLEAN) - : "memory"); -} - -/* - * Make sure any cacheline containing virtual address vaddr is written - * to memory and then invalidate it. - */ -static inline void flush_dcache_line(void *vaddr) -{ - asm volatile("cache %0[0], %1" - : - : "r"(vaddr), "n"(CACHE_OP_DCACHE_CLEAN_INVAL) - : "memory"); -} - -/* - * Invalidate any instruction cacheline containing virtual address - * vaddr. - */ -static inline void invalidate_icache_line(void *vaddr) -{ - asm volatile("cache %0[0], %1" - : - : "r"(vaddr), "n"(CACHE_OP_ICACHE_INVALIDATE) - : "memory"); -} - -/* - * Applies the above functions on all lines that are touched by the - * specified virtual address range. - */ -void invalidate_dcache_region(void *start, size_t len); -void clean_dcache_region(void *start, size_t len); -void flush_dcache_region(void *start, size_t len); -void invalidate_icache_region(void *start, size_t len); - -/* - * Make sure any pending writes are completed before continuing. - */ -#define flush_write_buffer() asm volatile("sync 0" : : : "memory") - -/* - * The following functions are called when a virtual mapping changes. - * We do not need to flush anything in this case. - */ -#define flush_cache_all() do { } while (0) -#define flush_cache_mm(mm) do { } while (0) -#define flush_cache_dup_mm(mm) do { } while (0) -#define flush_cache_range(vma, start, end) do { } while (0) -#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) -#define flush_cache_vmap(start, end) do { } while (0) -#define flush_cache_vunmap(start, end) do { } while (0) - -/* - * I think we need to implement this one to be able to reliably - * execute pages from RAMDISK. However, if we implement the - * flush_dcache_*() functions, it might not be needed anymore. - * - * #define flush_icache_page(vma, page) do { } while (0) - */ -extern void flush_icache_page(struct vm_area_struct *vma, struct page *page); - -/* - * These are (I think) related to D-cache aliasing. We might need to - * do something here, but only for certain configurations. No such - * configurations exist at this time. - */ -#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 -#define flush_dcache_page(page) do { } while (0) -#define flush_dcache_mmap_lock(page) do { } while (0) -#define flush_dcache_mmap_unlock(page) do { } while (0) - -/* - * These are for I/D cache coherency. In this case, we do need to - * flush with all configurations. - */ -extern void flush_icache_range(unsigned long start, unsigned long end); - -extern void copy_to_user_page(struct vm_area_struct *vma, struct page *page, - unsigned long vaddr, void *dst, const void *src, - unsigned long len); - -static inline void copy_from_user_page(struct vm_area_struct *vma, - struct page *page, unsigned long vaddr, void *dst, - const void *src, unsigned long len) -{ - memcpy(dst, src, len); -} - -#endif /* __ASM_AVR32_CACHEFLUSH_H */ diff --git a/arch/avr32/include/asm/checksum.h b/arch/avr32/include/asm/checksum.h deleted file mode 100644 index 4ab7d5bdaf53..000000000000 --- a/arch/avr32/include/asm/checksum.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_CHECKSUM_H -#define __ASM_AVR32_CHECKSUM_H - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -__wsum csum_partial(const void *buff, int len, __wsum sum); - -/* - * the same as csum_partial, but copies from src while it - * checksums, and handles user-space pointer exceptions correctly, when needed. - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ -__wsum csum_partial_copy_generic(const void *src, void *dst, int len, - __wsum sum, int *src_err_ptr, - int *dst_err_ptr); - -/* - * Note: when you get a NULL pointer exception here this means someone - * passed in an incorrect kernel address to one of these functions. - * - * If you use these functions directly please don't forget the - * access_ok(). - */ -static inline -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum) -{ - return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL); -} - -static inline -__wsum csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) -{ - return csum_partial_copy_generic((const void __force *)src, dst, len, - sum, err_ptr, NULL); -} - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum, tmp; - - __asm__ __volatile__( - " ld.w %0, %1++\n" - " ld.w %3, %1++\n" - " sub %2, 4\n" - " add %0, %3\n" - " ld.w %3, %1++\n" - " adc %0, %0, %3\n" - " ld.w %3, %1++\n" - " adc %0, %0, %3\n" - " acr %0\n" - "1: ld.w %3, %1++\n" - " add %0, %3\n" - " acr %0\n" - " sub %2, 1\n" - " brne 1b\n" - " lsl %3, %0, 16\n" - " andl %0, 0\n" - " mov %2, 0xffff\n" - " add %0, %3\n" - " adc %0, %0, %2\n" - " com %0\n" - " lsr %0, 16\n" - : "=r"(sum), "=r"(iph), "=r"(ihl), "=r"(tmp) - : "1"(iph), "2"(ihl) - : "memory", "cc"); - return (__force __sum16)sum; -} - -/* - * Fold a partial checksum - */ - -static inline __sum16 csum_fold(__wsum sum) -{ - unsigned int tmp; - - asm(" bfextu %1, %0, 0, 16\n" - " lsr %0, 16\n" - " add %0, %1\n" - " bfextu %1, %0, 16, 16\n" - " add %0, %1" - : "=&r"(sum), "=&r"(tmp) - : "0"(sum)); - - return (__force __sum16)~sum; -} - -static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - __u32 len, __u8 proto, - __wsum sum) -{ - asm(" add %0, %1\n" - " adc %0, %0, %2\n" - " adc %0, %0, %3\n" - " acr %0" - : "=r"(sum) - : "r"(daddr), "r"(saddr), "r"(len + proto), - "0"(sum) - : "cc"); - - return sum; -} - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - __u32 len, __u8 proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ - -static inline __sum16 ip_compute_csum(const void *buff, int len) -{ - return csum_fold(csum_partial(buff, len, 0)); -} - -#endif /* __ASM_AVR32_CHECKSUM_H */ diff --git a/arch/avr32/include/asm/cmpxchg.h b/arch/avr32/include/asm/cmpxchg.h deleted file mode 100644 index 572739b4c4b4..000000000000 --- a/arch/avr32/include/asm/cmpxchg.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Atomic operations that C can't guarantee us. Useful for - * resource counting etc. - * - * But use these as seldom as possible since they are slower than - * regular operations. - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_CMPXCHG_H -#define __ASM_AVR32_CMPXCHG_H - -#define xchg(ptr,x) \ - ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) - -extern void __xchg_called_with_bad_pointer(void); - -static inline unsigned long xchg_u32(u32 val, volatile u32 *m) -{ - u32 ret; - - asm volatile("xchg %[ret], %[m], %[val]" - : [ret] "=&r"(ret), "=m"(*m) - : "m"(*m), [m] "r"(m), [val] "r"(val) - : "memory"); - return ret; -} - -static inline unsigned long __xchg(unsigned long x, - volatile void *ptr, - int size) -{ - switch(size) { - case 4: - return xchg_u32(x, ptr); - default: - __xchg_called_with_bad_pointer(); - return x; - } -} - -static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old, - unsigned long new) -{ - __u32 ret; - - asm volatile( - "1: ssrf 5\n" - " ld.w %[ret], %[m]\n" - " cp.w %[ret], %[old]\n" - " brne 2f\n" - " stcond %[m], %[new]\n" - " brne 1b\n" - "2:\n" - : [ret] "=&r"(ret), [m] "=m"(*m) - : "m"(m), [old] "Ks21r"(old), [new] "r"(new) - : "memory", "cc"); - return ret; -} - -extern unsigned long __cmpxchg_u64_unsupported_on_32bit_kernels( - volatile int * m, unsigned long old, unsigned long new); -#define __cmpxchg_u64 __cmpxchg_u64_unsupported_on_32bit_kernels - -/* This function doesn't exist, so you'll get a linker error - if something tries to do an invalid cmpxchg(). */ -extern void __cmpxchg_called_with_bad_pointer(void); - -static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, - unsigned long new, int size) -{ - switch (size) { - case 4: - return __cmpxchg_u32(ptr, old, new); - case 8: - return __cmpxchg_u64(ptr, old, new); - } - - __cmpxchg_called_with_bad_pointer(); - return old; -} - -#define cmpxchg(ptr, old, new) \ - ((typeof(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), \ - (unsigned long)(new), \ - sizeof(*(ptr)))) - -#include <asm-generic/cmpxchg-local.h> - -static inline unsigned long __cmpxchg_local(volatile void *ptr, - unsigned long old, - unsigned long new, int size) -{ - switch (size) { - case 4: - return __cmpxchg_u32(ptr, old, new); - default: - return __cmpxchg_local_generic(ptr, old, new, size); - } - - return old; -} - -#define cmpxchg_local(ptr, old, new) \ - ((typeof(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(old), \ - (unsigned long)(new), \ - sizeof(*(ptr)))) - -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) - -#endif /* __ASM_AVR32_CMPXCHG_H */ diff --git a/arch/avr32/include/asm/current.h b/arch/avr32/include/asm/current.h deleted file mode 100644 index c7b0549eab8a..000000000000 --- a/arch/avr32/include/asm/current.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __ASM_AVR32_CURRENT_H -#define __ASM_AVR32_CURRENT_H - -#include <linux/thread_info.h> - -struct task_struct; - -inline static struct task_struct * get_current(void) -{ - return current_thread_info()->task; -} - -#define current get_current() - -#endif /* __ASM_AVR32_CURRENT_H */ diff --git a/arch/avr32/include/asm/dma-mapping.h b/arch/avr32/include/asm/dma-mapping.h deleted file mode 100644 index 7388451f9905..000000000000 --- a/arch/avr32/include/asm/dma-mapping.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __ASM_AVR32_DMA_MAPPING_H -#define __ASM_AVR32_DMA_MAPPING_H - -extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, - int direction); - -extern const struct dma_map_ops avr32_dma_ops; - -static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) -{ - return &avr32_dma_ops; -} - -#endif /* __ASM_AVR32_DMA_MAPPING_H */ diff --git a/arch/avr32/include/asm/dma.h b/arch/avr32/include/asm/dma.h deleted file mode 100644 index 9e91205590ac..000000000000 --- a/arch/avr32/include/asm/dma.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __ASM_AVR32_DMA_H -#define __ASM_AVR32_DMA_H - -/* The maximum address that we can perform a DMA transfer to on this platform. - * Not really applicable to AVR32, but some functions need it. */ -#define MAX_DMA_ADDRESS 0xffffffff - -#endif /* __ASM_AVR32_DMA_H */ diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h deleted file mode 100644 index 0388ece75b02..000000000000 --- a/arch/avr32/include/asm/elf.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef __ASM_AVR32_ELF_H -#define __ASM_AVR32_ELF_H - -/* AVR32 relocation numbers */ -#define R_AVR32_NONE 0 -#define R_AVR32_32 1 -#define R_AVR32_16 2 -#define R_AVR32_8 3 -#define R_AVR32_32_PCREL 4 -#define R_AVR32_16_PCREL 5 -#define R_AVR32_8_PCREL 6 -#define R_AVR32_DIFF32 7 -#define R_AVR32_DIFF16 8 -#define R_AVR32_DIFF8 9 -#define R_AVR32_GOT32 10 -#define R_AVR32_GOT16 11 -#define R_AVR32_GOT8 12 -#define R_AVR32_21S 13 -#define R_AVR32_16U 14 -#define R_AVR32_16S 15 -#define R_AVR32_8S 16 -#define R_AVR32_8S_EXT 17 -#define R_AVR32_22H_PCREL 18 -#define R_AVR32_18W_PCREL 19 -#define R_AVR32_16B_PCREL 20 -#define R_AVR32_16N_PCREL 21 -#define R_AVR32_14UW_PCREL 22 -#define R_AVR32_11H_PCREL 23 -#define R_AVR32_10UW_PCREL 24 -#define R_AVR32_9H_PCREL 25 -#define R_AVR32_9UW_PCREL 26 -#define R_AVR32_HI16 27 -#define R_AVR32_LO16 28 -#define R_AVR32_GOTPC 29 -#define R_AVR32_GOTCALL 30 -#define R_AVR32_LDA_GOT 31 -#define R_AVR32_GOT21S 32 -#define R_AVR32_GOT18SW 33 -#define R_AVR32_GOT16S 34 -#define R_AVR32_GOT7UW 35 -#define R_AVR32_32_CPENT 36 -#define R_AVR32_CPCALL 37 -#define R_AVR32_16_CP 38 -#define R_AVR32_9W_CP 39 -#define R_AVR32_RELATIVE 40 -#define R_AVR32_GLOB_DAT 41 -#define R_AVR32_JMP_SLOT 42 -#define R_AVR32_ALIGN 43 - -/* - * ELF register definitions.. - */ - -#include <asm/ptrace.h> -#include <asm/user.h> - -typedef unsigned long elf_greg_t; - -#define ELF_NGREG (sizeof (struct pt_regs) / sizeof (elf_greg_t)) -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef struct user_fpu_struct elf_fpregset_t; - -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) ( (x)->e_machine == EM_AVR32 ) - -/* - * These are used to set parameters in the core dumps. - */ -#define ELF_CLASS ELFCLASS32 -#ifdef __LITTLE_ENDIAN__ -#define ELF_DATA ELFDATA2LSB -#else -#define ELF_DATA ELFDATA2MSB -#endif -#define ELF_ARCH EM_AVR32 - -#define ELF_EXEC_PAGESIZE 4096 - -/* This is the location that an ET_DYN program is loaded if exec'ed. Typical - use of this is to invoke "./ld.so someprog" to test out a new version of - the loader. We need to make sure that it is out of the way of the program - that it will "exec", and that there is sufficient room for the brk. */ - -#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) - - -/* This yields a mask that user programs can use to figure out what - instruction set this CPU supports. This could be done in user space, - but it's not easy, and we've already done it here. */ - -#define ELF_HWCAP (0) - -/* This yields a string that ld.so will use to load implementation - specific libraries for optimization. This is more specific in - intent than poking at uname or /proc/cpuinfo. - - For the moment, we have only optimizations for the Intel generations, - but that could change... */ - -#define ELF_PLATFORM (NULL) - -#endif /* __ASM_AVR32_ELF_H */ diff --git a/arch/avr32/include/asm/fb.h b/arch/avr32/include/asm/fb.h deleted file mode 100644 index 41baf84ad402..000000000000 --- a/arch/avr32/include/asm/fb.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _ASM_FB_H_ -#define _ASM_FB_H_ - -#include <linux/fb.h> -#include <linux/fs.h> -#include <asm/page.h> - -static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, - unsigned long off) -{ - vma->vm_page_prot = __pgprot((pgprot_val(vma->vm_page_prot) - & ~_PAGE_CACHABLE) - | (_PAGE_BUFFER | _PAGE_DIRTY)); -} - -static inline int fb_is_primary_device(struct fb_info *info) -{ - return 0; -} - -#endif /* _ASM_FB_H_ */ diff --git a/arch/avr32/include/asm/ftrace.h b/arch/avr32/include/asm/ftrace.h deleted file mode 100644 index 40a8c178f10d..000000000000 --- a/arch/avr32/include/asm/ftrace.h +++ /dev/null @@ -1 +0,0 @@ -/* empty */ diff --git a/arch/avr32/include/asm/gpio.h b/arch/avr32/include/asm/gpio.h deleted file mode 100644 index b771f7105964..000000000000 --- a/arch/avr32/include/asm/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_GPIO_H -#define __ASM_AVR32_GPIO_H - -#include <mach/gpio.h> - -#endif /* __ASM_AVR32_GPIO_H */ diff --git a/arch/avr32/include/asm/hardirq.h b/arch/avr32/include/asm/hardirq.h deleted file mode 100644 index 9e36e3ff77d2..000000000000 --- a/arch/avr32/include/asm/hardirq.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_HARDIRQ_H -#define __ASM_AVR32_HARDIRQ_H -#ifndef __ASSEMBLY__ -#include <asm-generic/hardirq.h> -#endif /* __ASSEMBLY__ */ -#endif /* __ASM_AVR32_HARDIRQ_H */ diff --git a/arch/avr32/include/asm/hw_irq.h b/arch/avr32/include/asm/hw_irq.h deleted file mode 100644 index a36f9fcb8fcd..000000000000 --- a/arch/avr32/include/asm/hw_irq.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __ASM_AVR32_HW_IRQ_H -#define __ASM_AVR32_HW_IRQ_H - -static inline void hw_resend_irq(struct irq_chip *h, unsigned int i) -{ - /* Nothing to do */ -} - -#endif /* __ASM_AVR32_HW_IRQ_H */ diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h deleted file mode 100644 index f855646e0db7..000000000000 --- a/arch/avr32/include/asm/io.h +++ /dev/null @@ -1,329 +0,0 @@ -#ifndef __ASM_AVR32_IO_H -#define __ASM_AVR32_IO_H - -#include <linux/bug.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/types.h> - -#include <asm/addrspace.h> -#include <asm/byteorder.h> - -#include <mach/io.h> - -/* virt_to_phys will only work when address is in P1 or P2 */ -static __inline__ unsigned long virt_to_phys(volatile void *address) -{ - return PHYSADDR(address); -} - -static __inline__ void * phys_to_virt(unsigned long address) -{ - return (void *)P1SEGADDR(address); -} - -#define cached_to_phys(addr) ((unsigned long)PHYSADDR(addr)) -#define uncached_to_phys(addr) ((unsigned long)PHYSADDR(addr)) -#define phys_to_cached(addr) ((void *)P1SEGADDR(addr)) -#define phys_to_uncached(addr) ((void *)P2SEGADDR(addr)) - -/* - * Generic IO read/write. These perform native-endian accesses. Note - * that some architectures will want to re-define __raw_{read,write}w. - */ -extern void __raw_writesb(void __iomem *addr, const void *data, int bytelen); -extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen); -extern void __raw_writesl(void __iomem *addr, const void *data, int longlen); - -extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen); -extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); -extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); - -static inline void __raw_writeb(u8 v, volatile void __iomem *addr) -{ - *(volatile u8 __force *)addr = v; -} -static inline void __raw_writew(u16 v, volatile void __iomem *addr) -{ - *(volatile u16 __force *)addr = v; -} -static inline void __raw_writel(u32 v, volatile void __iomem *addr) -{ - *(volatile u32 __force *)addr = v; -} - -static inline u8 __raw_readb(const volatile void __iomem *addr) -{ - return *(const volatile u8 __force *)addr; -} -static inline u16 __raw_readw(const volatile void __iomem *addr) -{ - return *(const volatile u16 __force *)addr; -} -static inline u32 __raw_readl(const volatile void __iomem *addr) -{ - return *(const volatile u32 __force *)addr; -} - -/* Convert I/O port address to virtual address */ -#ifndef __io -# define __io(p) ((void *)phys_to_uncached(p)) -#endif - -/* - * Not really sure about the best way to slow down I/O on - * AVR32. Defining it as a no-op until we have an actual test case. - */ -#define SLOW_DOWN_IO do { } while (0) - -#define __BUILD_MEMORY_SINGLE(pfx, bwl, type) \ -static inline void \ -pfx##write##bwl(type val, volatile void __iomem *addr) \ -{ \ - volatile type *__addr; \ - type __val; \ - \ - __addr = (void *)__swizzle_addr_##bwl((unsigned long)(addr)); \ - __val = pfx##ioswab##bwl(__addr, val); \ - \ - BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ - \ - *__addr = __val; \ -} \ - \ -static inline type pfx##read##bwl(const volatile void __iomem *addr) \ -{ \ - volatile type *__addr; \ - type __val; \ - \ - __addr = (void *)__swizzle_addr_##bwl((unsigned long)(addr)); \ - \ - BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ - \ - __val = *__addr; \ - return pfx##ioswab##bwl(__addr, __val); \ -} - -#define __BUILD_IOPORT_SINGLE(pfx, bwl, type, p, slow) \ -static inline void pfx##out##bwl##p(type val, unsigned long port) \ -{ \ - volatile type *__addr; \ - type __val; \ - \ - __addr = __io(__swizzle_addr_##bwl(port)); \ - __val = pfx##ioswab##bwl(__addr, val); \ - \ - BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ - \ - *__addr = __val; \ - slow; \ -} \ - \ -static inline type pfx##in##bwl##p(unsigned long port) \ -{ \ - volatile type *__addr; \ - type __val; \ - \ - __addr = __io(__swizzle_addr_##bwl(port)); \ - \ - BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ - \ - __val = *__addr; \ - slow; \ - \ - return pfx##ioswab##bwl(__addr, __val); \ -} - -#define __BUILD_MEMORY_PFX(bus, bwl, type) \ - __BUILD_MEMORY_SINGLE(bus, bwl, type) - -#define BUILDIO_MEM(bwl, type) \ - __BUILD_MEMORY_PFX(, bwl, type) \ - __BUILD_MEMORY_PFX(__mem_, bwl, type) - -#define __BUILD_IOPORT_PFX(bus, bwl, type) \ - __BUILD_IOPORT_SINGLE(bus, bwl, type, ,) \ - __BUILD_IOPORT_SINGLE(bus, bwl, type, _p, SLOW_DOWN_IO) - -#define BUILDIO_IOPORT(bwl, type) \ - __BUILD_IOPORT_PFX(, bwl, type) \ - __BUILD_IOPORT_PFX(__mem_, bwl, type) - -BUILDIO_MEM(b, u8) -BUILDIO_MEM(w, u16) -BUILDIO_MEM(l, u32) - -BUILDIO_IOPORT(b, u8) -BUILDIO_IOPORT(w, u16) -BUILDIO_IOPORT(l, u32) - -#define readb_relaxed readb -#define readw_relaxed readw -#define readl_relaxed readl - -#define readb_be __raw_readb -#define readw_be __raw_readw -#define readl_be __raw_readl - -#define writeb_relaxed writeb -#define writew_relaxed writew -#define writel_relaxed writel - -#define writeb_be __raw_writeb -#define writew_be __raw_writew -#define writel_be __raw_writel - -#define __BUILD_MEMORY_STRING(bwl, type) \ -static inline void writes##bwl(volatile void __iomem *addr, \ - const void *data, unsigned int count) \ -{ \ - const type *__data = data; \ - \ - while (count--) \ - __mem_write##bwl(*__data++, addr); \ -} \ - \ -static inline void reads##bwl(const volatile void __iomem *addr, \ - void *data, unsigned int count) \ -{ \ - type *__data = data; \ - \ - while (count--) \ - *__data++ = __mem_read##bwl(addr); \ -} - -#define __BUILD_IOPORT_STRING(bwl, type) \ -static inline void outs##bwl(unsigned long port, const void *data, \ - unsigned int count) \ -{ \ - const type *__data = data; \ - \ - while (count--) \ - __mem_out##bwl(*__data++, port); \ -} \ - \ -static inline void ins##bwl(unsigned long port, void *data, \ - unsigned int count) \ -{ \ - type *__data = data; \ - \ - while (count--) \ - *__data++ = __mem_in##bwl(port); \ -} - -#define BUILDSTRING(bwl, type) \ - __BUILD_MEMORY_STRING(bwl, type) \ - __BUILD_IOPORT_STRING(bwl, type) - -BUILDSTRING(b, u8) -BUILDSTRING(w, u16) -BUILDSTRING(l, u32) - -/* - * io{read,write}{8,16,32} macros in both le (for PCI style consumers) and native be - */ -#ifndef ioread8 - -#define ioread8(p) ((unsigned int)readb(p)) - -#define ioread16(p) ((unsigned int)readw(p)) -#define ioread16be(p) ((unsigned int)__raw_readw(p)) - -#define ioread32(p) ((unsigned int)readl(p)) -#define ioread32be(p) ((unsigned int)__raw_readl(p)) - -#define iowrite8(v,p) writeb(v, p) - -#define iowrite16(v,p) writew(v, p) -#define iowrite16be(v,p) __raw_writew(v, p) - -#define iowrite32(v,p) writel(v, p) -#define iowrite32be(v,p) __raw_writel(v, p) - -#define ioread8_rep(p,d,c) readsb(p,d,c) -#define ioread16_rep(p,d,c) readsw(p,d,c) -#define ioread32_rep(p,d,c) readsl(p,d,c) - -#define iowrite8_rep(p,s,c) writesb(p,s,c) -#define iowrite16_rep(p,s,c) writesw(p,s,c) -#define iowrite32_rep(p,s,c) writesl(p,s,c) - -#endif - -static inline void memcpy_fromio(void * to, const volatile void __iomem *from, - unsigned long count) -{ - memcpy(to, (const void __force *)from, count); -} - -static inline void memcpy_toio(volatile void __iomem *to, const void * from, - unsigned long count) -{ - memcpy((void __force *)to, from, count); -} - -static inline void memset_io(volatile void __iomem *addr, unsigned char val, - unsigned long count) -{ - memset((void __force *)addr, val, count); -} - -#define mmiowb() - -#define IO_SPACE_LIMIT 0xffffffff - -extern void __iomem *__ioremap(unsigned long offset, size_t size, - unsigned long flags); -extern void __iounmap(void __iomem *addr); - -/* - * ioremap - map bus memory into CPU space - * @offset bus address of the memory - * @size size of the resource to map - * - * ioremap performs a platform specific sequence of operations to make - * bus memory CPU accessible via the readb/.../writel functions and - * the other mmio helpers. The returned address is not guaranteed to - * be usable directly as a virtual address. - */ -#define ioremap(offset, size) \ - __ioremap((offset), (size), 0) - -#define ioremap_nocache(offset, size) \ - __ioremap((offset), (size), 0) - -#define iounmap(addr) \ - __iounmap(addr) - -#define ioremap_wc ioremap_nocache -#define ioremap_wt ioremap_nocache -#define ioremap_uc ioremap_nocache - -#define cached(addr) P1SEGADDR(addr) -#define uncached(addr) P2SEGADDR(addr) - -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt -#define page_to_bus page_to_phys -#define bus_to_page phys_to_page - -/* - * Create a virtual mapping cookie for an IO port range. There exists - * no such thing as port-based I/O on AVR32, so a regular ioremap() - * should do what we need. - */ -#define ioport_map(port, nr) ioremap(port, nr) -#define ioport_unmap(port) iounmap(port) - -/* - * Convert a physical pointer to a virtual kernel pointer for /dev/mem - * access - */ -#define xlate_dev_mem_ptr(p) __va(p) - -/* - * Convert a virtual cached pointer to an uncached pointer - */ -#define xlate_dev_kmem_ptr(p) p - -#endif /* __ASM_AVR32_IO_H */ diff --git a/arch/avr32/include/asm/irq.h b/arch/avr32/include/asm/irq.h deleted file mode 100644 index 6fa8913f8548..000000000000 --- a/arch/avr32/include/asm/irq.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __ASM_AVR32_IRQ_H -#define __ASM_AVR32_IRQ_H - -#define NR_INTERNAL_IRQS 64 - -#include <mach/irq.h> - -#ifndef NR_IRQS -#define NR_IRQS (NR_INTERNAL_IRQS) -#endif - -#define irq_canonicalize(i) (i) - -#ifndef __ASSEMBLER__ -int nmi_enable(void); -void nmi_disable(void); - -/* - * Returns a bitmask of pending interrupts in a group. - */ -extern unsigned long intc_get_pending(unsigned int group); -#endif - -#endif /* __ASM_AVR32_IOCTLS_H */ diff --git a/arch/avr32/include/asm/irqflags.h b/arch/avr32/include/asm/irqflags.h deleted file mode 100644 index 006e9487372d..000000000000 --- a/arch/avr32/include/asm/irqflags.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_IRQFLAGS_H -#define __ASM_AVR32_IRQFLAGS_H - -#include <linux/types.h> -#include <asm/sysreg.h> - -static inline unsigned long arch_local_save_flags(void) -{ - return sysreg_read(SR); -} - -/* - * This will restore ALL status register flags, not only the interrupt - * mask flag. - * - * The empty asm statement informs the compiler of this fact while - * also serving as a barrier. - */ -static inline void arch_local_irq_restore(unsigned long flags) -{ - sysreg_write(SR, flags); - asm volatile("" : : : "memory", "cc"); -} - -static inline void arch_local_irq_disable(void) -{ - asm volatile("ssrf %0" : : "n"(SYSREG_GM_OFFSET) : "memory"); -} - -static inline void arch_local_irq_enable(void) -{ - asm volatile("csrf %0" : : "n"(SYSREG_GM_OFFSET) : "memory"); -} - -static inline bool arch_irqs_disabled_flags(unsigned long flags) -{ - return (flags & SYSREG_BIT(GM)) != 0; -} - -static inline bool arch_irqs_disabled(void) -{ - return arch_irqs_disabled_flags(arch_local_save_flags()); -} - -static inline unsigned long arch_local_irq_save(void) -{ - unsigned long flags = arch_local_save_flags(); - - arch_local_irq_disable(); - - return flags; -} - -#endif /* __ASM_AVR32_IRQFLAGS_H */ diff --git a/arch/avr32/include/asm/kdebug.h b/arch/avr32/include/asm/kdebug.h deleted file mode 100644 index f930ce286803..000000000000 --- a/arch/avr32/include/asm/kdebug.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __ASM_AVR32_KDEBUG_H -#define __ASM_AVR32_KDEBUG_H - -/* Grossly misnamed. */ -enum die_val { - DIE_BREAKPOINT, - DIE_SSTEP, - DIE_NMI, - DIE_OOPS, -}; - -#endif /* __ASM_AVR32_KDEBUG_H */ diff --git a/arch/avr32/include/asm/kmap_types.h b/arch/avr32/include/asm/kmap_types.h deleted file mode 100644 index 479330b89796..000000000000 --- a/arch/avr32/include/asm/kmap_types.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __ASM_AVR32_KMAP_TYPES_H -#define __ASM_AVR32_KMAP_TYPES_H - -#ifdef CONFIG_DEBUG_HIGHMEM -# define KM_TYPE_NR 29 -#else -# define KM_TYPE_NR 14 -#endif - -#endif /* __ASM_AVR32_KMAP_TYPES_H */ diff --git a/arch/avr32/include/asm/kprobes.h b/arch/avr32/include/asm/kprobes.h deleted file mode 100644 index 28dfc61ad384..000000000000 --- a/arch/avr32/include/asm/kprobes.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Kernel Probes (KProbes) - * - * Copyright (C) 2005-2006 Atmel Corporation - * Copyright (C) IBM Corporation, 2002, 2004 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_KPROBES_H -#define __ASM_AVR32_KPROBES_H - -#include <asm-generic/kprobes.h> - -#define BREAKPOINT_INSTRUCTION 0xd673 /* breakpoint */ - -#ifdef CONFIG_KPROBES -#include <linux/types.h> - -typedef u16 kprobe_opcode_t; -#define MAX_INSN_SIZE 2 -#define MAX_STACK_SIZE 64 /* 32 would probably be OK */ - -#define kretprobe_blacklist_size 0 - -#define arch_remove_kprobe(p) do { } while (0) - -/* Architecture specific copy of original instruction */ -struct arch_specific_insn { - kprobe_opcode_t insn[MAX_INSN_SIZE]; -}; - -struct prev_kprobe { - struct kprobe *kp; - unsigned int status; -}; - -/* per-cpu kprobe control block */ -struct kprobe_ctlblk { - unsigned int kprobe_status; - struct prev_kprobe prev_kprobe; - struct pt_regs jprobe_saved_regs; - char jprobes_stack[MAX_STACK_SIZE]; -}; - -extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); -extern int kprobe_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data); - -#define flush_insn_slot(p) do { } while (0) - -#endif /* CONFIG_KPROBES */ -#endif /* __ASM_AVR32_KPROBES_H */ diff --git a/arch/avr32/include/asm/linkage.h b/arch/avr32/include/asm/linkage.h deleted file mode 100644 index f7b285e910d4..000000000000 --- a/arch/avr32/include/asm/linkage.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_LINKAGE_H -#define __ASM_LINKAGE_H - -#define __ALIGN .balign 2 -#define __ALIGN_STR ".balign 2" - -#endif /* __ASM_LINKAGE_H */ diff --git a/arch/avr32/include/asm/mmu.h b/arch/avr32/include/asm/mmu.h deleted file mode 100644 index 60c2d2650d32..000000000000 --- a/arch/avr32/include/asm/mmu.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __ASM_AVR32_MMU_H -#define __ASM_AVR32_MMU_H - -/* Default "unsigned long" context */ -typedef unsigned long mm_context_t; - -#define MMU_ITLB_ENTRIES 64 -#define MMU_DTLB_ENTRIES 64 - -#endif /* __ASM_AVR32_MMU_H */ diff --git a/arch/avr32/include/asm/mmu_context.h b/arch/avr32/include/asm/mmu_context.h deleted file mode 100644 index cd87abba8db7..000000000000 --- a/arch/avr32/include/asm/mmu_context.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * ASID handling taken from SH implementation. - * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2003 Paul Mundt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_MMU_CONTEXT_H -#define __ASM_AVR32_MMU_CONTEXT_H - -#include <linux/mm_types.h> - -#include <asm/tlbflush.h> -#include <asm/sysreg.h> -#include <asm-generic/mm_hooks.h> - -/* - * The MMU "context" consists of two things: - * (a) TLB cache version - * (b) ASID (Address Space IDentifier) - */ -#define MMU_CONTEXT_ASID_MASK 0x000000ff -#define MMU_CONTEXT_VERSION_MASK 0xffffff00 -#define MMU_CONTEXT_FIRST_VERSION 0x00000100 -#define NO_CONTEXT 0 - -#define MMU_NO_ASID 0x100 - -/* Virtual Page Number mask */ -#define MMU_VPN_MASK 0xfffff000 - -/* Cache of MMU context last used */ -extern unsigned long mmu_context_cache; - -/* - * Get MMU context if needed - */ -static inline void -get_mmu_context(struct mm_struct *mm) -{ - unsigned long mc = mmu_context_cache; - - if (((mm->context ^ mc) & MMU_CONTEXT_VERSION_MASK) == 0) - /* It's up to date, do nothing */ - return; - - /* It's old, we need to get new context with new version */ - mc = ++mmu_context_cache; - if (!(mc & MMU_CONTEXT_ASID_MASK)) { - /* - * We have exhausted all ASIDs of this version. - * Flush the TLB and start new cycle. - */ - flush_tlb_all(); - /* - * Fix version. Note that we avoid version #0 - * to distinguish NO_CONTEXT. - */ - if (!mc) - mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION; - } - mm->context = mc; -} - -/* - * Initialize the context related info for a new mm_struct - * instance. - */ -static inline int init_new_context(struct task_struct *tsk, - struct mm_struct *mm) -{ - mm->context = NO_CONTEXT; - return 0; -} - -/* - * Destroy context related info for an mm_struct that is about - * to be put to rest. - */ -static inline void destroy_context(struct mm_struct *mm) -{ - /* Do nothing */ -} - -static inline void set_asid(unsigned long asid) -{ - /* XXX: We're destroying TLBEHI[8:31] */ - sysreg_write(TLBEHI, asid & MMU_CONTEXT_ASID_MASK); - cpu_sync_pipeline(); -} - -static inline unsigned long get_asid(void) -{ - unsigned long asid; - - asid = sysreg_read(TLBEHI); - return asid & MMU_CONTEXT_ASID_MASK; -} - -static inline void activate_context(struct mm_struct *mm) -{ - get_mmu_context(mm); - set_asid(mm->context & MMU_CONTEXT_ASID_MASK); -} - -static inline void switch_mm(struct mm_struct *prev, - struct mm_struct *next, - struct task_struct *tsk) -{ - if (likely(prev != next)) { - unsigned long __pgdir = (unsigned long)next->pgd; - - sysreg_write(PTBR, __pgdir); - activate_context(next); - } -} - -#define deactivate_mm(tsk,mm) do { } while(0) - -#define activate_mm(prev, next) switch_mm((prev), (next), NULL) - -static inline void -enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) -{ -} - - -static inline void enable_mmu(void) -{ - sysreg_write(MMUCR, (SYSREG_BIT(MMUCR_S) - | SYSREG_BIT(E) - | SYSREG_BIT(MMUCR_I))); - nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop(); - - if (mmu_context_cache == NO_CONTEXT) - mmu_context_cache = MMU_CONTEXT_FIRST_VERSION; - - set_asid(mmu_context_cache & MMU_CONTEXT_ASID_MASK); -} - -static inline void disable_mmu(void) -{ - sysreg_write(MMUCR, SYSREG_BIT(MMUCR_S)); -} - -#endif /* __ASM_AVR32_MMU_CONTEXT_H */ diff --git a/arch/avr32/include/asm/module.h b/arch/avr32/include/asm/module.h deleted file mode 100644 index 3f083d385a64..000000000000 --- a/arch/avr32/include/asm/module.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __ASM_AVR32_MODULE_H -#define __ASM_AVR32_MODULE_H - -#include <asm-generic/module.h> - -struct mod_arch_syminfo { - unsigned long got_offset; - int got_initialized; -}; - -struct mod_arch_specific { - /* Starting offset of got in the module core memory. */ - unsigned long got_offset; - /* Size of the got. */ - unsigned long got_size; - /* Number of symbols in syminfo. */ - int nsyms; - /* Additional symbol information (got offsets). */ - struct mod_arch_syminfo *syminfo; -}; - -#define MODULE_PROC_FAMILY "AVR32v1" - -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY - -#endif /* __ASM_AVR32_MODULE_H */ diff --git a/arch/avr32/include/asm/ocd.h b/arch/avr32/include/asm/ocd.h deleted file mode 100644 index 6bef09490235..000000000000 --- a/arch/avr32/include/asm/ocd.h +++ /dev/null @@ -1,543 +0,0 @@ -/* - * AVR32 OCD Interface and register definitions - * - * Copyright (C) 2004-2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_OCD_H -#define __ASM_AVR32_OCD_H - -/* OCD Register offsets. Abbreviations used below: - * - * BP Breakpoint - * Comm Communication - * DT Data Trace - * PC Program Counter - * PID Process ID - * R/W Read/Write - * WP Watchpoint - */ -#define OCD_DID 0x0000 /* Device ID */ -#define OCD_DC 0x0008 /* Development Control */ -#define OCD_DS 0x0010 /* Development Status */ -#define OCD_RWCS 0x001c /* R/W Access Control */ -#define OCD_RWA 0x0024 /* R/W Access Address */ -#define OCD_RWD 0x0028 /* R/W Access Data */ -#define OCD_WT 0x002c /* Watchpoint Trigger */ -#define OCD_DTC 0x0034 /* Data Trace Control */ -#define OCD_DTSA0 0x0038 /* DT Start Addr Channel 0 */ -#define OCD_DTSA1 0x003c /* DT Start Addr Channel 1 */ -#define OCD_DTEA0 0x0048 /* DT End Addr Channel 0 */ -#define OCD_DTEA1 0x004c /* DT End Addr Channel 1 */ -#define OCD_BWC0A 0x0058 /* PC BP/WP Control 0A */ -#define OCD_BWC0B 0x005c /* PC BP/WP Control 0B */ -#define OCD_BWC1A 0x0060 /* PC BP/WP Control 1A */ -#define OCD_BWC1B 0x0064 /* PC BP/WP Control 1B */ -#define OCD_BWC2A 0x0068 /* PC BP/WP Control 2A */ -#define OCD_BWC2B 0x006c /* PC BP/WP Control 2B */ -#define OCD_BWC3A 0x0070 /* Data BP/WP Control 3A */ -#define OCD_BWC3B 0x0074 /* Data BP/WP Control 3B */ -#define OCD_BWA0A 0x0078 /* PC BP/WP Address 0A */ -#define OCD_BWA0B 0x007c /* PC BP/WP Address 0B */ -#define OCD_BWA1A 0x0080 /* PC BP/WP Address 1A */ -#define OCD_BWA1B 0x0084 /* PC BP/WP Address 1B */ -#define OCD_BWA2A 0x0088 /* PC BP/WP Address 2A */ -#define OCD_BWA2B 0x008c /* PC BP/WP Address 2B */ -#define OCD_BWA3A 0x0090 /* Data BP/WP Address 3A */ -#define OCD_BWA3B 0x0094 /* Data BP/WP Address 3B */ -#define OCD_NXCFG 0x0100 /* Nexus Configuration */ -#define OCD_DINST 0x0104 /* Debug Instruction */ -#define OCD_DPC 0x0108 /* Debug Program Counter */ -#define OCD_CPUCM 0x010c /* CPU Control Mask */ -#define OCD_DCCPU 0x0110 /* Debug Comm CPU */ -#define OCD_DCEMU 0x0114 /* Debug Comm Emulator */ -#define OCD_DCSR 0x0118 /* Debug Comm Status */ -#define OCD_PID 0x011c /* Ownership Trace PID */ -#define OCD_EPC0 0x0120 /* Event Pair Control 0 */ -#define OCD_EPC1 0x0124 /* Event Pair Control 1 */ -#define OCD_EPC2 0x0128 /* Event Pair Control 2 */ -#define OCD_EPC3 0x012c /* Event Pair Control 3 */ -#define OCD_AXC 0x0130 /* AUX port Control */ - -/* Bits in DID */ -#define OCD_DID_MID_START 1 -#define OCD_DID_MID_SIZE 11 -#define OCD_DID_PN_START 12 -#define OCD_DID_PN_SIZE 16 -#define OCD_DID_RN_START 28 -#define OCD_DID_RN_SIZE 4 - -/* Bits in DC */ -#define OCD_DC_TM_START 0 -#define OCD_DC_TM_SIZE 2 -#define OCD_DC_EIC_START 3 -#define OCD_DC_EIC_SIZE 2 -#define OCD_DC_OVC_START 5 -#define OCD_DC_OVC_SIZE 3 -#define OCD_DC_SS_BIT 8 -#define OCD_DC_DBR_BIT 12 -#define OCD_DC_DBE_BIT 13 -#define OCD_DC_EOS_START 20 -#define OCD_DC_EOS_SIZE 2 -#define OCD_DC_SQA_BIT 22 -#define OCD_DC_IRP_BIT 23 -#define OCD_DC_IFM_BIT 24 -#define OCD_DC_TOZ_BIT 25 -#define OCD_DC_TSR_BIT 26 -#define OCD_DC_RID_BIT 27 -#define OCD_DC_ORP_BIT 28 -#define OCD_DC_MM_BIT 29 -#define OCD_DC_RES_BIT 30 -#define OCD_DC_ABORT_BIT 31 - -/* Bits in DS */ -#define OCD_DS_SSS_BIT 0 -#define OCD_DS_SWB_BIT 1 -#define OCD_DS_HWB_BIT 2 -#define OCD_DS_HWE_BIT 3 -#define OCD_DS_STP_BIT 4 -#define OCD_DS_DBS_BIT 5 -#define OCD_DS_BP_START 8 -#define OCD_DS_BP_SIZE 8 -#define OCD_DS_INC_BIT 24 -#define OCD_DS_BOZ_BIT 25 -#define OCD_DS_DBA_BIT 26 -#define OCD_DS_EXB_BIT 27 -#define OCD_DS_NTBF_BIT 28 - -/* Bits in RWCS */ -#define OCD_RWCS_DV_BIT 0 -#define OCD_RWCS_ERR_BIT 1 -#define OCD_RWCS_CNT_START 2 -#define OCD_RWCS_CNT_SIZE 14 -#define OCD_RWCS_CRC_BIT 19 -#define OCD_RWCS_NTBC_START 20 -#define OCD_RWCS_NTBC_SIZE 2 -#define OCD_RWCS_NTE_BIT 22 -#define OCD_RWCS_NTAP_BIT 23 -#define OCD_RWCS_WRAPPED_BIT 24 -#define OCD_RWCS_CCTRL_START 25 -#define OCD_RWCS_CCTRL_SIZE 2 -#define OCD_RWCS_SZ_START 27 -#define OCD_RWCS_SZ_SIZE 3 -#define OCD_RWCS_RW_BIT 30 -#define OCD_RWCS_AC_BIT 31 - -/* Bits in RWA */ -#define OCD_RWA_RWA_START 0 -#define OCD_RWA_RWA_SIZE 32 - -/* Bits in RWD */ -#define OCD_RWD_RWD_START 0 -#define OCD_RWD_RWD_SIZE 32 - -/* Bits in WT */ -#define OCD_WT_DTE_START 20 -#define OCD_WT_DTE_SIZE 3 -#define OCD_WT_DTS_START 23 -#define OCD_WT_DTS_SIZE 3 -#define OCD_WT_PTE_START 26 -#define OCD_WT_PTE_SIZE 3 -#define OCD_WT_PTS_START 29 -#define OCD_WT_PTS_SIZE 3 - -/* Bits in DTC */ -#define OCD_DTC_T0WP_BIT 0 -#define OCD_DTC_T1WP_BIT 1 -#define OCD_DTC_ASID0EN_BIT 2 -#define OCD_DTC_ASID0_START 3 -#define OCD_DTC_ASID0_SIZE 8 -#define OCD_DTC_ASID1EN_BIT 11 -#define OCD_DTC_ASID1_START 12 -#define OCD_DTC_ASID1_SIZE 8 -#define OCD_DTC_RWT1_START 28 -#define OCD_DTC_RWT1_SIZE 2 -#define OCD_DTC_RWT0_START 30 -#define OCD_DTC_RWT0_SIZE 2 - -/* Bits in DTSA0 */ -#define OCD_DTSA0_DTSA_START 0 -#define OCD_DTSA0_DTSA_SIZE 32 - -/* Bits in DTSA1 */ -#define OCD_DTSA1_DTSA_START 0 -#define OCD_DTSA1_DTSA_SIZE 32 - -/* Bits in DTEA0 */ -#define OCD_DTEA0_DTEA_START 0 -#define OCD_DTEA0_DTEA_SIZE 32 - -/* Bits in DTEA1 */ -#define OCD_DTEA1_DTEA_START 0 -#define OCD_DTEA1_DTEA_SIZE 32 - -/* Bits in BWC0A */ -#define OCD_BWC0A_ASIDEN_BIT 0 -#define OCD_BWC0A_ASID_START 1 -#define OCD_BWC0A_ASID_SIZE 8 -#define OCD_BWC0A_EOC_BIT 14 -#define OCD_BWC0A_AME_BIT 25 -#define OCD_BWC0A_BWE_START 30 -#define OCD_BWC0A_BWE_SIZE 2 - -/* Bits in BWC0B */ -#define OCD_BWC0B_ASIDEN_BIT 0 -#define OCD_BWC0B_ASID_START 1 -#define OCD_BWC0B_ASID_SIZE 8 -#define OCD_BWC0B_EOC_BIT 14 -#define OCD_BWC0B_AME_BIT 25 -#define OCD_BWC0B_BWE_START 30 -#define OCD_BWC0B_BWE_SIZE 2 - -/* Bits in BWC1A */ -#define OCD_BWC1A_ASIDEN_BIT 0 -#define OCD_BWC1A_ASID_START 1 -#define OCD_BWC1A_ASID_SIZE 8 -#define OCD_BWC1A_EOC_BIT 14 -#define OCD_BWC1A_AME_BIT 25 -#define OCD_BWC1A_BWE_START 30 -#define OCD_BWC1A_BWE_SIZE 2 - -/* Bits in BWC1B */ -#define OCD_BWC1B_ASIDEN_BIT 0 -#define OCD_BWC1B_ASID_START 1 -#define OCD_BWC1B_ASID_SIZE 8 -#define OCD_BWC1B_EOC_BIT 14 -#define OCD_BWC1B_AME_BIT 25 -#define OCD_BWC1B_BWE_START 30 -#define OCD_BWC1B_BWE_SIZE 2 - -/* Bits in BWC2A */ -#define OCD_BWC2A_ASIDEN_BIT 0 -#define OCD_BWC2A_ASID_START 1 -#define OCD_BWC2A_ASID_SIZE 8 -#define OCD_BWC2A_EOC_BIT 14 -#define OCD_BWC2A_AMB_START 20 -#define OCD_BWC2A_AMB_SIZE 5 -#define OCD_BWC2A_AME_BIT 25 -#define OCD_BWC2A_BWE_START 30 -#define OCD_BWC2A_BWE_SIZE 2 - -/* Bits in BWC2B */ -#define OCD_BWC2B_ASIDEN_BIT 0 -#define OCD_BWC2B_ASID_START 1 -#define OCD_BWC2B_ASID_SIZE 8 -#define OCD_BWC2B_EOC_BIT 14 -#define OCD_BWC2B_AME_BIT 25 -#define OCD_BWC2B_BWE_START 30 -#define OCD_BWC2B_BWE_SIZE 2 - -/* Bits in BWC3A */ -#define OCD_BWC3A_ASIDEN_BIT 0 -#define OCD_BWC3A_ASID_START 1 -#define OCD_BWC3A_ASID_SIZE 8 -#define OCD_BWC3A_SIZE_START 9 -#define OCD_BWC3A_SIZE_SIZE 3 -#define OCD_BWC3A_EOC_BIT 14 -#define OCD_BWC3A_BWO_START 16 -#define OCD_BWC3A_BWO_SIZE 2 -#define OCD_BWC3A_BME_START 20 -#define OCD_BWC3A_BME_SIZE 4 -#define OCD_BWC3A_BRW_START 28 -#define OCD_BWC3A_BRW_SIZE 2 -#define OCD_BWC3A_BWE_START 30 -#define OCD_BWC3A_BWE_SIZE 2 - -/* Bits in BWC3B */ -#define OCD_BWC3B_ASIDEN_BIT 0 -#define OCD_BWC3B_ASID_START 1 -#define OCD_BWC3B_ASID_SIZE 8 -#define OCD_BWC3B_SIZE_START 9 -#define OCD_BWC3B_SIZE_SIZE 3 -#define OCD_BWC3B_EOC_BIT 14 -#define OCD_BWC3B_BWO_START 16 -#define OCD_BWC3B_BWO_SIZE 2 -#define OCD_BWC3B_BME_START 20 -#define OCD_BWC3B_BME_SIZE 4 -#define OCD_BWC3B_BRW_START 28 -#define OCD_BWC3B_BRW_SIZE 2 -#define OCD_BWC3B_BWE_START 30 -#define OCD_BWC3B_BWE_SIZE 2 - -/* Bits in BWA0A */ -#define OCD_BWA0A_BWA_START 0 -#define OCD_BWA0A_BWA_SIZE 32 - -/* Bits in BWA0B */ -#define OCD_BWA0B_BWA_START 0 -#define OCD_BWA0B_BWA_SIZE 32 - -/* Bits in BWA1A */ -#define OCD_BWA1A_BWA_START 0 -#define OCD_BWA1A_BWA_SIZE 32 - -/* Bits in BWA1B */ -#define OCD_BWA1B_BWA_START 0 -#define OCD_BWA1B_BWA_SIZE 32 - -/* Bits in BWA2A */ -#define OCD_BWA2A_BWA_START 0 -#define OCD_BWA2A_BWA_SIZE 32 - -/* Bits in BWA2B */ -#define OCD_BWA2B_BWA_START 0 -#define OCD_BWA2B_BWA_SIZE 32 - -/* Bits in BWA3A */ -#define OCD_BWA3A_BWA_START 0 -#define OCD_BWA3A_BWA_SIZE 32 - -/* Bits in BWA3B */ -#define OCD_BWA3B_BWA_START 0 -#define OCD_BWA3B_BWA_SIZE 32 - -/* Bits in NXCFG */ -#define OCD_NXCFG_NXARCH_START 0 -#define OCD_NXCFG_NXARCH_SIZE 4 -#define OCD_NXCFG_NXOCD_START 4 -#define OCD_NXCFG_NXOCD_SIZE 4 -#define OCD_NXCFG_NXPCB_START 8 -#define OCD_NXCFG_NXPCB_SIZE 4 -#define OCD_NXCFG_NXDB_START 12 -#define OCD_NXCFG_NXDB_SIZE 4 -#define OCD_NXCFG_MXMSEO_BIT 16 -#define OCD_NXCFG_NXMDO_START 17 -#define OCD_NXCFG_NXMDO_SIZE 4 -#define OCD_NXCFG_NXPT_BIT 21 -#define OCD_NXCFG_NXOT_BIT 22 -#define OCD_NXCFG_NXDWT_BIT 23 -#define OCD_NXCFG_NXDRT_BIT 24 -#define OCD_NXCFG_NXDTC_START 25 -#define OCD_NXCFG_NXDTC_SIZE 3 -#define OCD_NXCFG_NXDMA_BIT 28 - -/* Bits in DINST */ -#define OCD_DINST_DINST_START 0 -#define OCD_DINST_DINST_SIZE 32 - -/* Bits in CPUCM */ -#define OCD_CPUCM_BEM_BIT 1 -#define OCD_CPUCM_FEM_BIT 2 -#define OCD_CPUCM_REM_BIT 3 -#define OCD_CPUCM_IBEM_BIT 4 -#define OCD_CPUCM_IEEM_BIT 5 - -/* Bits in DCCPU */ -#define OCD_DCCPU_DATA_START 0 -#define OCD_DCCPU_DATA_SIZE 32 - -/* Bits in DCEMU */ -#define OCD_DCEMU_DATA_START 0 -#define OCD_DCEMU_DATA_SIZE 32 - -/* Bits in DCSR */ -#define OCD_DCSR_CPUD_BIT 0 -#define OCD_DCSR_EMUD_BIT 1 - -/* Bits in PID */ -#define OCD_PID_PROCESS_START 0 -#define OCD_PID_PROCESS_SIZE 32 - -/* Bits in EPC0 */ -#define OCD_EPC0_RNG_START 0 -#define OCD_EPC0_RNG_SIZE 2 -#define OCD_EPC0_CE_BIT 4 -#define OCD_EPC0_ECNT_START 16 -#define OCD_EPC0_ECNT_SIZE 16 - -/* Bits in EPC1 */ -#define OCD_EPC1_RNG_START 0 -#define OCD_EPC1_RNG_SIZE 2 -#define OCD_EPC1_ATB_BIT 5 -#define OCD_EPC1_AM_BIT 6 - -/* Bits in EPC2 */ -#define OCD_EPC2_RNG_START 0 -#define OCD_EPC2_RNG_SIZE 2 -#define OCD_EPC2_DB_START 2 -#define OCD_EPC2_DB_SIZE 2 - -/* Bits in EPC3 */ -#define OCD_EPC3_RNG_START 0 -#define OCD_EPC3_RNG_SIZE 2 -#define OCD_EPC3_DWE_BIT 2 - -/* Bits in AXC */ -#define OCD_AXC_DIV_START 0 -#define OCD_AXC_DIV_SIZE 4 -#define OCD_AXC_AXE_BIT 8 -#define OCD_AXC_AXS_BIT 9 -#define OCD_AXC_DDR_BIT 10 -#define OCD_AXC_LS_BIT 11 -#define OCD_AXC_REX_BIT 12 -#define OCD_AXC_REXTEN_BIT 13 - -/* Constants for DC:EIC */ -#define OCD_EIC_PROGRAM_AND_DATA_TRACE 0 -#define OCD_EIC_BREAKPOINT 1 -#define OCD_EIC_NOP 2 - -/* Constants for DC:OVC */ -#define OCD_OVC_OVERRUN 0 -#define OCD_OVC_DELAY_CPU_BTM 1 -#define OCD_OVC_DELAY_CPU_DTM 2 -#define OCD_OVC_DELAY_CPU_BTM_DTM 3 - -/* Constants for DC:EOS */ -#define OCD_EOS_NOP 0 -#define OCD_EOS_DEBUG_MODE 1 -#define OCD_EOS_BREAKPOINT_WATCHPOINT 2 -#define OCD_EOS_THQ 3 - -/* Constants for RWCS:NTBC */ -#define OCD_NTBC_OVERWRITE 0 -#define OCD_NTBC_DISABLE 1 -#define OCD_NTBC_BREAKPOINT 2 - -/* Constants for RWCS:CCTRL */ -#define OCD_CCTRL_AUTO 0 -#define OCD_CCTRL_CACHED 1 -#define OCD_CCTRL_UNCACHED 2 - -/* Constants for RWCS:SZ */ -#define OCD_SZ_BYTE 0 -#define OCD_SZ_HALFWORD 1 -#define OCD_SZ_WORD 2 - -/* Constants for WT:PTS */ -#define OCD_PTS_DISABLED 0 -#define OCD_PTS_PROGRAM_0B 1 -#define OCD_PTS_PROGRAM_1A 2 -#define OCD_PTS_PROGRAM_1B 3 -#define OCD_PTS_PROGRAM_2A 4 -#define OCD_PTS_PROGRAM_2B 5 -#define OCD_PTS_DATA_3A 6 -#define OCD_PTS_DATA_3B 7 - -/* Constants for DTC:RWT1 */ -#define OCD_RWT1_NO_TRACE 0 -#define OCD_RWT1_DATA_READ 1 -#define OCD_RWT1_DATA_WRITE 2 -#define OCD_RWT1_DATA_READ_WRITE 3 - -/* Constants for DTC:RWT0 */ -#define OCD_RWT0_NO_TRACE 0 -#define OCD_RWT0_DATA_READ 1 -#define OCD_RWT0_DATA_WRITE 2 -#define OCD_RWT0_DATA_READ_WRITE 3 - -/* Constants for BWC0A:BWE */ -#define OCD_BWE_DISABLED 0 -#define OCD_BWE_BREAKPOINT_ENABLED 1 -#define OCD_BWE_WATCHPOINT_ENABLED 3 - -/* Constants for BWC0B:BWE */ -#define OCD_BWE_DISABLED 0 -#define OCD_BWE_BREAKPOINT_ENABLED 1 -#define OCD_BWE_WATCHPOINT_ENABLED 3 - -/* Constants for BWC1A:BWE */ -#define OCD_BWE_DISABLED 0 -#define OCD_BWE_BREAKPOINT_ENABLED 1 -#define OCD_BWE_WATCHPOINT_ENABLED 3 - -/* Constants for BWC1B:BWE */ -#define OCD_BWE_DISABLED 0 -#define OCD_BWE_BREAKPOINT_ENABLED 1 -#define OCD_BWE_WATCHPOINT_ENABLED 3 - -/* Constants for BWC2A:BWE */ -#define OCD_BWE_DISABLED 0 -#define OCD_BWE_BREAKPOINT_ENABLED 1 -#define OCD_BWE_WATCHPOINT_ENABLED 3 - -/* Constants for BWC2B:BWE */ -#define OCD_BWE_DISABLED 0 -#define OCD_BWE_BREAKPOINT_ENABLED 1 -#define OCD_BWE_WATCHPOINT_ENABLED 3 - -/* Constants for BWC3A:SIZE */ -#define OCD_SIZE_BYTE_ACCESS 4 -#define OCD_SIZE_HALFWORD_ACCESS 5 -#define OCD_SIZE_WORD_ACCESS 6 -#define OCD_SIZE_DOUBLE_WORD_ACCESS 7 - -/* Constants for BWC3A:BRW */ -#define OCD_BRW_READ_BREAK 0 -#define OCD_BRW_WRITE_BREAK 1 -#define OCD_BRW_ANY_ACCES_BREAK 2 - -/* Constants for BWC3A:BWE */ -#define OCD_BWE_DISABLED 0 -#define OCD_BWE_BREAKPOINT_ENABLED 1 -#define OCD_BWE_WATCHPOINT_ENABLED 3 - -/* Constants for BWC3B:SIZE */ -#define OCD_SIZE_BYTE_ACCESS 4 -#define OCD_SIZE_HALFWORD_ACCESS 5 -#define OCD_SIZE_WORD_ACCESS 6 -#define OCD_SIZE_DOUBLE_WORD_ACCESS 7 - -/* Constants for BWC3B:BRW */ -#define OCD_BRW_READ_BREAK 0 -#define OCD_BRW_WRITE_BREAK 1 -#define OCD_BRW_ANY_ACCES_BREAK 2 - -/* Constants for BWC3B:BWE */ -#define OCD_BWE_DISABLED 0 -#define OCD_BWE_BREAKPOINT_ENABLED 1 -#define OCD_BWE_WATCHPOINT_ENABLED 3 - -/* Constants for EPC0:RNG */ -#define OCD_RNG_DISABLED 0 -#define OCD_RNG_EXCLUSIVE 1 -#define OCD_RNG_INCLUSIVE 2 - -/* Constants for EPC1:RNG */ -#define OCD_RNG_DISABLED 0 -#define OCD_RNG_EXCLUSIVE 1 -#define OCD_RNG_INCLUSIVE 2 - -/* Constants for EPC2:RNG */ -#define OCD_RNG_DISABLED 0 -#define OCD_RNG_EXCLUSIVE 1 -#define OCD_RNG_INCLUSIVE 2 - -/* Constants for EPC2:DB */ -#define OCD_DB_DISABLED 0 -#define OCD_DB_CHAINED_B 1 -#define OCD_DB_CHAINED_A 2 -#define OCD_DB_AHAINED_A_AND_B 3 - -/* Constants for EPC3:RNG */ -#define OCD_RNG_DISABLED 0 -#define OCD_RNG_EXCLUSIVE 1 -#define OCD_RNG_INCLUSIVE 2 - -#ifndef __ASSEMBLER__ - -/* Register access macros */ -static inline unsigned long __ocd_read(unsigned int reg) -{ - return __builtin_mfdr(reg); -} - -static inline void __ocd_write(unsigned int reg, unsigned long value) -{ - __builtin_mtdr(reg, value); -} - -#define ocd_read(reg) __ocd_read(OCD_##reg) -#define ocd_write(reg, value) __ocd_write(OCD_##reg, value) - -struct task_struct; - -void ocd_enable(struct task_struct *child); -void ocd_disable(struct task_struct *child); - -#endif /* !__ASSEMBLER__ */ - -#endif /* __ASM_AVR32_OCD_H */ diff --git a/arch/avr32/include/asm/page.h b/arch/avr32/include/asm/page.h deleted file mode 100644 index c5d2a3e2c62f..000000000000 --- a/arch/avr32/include/asm/page.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_PAGE_H -#define __ASM_AVR32_PAGE_H - -#include <linux/const.h> - -/* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) -#define PTE_MASK PAGE_MASK - -#ifndef __ASSEMBLY__ - -#include <asm/addrspace.h> - -extern void clear_page(void *to); -extern void copy_page(void *to, void *from); - -#define clear_user_page(page, vaddr, pg) clear_page(page) -#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) - -/* - * These are used to make use of C type-checking.. - */ -typedef struct { unsigned long pte; } pte_t; -typedef struct { unsigned long pgd; } pgd_t; -typedef struct { unsigned long pgprot; } pgprot_t; -typedef struct page *pgtable_t; - -#define pte_val(x) ((x).pte) -#define pgd_val(x) ((x).pgd) -#define pgprot_val(x) ((x).pgprot) - -#define __pte(x) ((pte_t) { (x) }) -#define __pgd(x) ((pgd_t) { (x) }) -#define __pgprot(x) ((pgprot_t) { (x) }) - -/* FIXME: These should be removed soon */ -extern unsigned long memory_start, memory_end; - -/* Pure 2^n version of get_order */ -static inline int get_order(unsigned long size) -{ - unsigned lz; - - size = (size - 1) >> PAGE_SHIFT; - asm("clz %0, %1" : "=r"(lz) : "r"(size)); - return 32 - lz; -} - -#endif /* !__ASSEMBLY__ */ - -/* - * The hardware maps the virtual addresses 0x80000000 -> 0x9fffffff - * permanently to the physical addresses 0x00000000 -> 0x1fffffff when - * segmentation is enabled. We want to make use of this in order to - * minimize TLB pressure. - */ -#define PAGE_OFFSET (0x80000000UL) - -/* - * ALSA uses virt_to_page() on DMA pages, which I'm not entirely sure - * is a good idea. Anyway, we can't simply subtract PAGE_OFFSET here - * in that case, so we'll have to mask out the three most significant - * bits of the address instead... - * - * What's the difference between __pa() and virt_to_phys() anyway? - */ -#define __pa(x) PHYSADDR(x) -#define __va(x) ((void *)(P1SEGADDR(x))) - -#define MAP_NR(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT) - -#define phys_to_page(phys) (pfn_to_page(phys >> PAGE_SHIFT)) -#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) - -#ifndef CONFIG_NEED_MULTIPLE_NODES - -#define ARCH_PFN_OFFSET (CONFIG_PHYS_OFFSET >> PAGE_SHIFT) - -#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < (ARCH_PFN_OFFSET + max_mapnr)) -#endif /* CONFIG_NEED_MULTIPLE_NODES */ - -#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) - -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -/* - * Memory above this physical address will be considered highmem. - */ -#define HIGHMEM_START 0x20000000UL - -#include <asm-generic/memory_model.h> - -#endif /* __ASM_AVR32_PAGE_H */ diff --git a/arch/avr32/include/asm/pci.h b/arch/avr32/include/asm/pci.h deleted file mode 100644 index 0f5f134b896a..000000000000 --- a/arch/avr32/include/asm/pci.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __ASM_AVR32_PCI_H__ -#define __ASM_AVR32_PCI_H__ - -/* We don't support PCI yet, but some drivers require this file anyway */ - -#define PCI_DMA_BUS_IS_PHYS (1) - -#endif /* __ASM_AVR32_PCI_H__ */ diff --git a/arch/avr32/include/asm/pgalloc.h b/arch/avr32/include/asm/pgalloc.h deleted file mode 100644 index db039cb368be..000000000000 --- a/arch/avr32/include/asm/pgalloc.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_PGALLOC_H -#define __ASM_AVR32_PGALLOC_H - -#include <linux/mm.h> -#include <linux/quicklist.h> -#include <asm/page.h> -#include <asm/pgtable.h> - -#define QUICK_PGD 0 /* Preserve kernel mappings over free */ -#define QUICK_PT 1 /* Zero on free */ - -static inline void pmd_populate_kernel(struct mm_struct *mm, - pmd_t *pmd, pte_t *pte) -{ - set_pmd(pmd, __pmd((unsigned long)pte)); -} - -static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, - pgtable_t pte) -{ - set_pmd(pmd, __pmd((unsigned long)page_address(pte))); -} -#define pmd_pgtable(pmd) pmd_page(pmd) - -static inline void pgd_ctor(void *x) -{ - pgd_t *pgd = x; - - memcpy(pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); -} - -/* - * Allocate and free page tables - */ -static inline pgd_t *pgd_alloc(struct mm_struct *mm) -{ - return quicklist_alloc(QUICK_PGD, GFP_KERNEL, pgd_ctor); -} - -static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - quicklist_free(QUICK_PGD, NULL, pgd); -} - -static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, - unsigned long address) -{ - return quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL); -} - -static inline pgtable_t pte_alloc_one(struct mm_struct *mm, - unsigned long address) -{ - struct page *page; - void *pg; - - pg = quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL); - if (!pg) - return NULL; - - page = virt_to_page(pg); - if (!pgtable_page_ctor(page)) { - quicklist_free(QUICK_PT, NULL, pg); - return NULL; - } - - return page; -} - -static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) -{ - quicklist_free(QUICK_PT, NULL, pte); -} - -static inline void pte_free(struct mm_struct *mm, pgtable_t pte) -{ - pgtable_page_dtor(pte); - quicklist_free_page(QUICK_PT, NULL, pte); -} - -#define __pte_free_tlb(tlb,pte,addr) \ -do { \ - pgtable_page_dtor(pte); \ - tlb_remove_page((tlb), pte); \ -} while (0) - -static inline void check_pgt_cache(void) -{ - quicklist_trim(QUICK_PGD, NULL, 25, 16); - quicklist_trim(QUICK_PT, NULL, 25, 16); -} - -#endif /* __ASM_AVR32_PGALLOC_H */ diff --git a/arch/avr32/include/asm/pgtable-2level.h b/arch/avr32/include/asm/pgtable-2level.h deleted file mode 100644 index d5b1c63993ec..000000000000 --- a/arch/avr32/include/asm/pgtable-2level.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_PGTABLE_2LEVEL_H -#define __ASM_AVR32_PGTABLE_2LEVEL_H - -#define __ARCH_USE_5LEVEL_HACK -#include <asm-generic/pgtable-nopmd.h> - -/* - * Traditional 2-level paging structure - */ -#define PGDIR_SHIFT 22 -#define PTRS_PER_PGD 1024 - -#define PTRS_PER_PTE 1024 - -#ifndef __ASSEMBLY__ -#define pte_ERROR(e) \ - printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) -#define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) - -/* - * Certain architectures need to do special things when PTEs - * within a page table are directly modified. Thus, the following - * hook is made available. - */ -#define set_pte(pteptr, pteval) (*(pteptr) = pteval) -#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep, pteval) - -/* - * (pmds are folded into pgds so this doesn't get actually called, - * but the define is needed for a generic inline function.) - */ -#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) - -#define pte_pfn(x) ((unsigned long)(((x).pte >> PAGE_SHIFT))) -#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) -#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) - -#endif /* !__ASSEMBLY__ */ - -#endif /* __ASM_AVR32_PGTABLE_2LEVEL_H */ diff --git a/arch/avr32/include/asm/pgtable.h b/arch/avr32/include/asm/pgtable.h deleted file mode 100644 index 35800664076e..000000000000 --- a/arch/avr32/include/asm/pgtable.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_PGTABLE_H -#define __ASM_AVR32_PGTABLE_H - -#include <asm/addrspace.h> - -#ifndef __ASSEMBLY__ -#include <linux/sched.h> - -#endif /* !__ASSEMBLY__ */ - -/* - * Use two-level page tables just as the i386 (without PAE) - */ -#include <asm/pgtable-2level.h> - -/* - * The following code might need some cleanup when the values are - * final... - */ -#define PMD_SIZE (1UL << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE-1)) -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE-1)) - -#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) -#define FIRST_USER_ADDRESS 0UL - -#ifndef __ASSEMBLY__ -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -extern void paging_init(void); - -/* - * ZERO_PAGE is a global shared page that is always zero: used for - * zero-mapped memory areas etc. - */ -extern struct page *empty_zero_page; -#define ZERO_PAGE(vaddr) (empty_zero_page) - -/* - * Just any arbitrary offset to the start of the vmalloc VM area: the - * current 8 MiB value just means that there will be a 8 MiB "hole" - * after the uncached physical memory (P2 segment) until the vmalloc - * area starts. That means that any out-of-bounds memory accesses will - * hopefully be caught; we don't know if the end of the P1/P2 segments - * are actually used for anything, but it is anyway safer to let the - * MMU catch these kinds of errors than to rely on the memory bus. - * - * A "hole" of the same size is added to the end of the P3 segment as - * well. It might seem wasteful to use 16 MiB of virtual address space - * on this, but we do have 512 MiB of it... - * - * The vmalloc() routines leave a hole of 4 KiB between each vmalloced - * area for the same reason. - */ -#define VMALLOC_OFFSET (8 * 1024 * 1024) -#define VMALLOC_START (P3SEG + VMALLOC_OFFSET) -#define VMALLOC_END (P4SEG - VMALLOC_OFFSET) -#endif /* !__ASSEMBLY__ */ - -/* - * Page flags. Some of these flags are not directly supported by - * hardware, so we have to emulate them. - */ -#define _TLBEHI_BIT_VALID 9 -#define _TLBEHI_VALID (1 << _TLBEHI_BIT_VALID) - -#define _PAGE_BIT_WT 0 /* W-bit : write-through */ -#define _PAGE_BIT_DIRTY 1 /* D-bit : page changed */ -#define _PAGE_BIT_SZ0 2 /* SZ0-bit : Size of page */ -#define _PAGE_BIT_SZ1 3 /* SZ1-bit : Size of page */ -#define _PAGE_BIT_EXECUTE 4 /* X-bit : execute access allowed */ -#define _PAGE_BIT_RW 5 /* AP0-bit : write access allowed */ -#define _PAGE_BIT_USER 6 /* AP1-bit : user space access allowed */ -#define _PAGE_BIT_BUFFER 7 /* B-bit : bufferable */ -#define _PAGE_BIT_GLOBAL 8 /* G-bit : global (ignore ASID) */ -#define _PAGE_BIT_CACHABLE 9 /* C-bit : cachable */ - -/* If we drop support for 1K pages, we get two extra bits */ -#define _PAGE_BIT_PRESENT 10 -#define _PAGE_BIT_ACCESSED 11 /* software: page was accessed */ - -#define _PAGE_WT (1 << _PAGE_BIT_WT) -#define _PAGE_DIRTY (1 << _PAGE_BIT_DIRTY) -#define _PAGE_EXECUTE (1 << _PAGE_BIT_EXECUTE) -#define _PAGE_RW (1 << _PAGE_BIT_RW) -#define _PAGE_USER (1 << _PAGE_BIT_USER) -#define _PAGE_BUFFER (1 << _PAGE_BIT_BUFFER) -#define _PAGE_GLOBAL (1 << _PAGE_BIT_GLOBAL) -#define _PAGE_CACHABLE (1 << _PAGE_BIT_CACHABLE) - -/* Software flags */ -#define _PAGE_ACCESSED (1 << _PAGE_BIT_ACCESSED) -#define _PAGE_PRESENT (1 << _PAGE_BIT_PRESENT) - -/* - * Page types, i.e. sizes. _PAGE_TYPE_NONE corresponds to what is - * usually called _PAGE_PROTNONE on other architectures. - * - * XXX: Find out if _PAGE_PROTNONE is equivalent with !_PAGE_USER. If - * so, we can encode all possible page sizes (although we can't really - * support 1K pages anyway due to the _PAGE_PRESENT and _PAGE_ACCESSED - * bits) - * - */ -#define _PAGE_TYPE_MASK ((1 << _PAGE_BIT_SZ0) | (1 << _PAGE_BIT_SZ1)) -#define _PAGE_TYPE_NONE (0 << _PAGE_BIT_SZ0) -#define _PAGE_TYPE_SMALL (1 << _PAGE_BIT_SZ0) -#define _PAGE_TYPE_MEDIUM (2 << _PAGE_BIT_SZ0) -#define _PAGE_TYPE_LARGE (3 << _PAGE_BIT_SZ0) - -/* - * Mask which drop software flags. We currently can't handle more than - * 512 MiB of physical memory, so we can use bits 29-31 for other - * stuff. With a fixed 4K page size, we can use bits 10-11 as well as - * bits 2-3 (SZ) - */ -#define _PAGE_FLAGS_HARDWARE_MASK 0xfffff3ff - -#define _PAGE_FLAGS_CACHE_MASK (_PAGE_CACHABLE | _PAGE_BUFFER | _PAGE_WT) - -/* Flags that may be modified by software */ -#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY \ - | _PAGE_FLAGS_CACHE_MASK) - -#define _PAGE_FLAGS_READ (_PAGE_CACHABLE | _PAGE_BUFFER) -#define _PAGE_FLAGS_WRITE (_PAGE_FLAGS_READ | _PAGE_RW | _PAGE_DIRTY) - -#define _PAGE_NORMAL(x) __pgprot((x) | _PAGE_PRESENT | _PAGE_TYPE_SMALL \ - | _PAGE_ACCESSED) - -#define PAGE_NONE (_PAGE_ACCESSED | _PAGE_TYPE_NONE) -#define PAGE_READ (_PAGE_FLAGS_READ | _PAGE_USER) -#define PAGE_EXEC (_PAGE_FLAGS_READ | _PAGE_EXECUTE | _PAGE_USER) -#define PAGE_WRITE (_PAGE_FLAGS_WRITE | _PAGE_USER) -#define PAGE_KERNEL _PAGE_NORMAL(_PAGE_FLAGS_WRITE | _PAGE_EXECUTE | _PAGE_GLOBAL) -#define PAGE_KERNEL_RO _PAGE_NORMAL(_PAGE_FLAGS_READ | _PAGE_EXECUTE | _PAGE_GLOBAL) - -#define _PAGE_P(x) _PAGE_NORMAL((x) & ~(_PAGE_RW | _PAGE_DIRTY)) -#define _PAGE_S(x) _PAGE_NORMAL(x) - -#define PAGE_COPY _PAGE_P(PAGE_WRITE | PAGE_READ) -#define PAGE_SHARED _PAGE_S(PAGE_WRITE | PAGE_READ) - -#ifndef __ASSEMBLY__ -/* - * The hardware supports flags for write- and execute access. Read is - * always allowed if the page is loaded into the TLB, so the "-w-", - * "--x" and "-wx" mappings are implemented as "rw-", "r-x" and "rwx", - * respectively. - * - * The "---" case is handled by software; the page will simply not be - * loaded into the TLB if the page type is _PAGE_TYPE_NONE. - */ - -#define __P000 __pgprot(PAGE_NONE) -#define __P001 _PAGE_P(PAGE_READ) -#define __P010 _PAGE_P(PAGE_WRITE) -#define __P011 _PAGE_P(PAGE_WRITE | PAGE_READ) -#define __P100 _PAGE_P(PAGE_EXEC) -#define __P101 _PAGE_P(PAGE_EXEC | PAGE_READ) -#define __P110 _PAGE_P(PAGE_EXEC | PAGE_WRITE) -#define __P111 _PAGE_P(PAGE_EXEC | PAGE_WRITE | PAGE_READ) - -#define __S000 __pgprot(PAGE_NONE) -#define __S001 _PAGE_S(PAGE_READ) -#define __S010 _PAGE_S(PAGE_WRITE) -#define __S011 _PAGE_S(PAGE_WRITE | PAGE_READ) -#define __S100 _PAGE_S(PAGE_EXEC) -#define __S101 _PAGE_S(PAGE_EXEC | PAGE_READ) -#define __S110 _PAGE_S(PAGE_EXEC | PAGE_WRITE) -#define __S111 _PAGE_S(PAGE_EXEC | PAGE_WRITE | PAGE_READ) - -#define pte_none(x) (!pte_val(x)) -#define pte_present(x) (pte_val(x) & _PAGE_PRESENT) - -#define pte_clear(mm,addr,xp) \ - do { \ - set_pte_at(mm, addr, xp, __pte(0)); \ - } while (0) - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -static inline int pte_write(pte_t pte) -{ - return pte_val(pte) & _PAGE_RW; -} -static inline int pte_dirty(pte_t pte) -{ - return pte_val(pte) & _PAGE_DIRTY; -} -static inline int pte_young(pte_t pte) -{ - return pte_val(pte) & _PAGE_ACCESSED; -} -static inline int pte_special(pte_t pte) -{ - return 0; -} - -/* Mutator functions for PTE bits */ -static inline pte_t pte_wrprotect(pte_t pte) -{ - set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); - return pte; -} -static inline pte_t pte_mkclean(pte_t pte) -{ - set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); - return pte; -} -static inline pte_t pte_mkold(pte_t pte) -{ - set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); - return pte; -} -static inline pte_t pte_mkwrite(pte_t pte) -{ - set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); - return pte; -} -static inline pte_t pte_mkdirty(pte_t pte) -{ - set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); - return pte; -} -static inline pte_t pte_mkyoung(pte_t pte) -{ - set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); - return pte; -} -static inline pte_t pte_mkspecial(pte_t pte) -{ - return pte; -} - -#define pmd_none(x) (!pmd_val(x)) -#define pmd_present(x) (pmd_val(x)) - -static inline void pmd_clear(pmd_t *pmdp) -{ - set_pmd(pmdp, __pmd(0)); -} - -#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK) - -/* - * Permanent address of a page. We don't support highmem, so this is - * trivial. - */ -#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) -#define pte_page(x) (pfn_to_page(pte_pfn(x))) - -/* - * Mark the prot value as uncacheable and unbufferable - */ -#define pgprot_noncached(prot) \ - __pgprot(pgprot_val(prot) & ~(_PAGE_BUFFER | _PAGE_CACHABLE)) - -/* - * Mark the prot value as uncacheable but bufferable - */ -#define pgprot_writecombine(prot) \ - __pgprot((pgprot_val(prot) & ~_PAGE_CACHABLE) | _PAGE_BUFFER) - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - * - * extern pte_t mk_pte(struct page *page, pgprot_t pgprot) - */ -#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) - -static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) - | pgprot_val(newprot))); - return pte; -} - -#define page_pte(page) page_pte_prot(page, __pgprot(0)) - -#define pmd_page_vaddr(pmd) pmd_val(pmd) -#define pmd_page(pmd) (virt_to_page(pmd_val(pmd))) - -/* to find an entry in a page-table-directory. */ -#define pgd_index(address) (((address) >> PGDIR_SHIFT) \ - & (PTRS_PER_PGD - 1)) -#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) - -/* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k(address) pgd_offset(&init_mm, address) - -/* Find an entry in the third-level page table.. */ -#define pte_index(address) \ - ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) -#define pte_offset(dir, address) \ - ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address)) -#define pte_offset_kernel(dir, address) \ - ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address)) -#define pte_offset_map(dir, address) pte_offset_kernel(dir, address) -#define pte_unmap(pte) do { } while (0) - -struct vm_area_struct; -extern void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t *ptep); - -/* - * Encode and decode a swap entry - * - * Constraints: - * _PAGE_TYPE_* at bits 2-3 (for emulating _PAGE_PROTNONE) - * _PAGE_PRESENT at bit 10 - * - * We encode the type into bits 4-9 and offset into bits 11-31. This - * gives us a 21 bits offset, or 2**21 * 4K = 8G usable swap space per - * device, and 64 possible types. - * - * NOTE: We should set ZEROs at the position of _PAGE_PRESENT - * and _PAGE_PROTNONE bits - */ -#define __swp_type(x) (((x).val >> 4) & 0x3f) -#define __swp_offset(x) ((x).val >> 11) -#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 4) | ((offset) << 11) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) - -typedef pte_t *pte_addr_t; - -#define kern_addr_valid(addr) (1) - -/* No page table caches to initialize (?) */ -#define pgtable_cache_init() do { } while(0) - -#include <asm-generic/pgtable.h> - -#endif /* !__ASSEMBLY__ */ - -#endif /* __ASM_AVR32_PGTABLE_H */ diff --git a/arch/avr32/include/asm/processor.h b/arch/avr32/include/asm/processor.h deleted file mode 100644 index 972adcc1e8f4..000000000000 --- a/arch/avr32/include/asm/processor.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_PROCESSOR_H -#define __ASM_AVR32_PROCESSOR_H - -#include <asm/page.h> -#include <asm/cache.h> - -#define TASK_SIZE 0x80000000 - -#ifdef __KERNEL__ -#define STACK_TOP TASK_SIZE -#define STACK_TOP_MAX STACK_TOP -#endif - -#ifndef __ASSEMBLY__ - -static inline void *current_text_addr(void) -{ - register void *pc asm("pc"); - return pc; -} - -enum arch_type { - ARCH_AVR32A, - ARCH_AVR32B, - ARCH_MAX -}; - -enum cpu_type { - CPU_MORGAN, - CPU_AT32AP, - CPU_MAX -}; - -enum tlb_config { - TLB_NONE, - TLB_SPLIT, - TLB_UNIFIED, - TLB_INVALID -}; - -#define AVR32_FEATURE_RMW (1 << 0) -#define AVR32_FEATURE_DSP (1 << 1) -#define AVR32_FEATURE_SIMD (1 << 2) -#define AVR32_FEATURE_OCD (1 << 3) -#define AVR32_FEATURE_PCTR (1 << 4) -#define AVR32_FEATURE_JAVA (1 << 5) -#define AVR32_FEATURE_FPU (1 << 6) - -struct avr32_cpuinfo { - struct clk *clk; - unsigned long loops_per_jiffy; - enum arch_type arch_type; - enum cpu_type cpu_type; - unsigned short arch_revision; - unsigned short cpu_revision; - enum tlb_config tlb_config; - unsigned long features; - u32 device_id; - - struct cache_info icache; - struct cache_info dcache; -}; - -static inline unsigned int avr32_get_manufacturer_id(struct avr32_cpuinfo *cpu) -{ - return (cpu->device_id >> 1) & 0x7f; -} -static inline unsigned int avr32_get_product_number(struct avr32_cpuinfo *cpu) -{ - return (cpu->device_id >> 12) & 0xffff; -} -static inline unsigned int avr32_get_chip_revision(struct avr32_cpuinfo *cpu) -{ - return (cpu->device_id >> 28) & 0x0f; -} - -extern struct avr32_cpuinfo boot_cpu_data; - -/* No SMP support so far */ -#define current_cpu_data boot_cpu_data - -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's - */ -#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) - -#define cpu_relax() barrier() -#define cpu_sync_pipeline() asm volatile("sub pc, -2" : : : "memory") - -struct cpu_context { - unsigned long sr; - unsigned long pc; - unsigned long ksp; /* Kernel stack pointer */ - unsigned long r7; - unsigned long r6; - unsigned long r5; - unsigned long r4; - unsigned long r3; - unsigned long r2; - unsigned long r1; - unsigned long r0; -}; - -/* This struct contains the CPU context as stored by switch_to() */ -struct thread_struct { - struct cpu_context cpu_context; - unsigned long single_step_addr; - u16 single_step_insn; -}; - -#define INIT_THREAD { \ - .cpu_context = { \ - .ksp = sizeof(init_stack) + (long)&init_stack, \ - }, \ -} - -/* - * Do necessary setup to start up a newly executed thread. - */ -#define start_thread(regs, new_pc, new_sp) \ - do { \ - memset(regs, 0, sizeof(*regs)); \ - regs->sr = MODE_USER; \ - regs->pc = new_pc & ~1; \ - regs->sp = new_sp; \ - } while(0) - -struct task_struct; - -/* Free all resources held by a thread */ -extern void release_thread(struct task_struct *); - -/* Return saved PC of a blocked thread */ -#define thread_saved_pc(tsk) ((tsk)->thread.cpu_context.pc) - -struct pt_regs; -extern unsigned long get_wchan(struct task_struct *p); -extern void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl); -extern void show_stack_log_lvl(struct task_struct *tsk, unsigned long sp, - struct pt_regs *regs, const char *log_lvl); - -#define task_pt_regs(p) \ - ((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1) - -#define KSTK_EIP(tsk) ((tsk)->thread.cpu_context.pc) -#define KSTK_ESP(tsk) ((tsk)->thread.cpu_context.ksp) - -#define ARCH_HAS_PREFETCH - -static inline void prefetch(const void *x) -{ - const char *c = x; - asm volatile("pref %0" : : "r"(c)); -} -#define PREFETCH_STRIDE L1_CACHE_BYTES - -#endif /* __ASSEMBLY__ */ - -#endif /* __ASM_AVR32_PROCESSOR_H */ diff --git a/arch/avr32/include/asm/ptrace.h b/arch/avr32/include/asm/ptrace.h deleted file mode 100644 index 630e4f9bf5f0..000000000000 --- a/arch/avr32/include/asm/ptrace.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_PTRACE_H -#define __ASM_AVR32_PTRACE_H - -#include <uapi/asm/ptrace.h> - -#ifndef __ASSEMBLY__ - -#include <asm/ocd.h> - -#define arch_has_single_step() (1) - -#define arch_ptrace_attach(child) ocd_enable(child) - -#define user_mode(regs) (((regs)->sr & MODE_MASK) == MODE_USER) -#define instruction_pointer(regs) ((regs)->pc) -#define profile_pc(regs) instruction_pointer(regs) -#define user_stack_pointer(regs) ((regs)->sp) - -static __inline__ int valid_user_regs(struct pt_regs *regs) -{ - /* - * Some of the Java bits might be acceptable if/when we - * implement some support for that stuff... - */ - if ((regs->sr & 0xffff0000) == 0) - return 1; - - /* - * Force status register flags to be sane and report this - * illegal behaviour... - */ - regs->sr &= 0x0000ffff; - return 0; -} - - -#endif /* ! __ASSEMBLY__ */ -#endif /* __ASM_AVR32_PTRACE_H */ diff --git a/arch/avr32/include/asm/serial.h b/arch/avr32/include/asm/serial.h deleted file mode 100644 index 5ecaebc22b02..000000000000 --- a/arch/avr32/include/asm/serial.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _ASM_SERIAL_H -#define _ASM_SERIAL_H - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD (1843200 / 16) - -#endif /* _ASM_SERIAL_H */ diff --git a/arch/avr32/include/asm/setup.h b/arch/avr32/include/asm/setup.h deleted file mode 100644 index 73490ae0c476..000000000000 --- a/arch/avr32/include/asm/setup.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * Based on linux/include/asm-arm/setup.h - * Copyright (C) 1997-1999 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_SETUP_H__ -#define __ASM_AVR32_SETUP_H__ - -#include <uapi/asm/setup.h> - - -/* Magic number indicating that a tag table is present */ -#define ATAG_MAGIC 0xa2a25441 - -#ifndef __ASSEMBLY__ - -/* - * Generic memory range, used by several tags. - * - * addr is always physical. - * size is measured in bytes. - * next is for use by the OS, e.g. for grouping regions into - * linked lists. - */ -struct tag_mem_range { - u32 addr; - u32 size; - struct tag_mem_range * next; -}; - -/* The list ends with an ATAG_NONE node. */ -#define ATAG_NONE 0x00000000 - -struct tag_header { - u32 size; - u32 tag; -}; - -/* The list must start with an ATAG_CORE node */ -#define ATAG_CORE 0x54410001 - -struct tag_core { - u32 flags; - u32 pagesize; - u32 rootdev; -}; - -/* it is allowed to have multiple ATAG_MEM nodes */ -#define ATAG_MEM 0x54410002 -/* ATAG_MEM uses tag_mem_range */ - -/* command line: \0 terminated string */ -#define ATAG_CMDLINE 0x54410003 - -struct tag_cmdline { - char cmdline[1]; /* this is the minimum size */ -}; - -/* Ramdisk image (may be compressed) */ -#define ATAG_RDIMG 0x54410004 -/* ATAG_RDIMG uses tag_mem_range */ - -/* Information about various clocks present in the system */ -#define ATAG_CLOCK 0x54410005 - -struct tag_clock { - u32 clock_id; /* Which clock are we talking about? */ - u32 clock_flags; /* Special features */ - u64 clock_hz; /* Clock speed in Hz */ -}; - -/* The clock types we know about */ -#define CLOCK_BOOTCPU 0 - -/* Memory reserved for the system (e.g. the bootloader) */ -#define ATAG_RSVD_MEM 0x54410006 -/* ATAG_RSVD_MEM uses tag_mem_range */ - -/* Ethernet information */ - -#define ATAG_ETHERNET 0x54410007 - -struct tag_ethernet { - u8 mac_index; - u8 mii_phy_addr; - u8 hw_address[6]; -}; - -#define ETH_INVALID_PHY 0xff - -/* board information */ -#define ATAG_BOARDINFO 0x54410008 - -struct tag_boardinfo { - u32 board_number; -}; - -struct tag { - struct tag_header hdr; - union { - struct tag_core core; - struct tag_mem_range mem_range; - struct tag_cmdline cmdline; - struct tag_clock clock; - struct tag_ethernet ethernet; - struct tag_boardinfo boardinfo; - } u; -}; - -struct tagtable { - u32 tag; - int (*parse)(struct tag *); -}; - -#define __tag __used __attribute__((__section__(".taglist.init"))) -#define __tagtable(tag, fn) \ - static struct tagtable __tagtable_##fn __tag = { tag, fn } - -#define tag_member_present(tag,member) \ - ((unsigned long)(&((struct tag *)0L)->member + 1) \ - <= (tag)->hdr.size * 4) - -#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size)) -#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2) - -#define for_each_tag(t,base) \ - for (t = base; t->hdr.size; t = tag_next(t)) - -extern struct tag *bootloader_tags; - -extern resource_size_t fbmem_start; -extern resource_size_t fbmem_size; -extern u32 board_number; - -void setup_processor(void); - -#endif /* !__ASSEMBLY__ */ - -#endif /* __ASM_AVR32_SETUP_H__ */ diff --git a/arch/avr32/include/asm/shmparam.h b/arch/avr32/include/asm/shmparam.h deleted file mode 100644 index 3681266c77f7..000000000000 --- a/arch/avr32/include/asm/shmparam.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_SHMPARAM_H -#define __ASM_AVR32_SHMPARAM_H - -#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ - -#endif /* __ASM_AVR32_SHMPARAM_H */ diff --git a/arch/avr32/include/asm/signal.h b/arch/avr32/include/asm/signal.h deleted file mode 100644 index d875eb6a3f3c..000000000000 --- a/arch/avr32/include/asm/signal.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_SIGNAL_H -#define __ASM_AVR32_SIGNAL_H - -#include <uapi/asm/signal.h> - -/* Most things should be clean enough to redefine this at will, if care - is taken to make libc match. */ - -#define _NSIG 64 -#define _NSIG_BPW 32 -#define _NSIG_WORDS (_NSIG / _NSIG_BPW) - -typedef unsigned long old_sigset_t; /* at least 32 bits */ - -typedef struct { - unsigned long sig[_NSIG_WORDS]; -} sigset_t; - -#define __ARCH_HAS_SA_RESTORER - -#include <asm/sigcontext.h> -#undef __HAVE_ARCH_SIG_BITOPS - -#endif diff --git a/arch/avr32/include/asm/string.h b/arch/avr32/include/asm/string.h deleted file mode 100644 index c91a623cd585..000000000000 --- a/arch/avr32/include/asm/string.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_STRING_H -#define __ASM_AVR32_STRING_H - -#define __HAVE_ARCH_MEMSET -extern void *memset(void *b, int c, size_t len); - -#define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *to, const void *from, size_t len); - -#endif /* __ASM_AVR32_STRING_H */ diff --git a/arch/avr32/include/asm/switch_to.h b/arch/avr32/include/asm/switch_to.h deleted file mode 100644 index 6f00581c3d4f..000000000000 --- a/arch/avr32/include/asm/switch_to.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_SWITCH_TO_H -#define __ASM_AVR32_SWITCH_TO_H - -/* - * Help PathFinder and other Nexus-compliant debuggers keep track of - * the current PID by emitting an Ownership Trace Message each time we - * switch task. - */ -#ifdef CONFIG_OWNERSHIP_TRACE -#include <asm/ocd.h> -#define ocd_switch(prev, next) \ - do { \ - ocd_write(PID, prev->pid); \ - ocd_write(PID, next->pid); \ - } while(0) -#else -#define ocd_switch(prev, next) -#endif - -/* - * switch_to(prev, next, last) should switch from task `prev' to task - * `next'. `prev' will never be the same as `next'. - * - * We just delegate everything to the __switch_to assembly function, - * which is implemented in arch/avr32/kernel/switch_to.S - * - * mb() tells GCC not to cache `current' across this call. - */ -struct cpu_context; -struct task_struct; -extern struct task_struct *__switch_to(struct task_struct *, - struct cpu_context *, - struct cpu_context *); -#define switch_to(prev, next, last) \ - do { \ - ocd_switch(prev, next); \ - last = __switch_to(prev, &prev->thread.cpu_context + 1, \ - &next->thread.cpu_context); \ - } while (0) - - -#endif /* __ASM_AVR32_SWITCH_TO_H */ diff --git a/arch/avr32/include/asm/syscalls.h b/arch/avr32/include/asm/syscalls.h deleted file mode 100644 index 244f2acab546..000000000000 --- a/arch/avr32/include/asm/syscalls.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * syscalls.h - Linux syscall interfaces (arch-specific) - * - * Copyright (c) 2008 Jaswinder Singh - * - * This file is released under the GPLv2. - * See the file COPYING for more details. - */ - -#ifndef _ASM_AVR32_SYSCALLS_H -#define _ASM_AVR32_SYSCALLS_H - -#include <linux/compiler.h> -#include <linux/linkage.h> -#include <linux/types.h> -#include <linux/signal.h> - -/* mm/cache.c */ -asmlinkage int sys_cacheflush(int, void __user *, size_t); - -#endif /* _ASM_AVR32_SYSCALLS_H */ diff --git a/arch/avr32/include/asm/sysreg.h b/arch/avr32/include/asm/sysreg.h deleted file mode 100644 index d4e0950170ca..000000000000 --- a/arch/avr32/include/asm/sysreg.h +++ /dev/null @@ -1,291 +0,0 @@ -/* - * AVR32 System Registers - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_SYSREG_H -#define __ASM_AVR32_SYSREG_H - -/* sysreg register offsets */ -#define SYSREG_SR 0x0000 -#define SYSREG_EVBA 0x0004 -#define SYSREG_ACBA 0x0008 -#define SYSREG_CPUCR 0x000c -#define SYSREG_ECR 0x0010 -#define SYSREG_RSR_SUP 0x0014 -#define SYSREG_RSR_INT0 0x0018 -#define SYSREG_RSR_INT1 0x001c -#define SYSREG_RSR_INT2 0x0020 -#define SYSREG_RSR_INT3 0x0024 -#define SYSREG_RSR_EX 0x0028 -#define SYSREG_RSR_NMI 0x002c -#define SYSREG_RSR_DBG 0x0030 -#define SYSREG_RAR_SUP 0x0034 -#define SYSREG_RAR_INT0 0x0038 -#define SYSREG_RAR_INT1 0x003c -#define SYSREG_RAR_INT2 0x0040 -#define SYSREG_RAR_INT3 0x0044 -#define SYSREG_RAR_EX 0x0048 -#define SYSREG_RAR_NMI 0x004c -#define SYSREG_RAR_DBG 0x0050 -#define SYSREG_JECR 0x0054 -#define SYSREG_JOSP 0x0058 -#define SYSREG_JAVA_LV0 0x005c -#define SYSREG_JAVA_LV1 0x0060 -#define SYSREG_JAVA_LV2 0x0064 -#define SYSREG_JAVA_LV3 0x0068 -#define SYSREG_JAVA_LV4 0x006c -#define SYSREG_JAVA_LV5 0x0070 -#define SYSREG_JAVA_LV6 0x0074 -#define SYSREG_JAVA_LV7 0x0078 -#define SYSREG_JTBA 0x007c -#define SYSREG_JBCR 0x0080 -#define SYSREG_CONFIG0 0x0100 -#define SYSREG_CONFIG1 0x0104 -#define SYSREG_COUNT 0x0108 -#define SYSREG_COMPARE 0x010c -#define SYSREG_TLBEHI 0x0110 -#define SYSREG_TLBELO 0x0114 -#define SYSREG_PTBR 0x0118 -#define SYSREG_TLBEAR 0x011c -#define SYSREG_MMUCR 0x0120 -#define SYSREG_TLBARLO 0x0124 -#define SYSREG_TLBARHI 0x0128 -#define SYSREG_PCCNT 0x012c -#define SYSREG_PCNT0 0x0130 -#define SYSREG_PCNT1 0x0134 -#define SYSREG_PCCR 0x0138 -#define SYSREG_BEAR 0x013c -#define SYSREG_SABAL 0x0300 -#define SYSREG_SABAH 0x0304 -#define SYSREG_SABD 0x0308 - -/* Bitfields in SR */ -#define SYSREG_SR_C_OFFSET 0 -#define SYSREG_SR_C_SIZE 1 -#define SYSREG_Z_OFFSET 1 -#define SYSREG_Z_SIZE 1 -#define SYSREG_SR_N_OFFSET 2 -#define SYSREG_SR_N_SIZE 1 -#define SYSREG_SR_V_OFFSET 3 -#define SYSREG_SR_V_SIZE 1 -#define SYSREG_Q_OFFSET 4 -#define SYSREG_Q_SIZE 1 -#define SYSREG_L_OFFSET 5 -#define SYSREG_L_SIZE 1 -#define SYSREG_T_OFFSET 14 -#define SYSREG_T_SIZE 1 -#define SYSREG_SR_R_OFFSET 15 -#define SYSREG_SR_R_SIZE 1 -#define SYSREG_GM_OFFSET 16 -#define SYSREG_GM_SIZE 1 -#define SYSREG_I0M_OFFSET 17 -#define SYSREG_I0M_SIZE 1 -#define SYSREG_I1M_OFFSET 18 -#define SYSREG_I1M_SIZE 1 -#define SYSREG_I2M_OFFSET 19 -#define SYSREG_I2M_SIZE 1 -#define SYSREG_I3M_OFFSET 20 -#define SYSREG_I3M_SIZE 1 -#define SYSREG_EM_OFFSET 21 -#define SYSREG_EM_SIZE 1 -#define SYSREG_MODE_OFFSET 22 -#define SYSREG_MODE_SIZE 3 -#define SYSREG_M0_OFFSET 22 -#define SYSREG_M0_SIZE 1 -#define SYSREG_M1_OFFSET 23 -#define SYSREG_M1_SIZE 1 -#define SYSREG_M2_OFFSET 24 -#define SYSREG_M2_SIZE 1 -#define SYSREG_SR_D_OFFSET 26 -#define SYSREG_SR_D_SIZE 1 -#define SYSREG_DM_OFFSET 27 -#define SYSREG_DM_SIZE 1 -#define SYSREG_SR_J_OFFSET 28 -#define SYSREG_SR_J_SIZE 1 -#define SYSREG_H_OFFSET 29 -#define SYSREG_H_SIZE 1 - -/* Bitfields in CPUCR */ -#define SYSREG_BI_OFFSET 0 -#define SYSREG_BI_SIZE 1 -#define SYSREG_BE_OFFSET 1 -#define SYSREG_BE_SIZE 1 -#define SYSREG_FE_OFFSET 2 -#define SYSREG_FE_SIZE 1 -#define SYSREG_RE_OFFSET 3 -#define SYSREG_RE_SIZE 1 -#define SYSREG_IBE_OFFSET 4 -#define SYSREG_IBE_SIZE 1 -#define SYSREG_IEE_OFFSET 5 -#define SYSREG_IEE_SIZE 1 - -/* Bitfields in CONFIG0 */ -#define SYSREG_CONFIG0_R_OFFSET 0 -#define SYSREG_CONFIG0_R_SIZE 1 -#define SYSREG_CONFIG0_D_OFFSET 1 -#define SYSREG_CONFIG0_D_SIZE 1 -#define SYSREG_CONFIG0_S_OFFSET 2 -#define SYSREG_CONFIG0_S_SIZE 1 -#define SYSREG_CONFIG0_O_OFFSET 3 -#define SYSREG_CONFIG0_O_SIZE 1 -#define SYSREG_CONFIG0_P_OFFSET 4 -#define SYSREG_CONFIG0_P_SIZE 1 -#define SYSREG_CONFIG0_J_OFFSET 5 -#define SYSREG_CONFIG0_J_SIZE 1 -#define SYSREG_CONFIG0_F_OFFSET 6 -#define SYSREG_CONFIG0_F_SIZE 1 -#define SYSREG_MMUT_OFFSET 7 -#define SYSREG_MMUT_SIZE 3 -#define SYSREG_AR_OFFSET 10 -#define SYSREG_AR_SIZE 3 -#define SYSREG_AT_OFFSET 13 -#define SYSREG_AT_SIZE 3 -#define SYSREG_PROCESSORREVISION_OFFSET 16 -#define SYSREG_PROCESSORREVISION_SIZE 8 -#define SYSREG_PROCESSORID_OFFSET 24 -#define SYSREG_PROCESSORID_SIZE 8 - -/* Bitfields in CONFIG1 */ -#define SYSREG_DASS_OFFSET 0 -#define SYSREG_DASS_SIZE 3 -#define SYSREG_DLSZ_OFFSET 3 -#define SYSREG_DLSZ_SIZE 3 -#define SYSREG_DSET_OFFSET 6 -#define SYSREG_DSET_SIZE 4 -#define SYSREG_IASS_OFFSET 10 -#define SYSREG_IASS_SIZE 3 -#define SYSREG_ILSZ_OFFSET 13 -#define SYSREG_ILSZ_SIZE 3 -#define SYSREG_ISET_OFFSET 16 -#define SYSREG_ISET_SIZE 4 -#define SYSREG_DMMUSZ_OFFSET 20 -#define SYSREG_DMMUSZ_SIZE 6 -#define SYSREG_IMMUSZ_OFFSET 26 -#define SYSREG_IMMUSZ_SIZE 6 - -/* Bitfields in TLBEHI */ -#define SYSREG_ASID_OFFSET 0 -#define SYSREG_ASID_SIZE 8 -#define SYSREG_TLBEHI_I_OFFSET 8 -#define SYSREG_TLBEHI_I_SIZE 1 -#define SYSREG_TLBEHI_V_OFFSET 9 -#define SYSREG_TLBEHI_V_SIZE 1 -#define SYSREG_VPN_OFFSET 10 -#define SYSREG_VPN_SIZE 22 - -/* Bitfields in TLBELO */ -#define SYSREG_W_OFFSET 0 -#define SYSREG_W_SIZE 1 -#define SYSREG_TLBELO_D_OFFSET 1 -#define SYSREG_TLBELO_D_SIZE 1 -#define SYSREG_SZ_OFFSET 2 -#define SYSREG_SZ_SIZE 2 -#define SYSREG_AP_OFFSET 4 -#define SYSREG_AP_SIZE 3 -#define SYSREG_B_OFFSET 7 -#define SYSREG_B_SIZE 1 -#define SYSREG_G_OFFSET 8 -#define SYSREG_G_SIZE 1 -#define SYSREG_TLBELO_C_OFFSET 9 -#define SYSREG_TLBELO_C_SIZE 1 -#define SYSREG_PFN_OFFSET 10 -#define SYSREG_PFN_SIZE 22 - -/* Bitfields in MMUCR */ -#define SYSREG_E_OFFSET 0 -#define SYSREG_E_SIZE 1 -#define SYSREG_M_OFFSET 1 -#define SYSREG_M_SIZE 1 -#define SYSREG_MMUCR_I_OFFSET 2 -#define SYSREG_MMUCR_I_SIZE 1 -#define SYSREG_MMUCR_N_OFFSET 3 -#define SYSREG_MMUCR_N_SIZE 1 -#define SYSREG_MMUCR_S_OFFSET 4 -#define SYSREG_MMUCR_S_SIZE 1 -#define SYSREG_DLA_OFFSET 8 -#define SYSREG_DLA_SIZE 6 -#define SYSREG_DRP_OFFSET 14 -#define SYSREG_DRP_SIZE 6 -#define SYSREG_ILA_OFFSET 20 -#define SYSREG_ILA_SIZE 6 -#define SYSREG_IRP_OFFSET 26 -#define SYSREG_IRP_SIZE 6 - -/* Bitfields in PCCR */ -#define SYSREG_PCCR_E_OFFSET 0 -#define SYSREG_PCCR_E_SIZE 1 -#define SYSREG_PCCR_R_OFFSET 1 -#define SYSREG_PCCR_R_SIZE 1 -#define SYSREG_PCCR_C_OFFSET 2 -#define SYSREG_PCCR_C_SIZE 1 -#define SYSREG_PCCR_S_OFFSET 3 -#define SYSREG_PCCR_S_SIZE 1 -#define SYSREG_IEC_OFFSET 4 -#define SYSREG_IEC_SIZE 1 -#define SYSREG_IE0_OFFSET 5 -#define SYSREG_IE0_SIZE 1 -#define SYSREG_IE1_OFFSET 6 -#define SYSREG_IE1_SIZE 1 -#define SYSREG_FC_OFFSET 8 -#define SYSREG_FC_SIZE 1 -#define SYSREG_F0_OFFSET 9 -#define SYSREG_F0_SIZE 1 -#define SYSREG_F1_OFFSET 10 -#define SYSREG_F1_SIZE 1 -#define SYSREG_CONF0_OFFSET 12 -#define SYSREG_CONF0_SIZE 6 -#define SYSREG_CONF1_OFFSET 18 -#define SYSREG_CONF1_SIZE 6 - -/* Constants for ECR */ -#define ECR_UNRECOVERABLE 0 -#define ECR_TLB_MULTIPLE 1 -#define ECR_BUS_ERROR_WRITE 2 -#define ECR_BUS_ERROR_READ 3 -#define ECR_NMI 4 -#define ECR_ADDR_ALIGN_X 5 -#define ECR_PROTECTION_X 6 -#define ECR_DEBUG 7 -#define ECR_ILLEGAL_OPCODE 8 -#define ECR_UNIMPL_INSTRUCTION 9 -#define ECR_PRIVILEGE_VIOLATION 10 -#define ECR_FPE 11 -#define ECR_COPROC_ABSENT 12 -#define ECR_ADDR_ALIGN_R 13 -#define ECR_ADDR_ALIGN_W 14 -#define ECR_PROTECTION_R 15 -#define ECR_PROTECTION_W 16 -#define ECR_DTLB_MODIFIED 17 -#define ECR_TLB_MISS_X 20 -#define ECR_TLB_MISS_R 24 -#define ECR_TLB_MISS_W 28 - -/* Bit manipulation macros */ -#define SYSREG_BIT(name) \ - (1 << SYSREG_##name##_OFFSET) -#define SYSREG_BF(name,value) \ - (((value) & ((1 << SYSREG_##name##_SIZE) - 1)) \ - << SYSREG_##name##_OFFSET) -#define SYSREG_BFEXT(name,value)\ - (((value) >> SYSREG_##name##_OFFSET) \ - & ((1 << SYSREG_##name##_SIZE) - 1)) -#define SYSREG_BFINS(name,value,old) \ - (((old) & ~(((1 << SYSREG_##name##_SIZE) - 1) \ - << SYSREG_##name##_OFFSET)) \ - | SYSREG_BF(name,value)) - -/* Register access macros */ -#ifdef __CHECKER__ -extern unsigned long __builtin_mfsr(unsigned long reg); -extern void __builtin_mtsr(unsigned long reg, unsigned long value); -#endif - -#define sysreg_read(reg) __builtin_mfsr(SYSREG_##reg) -#define sysreg_write(reg, value) __builtin_mtsr(SYSREG_##reg, value) - -#endif /* __ASM_AVR32_SYSREG_H */ diff --git a/arch/avr32/include/asm/termios.h b/arch/avr32/include/asm/termios.h deleted file mode 100644 index 9d594376dbd6..000000000000 --- a/arch/avr32/include/asm/termios.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_TERMIOS_H -#define __ASM_AVR32_TERMIOS_H - -#include <uapi/asm/termios.h> - -/* intr=^C quit=^\ erase=del kill=^U - eof=^D vtime=\0 vmin=\1 sxtc=\0 - start=^Q stop=^S susp=^Z eol=\0 - reprint=^R discard=^U werase=^W lnext=^V - eol2=\0 -*/ -#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" - -#include <asm-generic/termios-base.h> - -#endif /* __ASM_AVR32_TERMIOS_H */ diff --git a/arch/avr32/include/asm/thread_info.h b/arch/avr32/include/asm/thread_info.h deleted file mode 100644 index d4d3079541ea..000000000000 --- a/arch/avr32/include/asm/thread_info.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_THREAD_INFO_H -#define __ASM_AVR32_THREAD_INFO_H - -#include <asm/page.h> - -#define THREAD_SIZE_ORDER 1 -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) - -#ifndef __ASSEMBLY__ -#include <asm/types.h> - -struct task_struct; - -struct thread_info { - struct task_struct *task; /* main task structure */ - unsigned long flags; /* low level flags */ - __u32 cpu; - __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ - __u32 rar_saved; /* return address... */ - __u32 rsr_saved; /* ...and status register - saved by debug handler - when setting up - trampoline */ - __u8 supervisor_stack[0]; -}; - -#define INIT_THREAD_INFO(tsk) \ -{ \ - .task = &tsk, \ - .flags = 0, \ - .cpu = 0, \ - .preempt_count = INIT_PREEMPT_COUNT, \ -} - -#define init_thread_info (init_thread_union.thread_info) -#define init_stack (init_thread_union.stack) - -/* - * Get the thread information struct from C. - * We do the usual trick and use the lower end of the stack for this - */ -static inline struct thread_info *current_thread_info(void) -{ - unsigned long addr = ~(THREAD_SIZE - 1); - - asm("and %0, sp" : "=r"(addr) : "0"(addr)); - return (struct thread_info *)addr; -} - -#define get_thread_info(ti) get_task_struct((ti)->task) -#define put_thread_info(ti) put_task_struct((ti)->task) - -#endif /* !__ASSEMBLY__ */ - -/* - * Thread information flags - * - these are process state flags that various assembly files may need to access - * - pending work-to-be-done flags are in LSW - * - other flags in MSW - */ -#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ -#define TIF_SIGPENDING 1 /* signal pending */ -#define TIF_NEED_RESCHED 2 /* rescheduling necessary */ -#define TIF_BREAKPOINT 4 /* enter monitor mode on return */ -#define TIF_SINGLE_STEP 5 /* single step in progress */ -#define TIF_MEMDIE 6 /* is terminating due to OOM killer */ -#define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */ -#define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */ -#define TIF_NOTIFY_RESUME 9 /* callback before returning to user */ -#define TIF_DEBUG 30 /* debugging enabled */ -#define TIF_USERSPACE 31 /* true if FS sets userspace */ - -#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) -#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) -#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) -#define _TIF_BREAKPOINT (1 << TIF_BREAKPOINT) -#define _TIF_SINGLE_STEP (1 << TIF_SINGLE_STEP) -#define _TIF_MEMDIE (1 << TIF_MEMDIE) -#define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP) -#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) - -/* Note: The masks below must never span more than 16 bits! */ - -/* work to do on interrupt/exception return */ -#define _TIF_WORK_MASK \ - (_TIF_SIGPENDING \ - | _TIF_NOTIFY_RESUME \ - | _TIF_NEED_RESCHED \ - | _TIF_BREAKPOINT) - -/* work to do on any return to userspace */ -#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | _TIF_SYSCALL_TRACE) -/* work to do on return from debug mode */ -#define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~_TIF_BREAKPOINT) - -#endif /* __ASM_AVR32_THREAD_INFO_H */ diff --git a/arch/avr32/include/asm/timex.h b/arch/avr32/include/asm/timex.h deleted file mode 100644 index 187dcf38b210..000000000000 --- a/arch/avr32/include/asm/timex.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_TIMEX_H -#define __ASM_AVR32_TIMEX_H - -/* - * This is the frequency of the timer used for Linux's timer interrupt. - * The value should be defined as accurate as possible or under certain - * circumstances Linux timekeeping might become inaccurate or fail. - * - * For many system the exact clockrate of the timer isn't known but due to - * the way this value is used we can get away with a wrong value as long - * as this value is: - * - * - a multiple of HZ - * - a divisor of the actual rate - * - * 500000 is a good such cheat value. - * - * The obscure number 1193182 is the same as used by the original i8254 - * time in legacy PC hardware; the chip is never found in AVR32 systems. - */ -#define CLOCK_TICK_RATE 500000 /* Underlying HZ */ - -typedef unsigned long cycles_t; - -static inline cycles_t get_cycles (void) -{ - return 0; -} - -#define ARCH_HAS_READ_CURRENT_TIMER - -#endif /* __ASM_AVR32_TIMEX_H */ diff --git a/arch/avr32/include/asm/tlb.h b/arch/avr32/include/asm/tlb.h deleted file mode 100644 index 5c55f9ce7c7d..000000000000 --- a/arch/avr32/include/asm/tlb.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_TLB_H -#define __ASM_AVR32_TLB_H - -#define tlb_start_vma(tlb, vma) \ - flush_cache_range(vma, vma->vm_start, vma->vm_end) - -#define tlb_end_vma(tlb, vma) \ - flush_tlb_range(vma, vma->vm_start, vma->vm_end) - -#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while(0) - -/* - * Flush whole TLB for MM - */ -#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) - -#include <asm-generic/tlb.h> - -/* - * For debugging purposes - */ -extern void show_dtlb_entry(unsigned int index); -extern void dump_dtlb(void); - -#endif /* __ASM_AVR32_TLB_H */ diff --git a/arch/avr32/include/asm/tlbflush.h b/arch/avr32/include/asm/tlbflush.h deleted file mode 100644 index bf90a786f6be..000000000000 --- a/arch/avr32/include/asm/tlbflush.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_TLBFLUSH_H -#define __ASM_AVR32_TLBFLUSH_H - -#include <asm/mmu.h> - -/* - * TLB flushing: - * - * - flush_tlb() flushes the current mm struct TLBs - * - flush_tlb_all() flushes all processes' TLB entries - * - flush_tlb_mm(mm) flushes the specified mm context TLBs - * - flush_tlb_page(vma, vmaddr) flushes one page - * - flush_tlb_range(vma, start, end) flushes a range of pages - * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages - */ -extern void flush_tlb(void); -extern void flush_tlb_all(void); -extern void flush_tlb_mm(struct mm_struct *mm); -extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); - -extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); - -#endif /* __ASM_AVR32_TLBFLUSH_H */ diff --git a/arch/avr32/include/asm/traps.h b/arch/avr32/include/asm/traps.h deleted file mode 100644 index 6a8fb944f414..000000000000 --- a/arch/avr32/include/asm/traps.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_TRAPS_H -#define __ASM_AVR32_TRAPS_H - -#include <linux/list.h> - -struct undef_hook { - struct list_head node; - u32 insn_mask; - u32 insn_val; - int (*fn)(struct pt_regs *regs, u32 insn); -}; - -void register_undef_hook(struct undef_hook *hook); -void unregister_undef_hook(struct undef_hook *hook); - -#endif /* __ASM_AVR32_TRAPS_H */ diff --git a/arch/avr32/include/asm/types.h b/arch/avr32/include/asm/types.h deleted file mode 100644 index 59324058069c..000000000000 --- a/arch/avr32/include/asm/types.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_TYPES_H -#define __ASM_AVR32_TYPES_H - -#include <uapi/asm/types.h> - -/* - * These aren't exported outside the kernel to avoid name space clashes - */ - -#define BITS_PER_LONG 32 - -#endif /* __ASM_AVR32_TYPES_H */ diff --git a/arch/avr32/include/asm/uaccess.h b/arch/avr32/include/asm/uaccess.h deleted file mode 100644 index b1ec1fa06463..000000000000 --- a/arch/avr32/include/asm/uaccess.h +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_UACCESS_H -#define __ASM_AVR32_UACCESS_H - -#include <linux/errno.h> -#include <linux/sched.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -typedef struct { - unsigned int is_user_space; -} mm_segment_t; - -/* - * The fs value determines whether argument validity checking should be - * performed or not. If get_fs() == USER_DS, checking is performed, with - * get_fs() == KERNEL_DS, checking is bypassed. - * - * For historical reasons (Data Segment Register?), these macros are misnamed. - */ -#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) -#define segment_eq(a, b) ((a).is_user_space == (b).is_user_space) - -#define USER_ADDR_LIMIT 0x80000000 - -#define KERNEL_DS MAKE_MM_SEG(0) -#define USER_DS MAKE_MM_SEG(1) - -#define get_ds() (KERNEL_DS) - -static inline mm_segment_t get_fs(void) -{ - return MAKE_MM_SEG(test_thread_flag(TIF_USERSPACE)); -} - -static inline void set_fs(mm_segment_t s) -{ - if (s.is_user_space) - set_thread_flag(TIF_USERSPACE); - else - clear_thread_flag(TIF_USERSPACE); -} - -/* - * Test whether a block of memory is a valid user space address. - * Returns 0 if the range is valid, nonzero otherwise. - * - * We do the following checks: - * 1. Is the access from kernel space? - * 2. Does (addr + size) set the carry bit? - * 3. Is (addr + size) a negative number (i.e. >= 0x80000000)? - * - * If yes on the first check, access is granted. - * If no on any of the others, access is denied. - */ -#define __range_ok(addr, size) \ - (test_thread_flag(TIF_USERSPACE) \ - && (((unsigned long)(addr) >= 0x80000000) \ - || ((unsigned long)(size) > 0x80000000) \ - || (((unsigned long)(addr) + (unsigned long)(size)) > 0x80000000))) - -#define access_ok(type, addr, size) (likely(__range_ok(addr, size) == 0)) - -/* Generic arbitrary sized copy. Return the number of bytes NOT copied */ -extern __kernel_size_t __copy_user(void *to, const void *from, - __kernel_size_t n); - -extern __kernel_size_t copy_to_user(void __user *to, const void *from, - __kernel_size_t n); -extern __kernel_size_t ___copy_from_user(void *to, const void __user *from, - __kernel_size_t n); - -static inline __kernel_size_t __copy_to_user(void __user *to, const void *from, - __kernel_size_t n) -{ - return __copy_user((void __force *)to, from, n); -} -static inline __kernel_size_t __copy_from_user(void *to, - const void __user *from, - __kernel_size_t n) -{ - return __copy_user(to, (const void __force *)from, n); -} -static inline __kernel_size_t copy_from_user(void *to, - const void __user *from, - __kernel_size_t n) -{ - size_t res = ___copy_from_user(to, from, n); - if (unlikely(res)) - memset(to + (n - res), 0, res); - return res; -} - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - -/* - * put_user: - Write a simple value into user space. - * @x: Value to copy to user space. - * @ptr: Destination address, in user space. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * This macro copies a single simple value from kernel space to user - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and @x must be assignable - * to the result of dereferencing @ptr. - * - * Returns zero on success, or -EFAULT on error. - */ -#define put_user(x, ptr) \ - __put_user_check((x), (ptr), sizeof(*(ptr))) - -/* - * get_user: - Get a simple variable from user space. - * @x: Variable to store result. - * @ptr: Source address, in user space. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * This macro copies a single simple variable from user space to kernel - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and the result of - * dereferencing @ptr must be assignable to @x without a cast. - * - * Returns zero on success, or -EFAULT on error. - * On error, the variable @x is set to zero. - */ -#define get_user(x, ptr) \ - __get_user_check((x), (ptr), sizeof(*(ptr))) - -/* - * __put_user: - Write a simple value into user space, with less checking. - * @x: Value to copy to user space. - * @ptr: Destination address, in user space. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * This macro copies a single simple value from kernel space to user - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and @x must be assignable - * to the result of dereferencing @ptr. - * - * Caller must check the pointer with access_ok() before calling this - * function. - * - * Returns zero on success, or -EFAULT on error. - */ -#define __put_user(x, ptr) \ - __put_user_nocheck((x), (ptr), sizeof(*(ptr))) - -/* - * __get_user: - Get a simple variable from user space, with less checking. - * @x: Variable to store result. - * @ptr: Source address, in user space. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * This macro copies a single simple variable from user space to kernel - * space. It supports simple types like char and int, but not larger - * data types like structures or arrays. - * - * @ptr must have pointer-to-simple-variable type, and the result of - * dereferencing @ptr must be assignable to @x without a cast. - * - * Caller must check the pointer with access_ok() before calling this - * function. - * - * Returns zero on success, or -EFAULT on error. - * On error, the variable @x is set to zero. - */ -#define __get_user(x, ptr) \ - __get_user_nocheck((x), (ptr), sizeof(*(ptr))) - -extern int __get_user_bad(void); -extern int __put_user_bad(void); - -#define __get_user_nocheck(x, ptr, size) \ -({ \ - unsigned long __gu_val = 0; \ - int __gu_err = 0; \ - \ - switch (size) { \ - case 1: __get_user_asm("ub", __gu_val, ptr, __gu_err); break; \ - case 2: __get_user_asm("uh", __gu_val, ptr, __gu_err); break; \ - case 4: __get_user_asm("w", __gu_val, ptr, __gu_err); break; \ - default: __gu_err = __get_user_bad(); break; \ - } \ - \ - x = (__force typeof(*(ptr)))__gu_val; \ - __gu_err; \ -}) - -#define __get_user_check(x, ptr, size) \ -({ \ - unsigned long __gu_val = 0; \ - const typeof(*(ptr)) __user * __gu_addr = (ptr); \ - int __gu_err = 0; \ - \ - if (access_ok(VERIFY_READ, __gu_addr, size)) { \ - switch (size) { \ - case 1: \ - __get_user_asm("ub", __gu_val, __gu_addr, \ - __gu_err); \ - break; \ - case 2: \ - __get_user_asm("uh", __gu_val, __gu_addr, \ - __gu_err); \ - break; \ - case 4: \ - __get_user_asm("w", __gu_val, __gu_addr, \ - __gu_err); \ - break; \ - default: \ - __gu_err = __get_user_bad(); \ - break; \ - } \ - } else { \ - __gu_err = -EFAULT; \ - } \ - x = (__force typeof(*(ptr)))__gu_val; \ - __gu_err; \ -}) - -#define __get_user_asm(suffix, __gu_val, ptr, __gu_err) \ - asm volatile( \ - "1: ld." suffix " %1, %3 \n" \ - "2: \n" \ - " .subsection 1 \n" \ - "3: mov %0, %4 \n" \ - " rjmp 2b \n" \ - " .subsection 0 \n" \ - " .section __ex_table, \"a\" \n" \ - " .long 1b, 3b \n" \ - " .previous \n" \ - : "=r"(__gu_err), "=r"(__gu_val) \ - : "0"(__gu_err), "m"(*(ptr)), "i"(-EFAULT)) - -#define __put_user_nocheck(x, ptr, size) \ -({ \ - typeof(*(ptr)) __pu_val; \ - int __pu_err = 0; \ - \ - __pu_val = (x); \ - switch (size) { \ - case 1: __put_user_asm("b", ptr, __pu_val, __pu_err); break; \ - case 2: __put_user_asm("h", ptr, __pu_val, __pu_err); break; \ - case 4: __put_user_asm("w", ptr, __pu_val, __pu_err); break; \ - case 8: __put_user_asm("d", ptr, __pu_val, __pu_err); break; \ - default: __pu_err = __put_user_bad(); break; \ - } \ - __pu_err; \ -}) - -#define __put_user_check(x, ptr, size) \ -({ \ - typeof(*(ptr)) __pu_val; \ - typeof(*(ptr)) __user *__pu_addr = (ptr); \ - int __pu_err = 0; \ - \ - __pu_val = (x); \ - if (access_ok(VERIFY_WRITE, __pu_addr, size)) { \ - switch (size) { \ - case 1: \ - __put_user_asm("b", __pu_addr, __pu_val, \ - __pu_err); \ - break; \ - case 2: \ - __put_user_asm("h", __pu_addr, __pu_val, \ - __pu_err); \ - break; \ - case 4: \ - __put_user_asm("w", __pu_addr, __pu_val, \ - __pu_err); \ - break; \ - case 8: \ - __put_user_asm("d", __pu_addr, __pu_val, \ - __pu_err); \ - break; \ - default: \ - __pu_err = __put_user_bad(); \ - break; \ - } \ - } else { \ - __pu_err = -EFAULT; \ - } \ - __pu_err; \ -}) - -#define __put_user_asm(suffix, ptr, __pu_val, __gu_err) \ - asm volatile( \ - "1: st." suffix " %1, %3 \n" \ - "2: \n" \ - " .subsection 1 \n" \ - "3: mov %0, %4 \n" \ - " rjmp 2b \n" \ - " .subsection 0 \n" \ - " .section __ex_table, \"a\" \n" \ - " .long 1b, 3b \n" \ - " .previous \n" \ - : "=r"(__gu_err), "=m"(*(ptr)) \ - : "0"(__gu_err), "r"(__pu_val), "i"(-EFAULT)) - -extern __kernel_size_t clear_user(void __user *addr, __kernel_size_t size); -extern __kernel_size_t __clear_user(void __user *addr, __kernel_size_t size); - -extern long strncpy_from_user(char *dst, const char __user *src, long count); -extern long __strncpy_from_user(char *dst, const char __user *src, long count); - -extern long strnlen_user(const char __user *__s, long __n); -extern long __strnlen_user(const char __user *__s, long __n); - -#define strlen_user(s) strnlen_user(s, ~0UL >> 1) - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -#endif /* __ASM_AVR32_UACCESS_H */ diff --git a/arch/avr32/include/asm/ucontext.h b/arch/avr32/include/asm/ucontext.h deleted file mode 100644 index ac7259c2a799..000000000000 --- a/arch/avr32/include/asm/ucontext.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __ASM_AVR32_UCONTEXT_H -#define __ASM_AVR32_UCONTEXT_H - -struct ucontext { - unsigned long uc_flags; - struct ucontext * uc_link; - stack_t uc_stack; - struct sigcontext uc_mcontext; - sigset_t uc_sigmask; -}; - -#endif /* __ASM_AVR32_UCONTEXT_H */ diff --git a/arch/avr32/include/asm/unaligned.h b/arch/avr32/include/asm/unaligned.h deleted file mode 100644 index 041877290470..000000000000 --- a/arch/avr32/include/asm/unaligned.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _ASM_AVR32_UNALIGNED_H -#define _ASM_AVR32_UNALIGNED_H - -/* - * AVR32 can handle some unaligned accesses, depending on the - * implementation. The AVR32 AP implementation can handle unaligned - * words, but halfwords must be halfword-aligned, and doublewords must - * be word-aligned. - * - * However, swapped word loads must be word-aligned so we can't - * optimize word loads in general. - */ - -#include <linux/unaligned/be_struct.h> -#include <linux/unaligned/le_byteshift.h> -#include <linux/unaligned/generic.h> - -#define get_unaligned __get_unaligned_be -#define put_unaligned __put_unaligned_be - -#endif /* _ASM_AVR32_UNALIGNED_H */ diff --git a/arch/avr32/include/asm/unistd.h b/arch/avr32/include/asm/unistd.h deleted file mode 100644 index 2011bee3f252..000000000000 --- a/arch/avr32/include/asm/unistd.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_UNISTD_H -#define __ASM_AVR32_UNISTD_H - -#include <uapi/asm/unistd.h> - -#define NR_syscalls 321 - -/* Old stuff */ -#define __IGNORE_uselib -#define __IGNORE_mmap - -/* NUMA stuff */ -#define __IGNORE_mbind -#define __IGNORE_get_mempolicy -#define __IGNORE_set_mempolicy -#define __IGNORE_migrate_pages -#define __IGNORE_move_pages - -/* SMP stuff */ -#define __IGNORE_getcpu - -#define __ARCH_WANT_STAT64 -#define __ARCH_WANT_SYS_ALARM -#define __ARCH_WANT_SYS_GETHOSTNAME -#define __ARCH_WANT_SYS_PAUSE -#define __ARCH_WANT_SYS_TIME -#define __ARCH_WANT_SYS_UTIME -#define __ARCH_WANT_SYS_WAITPID -#define __ARCH_WANT_SYS_FADVISE64 -#define __ARCH_WANT_SYS_GETPGRP -#define __ARCH_WANT_SYS_LLSEEK -#define __ARCH_WANT_SYS_GETPGRP -#define __ARCH_WANT_SYS_FORK -#define __ARCH_WANT_SYS_VFORK -#define __ARCH_WANT_SYS_CLONE - -#endif /* __ASM_AVR32_UNISTD_H */ diff --git a/arch/avr32/include/asm/user.h b/arch/avr32/include/asm/user.h deleted file mode 100644 index 7e9152f81f5e..000000000000 --- a/arch/avr32/include/asm/user.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Note: We may not need these definitions for AVR32, as we don't - * support a.out. - */ -#ifndef __ASM_AVR32_USER_H -#define __ASM_AVR32_USER_H - -#include <linux/types.h> -#include <asm/ptrace.h> -#include <asm/page.h> - -/* - * Core file format: The core file is written in such a way that gdb - * can understand it and provide useful information to the user (under - * linux we use the `trad-core' bfd). The file contents are as follows: - * - * upage: 1 page consisting of a user struct that tells gdb - * what is present in the file. Directly after this is a - * copy of the task_struct, which is currently not used by gdb, - * but it may come in handy at some point. All of the registers - * are stored as part of the upage. The upage should always be - * only one page long. - * data: The data segment follows next. We use current->end_text to - * current->brk to pick up all of the user variables, plus any memory - * that may have been sbrk'ed. No attempt is made to determine if a - * page is demand-zero or if a page is totally unused, we just cover - * the entire range. All of the addresses are rounded in such a way - * that an integral number of pages is written. - * stack: We need the stack information in order to get a meaningful - * backtrace. We need to write the data from usp to - * current->start_stack, so we round each of these in order to be able - * to write an integer number of pages. - */ - -struct user_fpu_struct { - /* We have no FPU (yet) */ -}; - -struct user { - struct pt_regs regs; /* entire machine state */ - size_t u_tsize; /* text size (pages) */ - size_t u_dsize; /* data size (pages) */ - size_t u_ssize; /* stack size (pages) */ - unsigned long start_code; /* text starting address */ - unsigned long start_data; /* data starting address */ - unsigned long start_stack; /* stack starting address */ - long int signal; /* signal causing core dump */ - unsigned long u_ar0; /* help gdb find registers */ - unsigned long magic; /* identifies a core file */ - char u_comm[32]; /* user command name */ -}; - -#define NBPG PAGE_SIZE -#define UPAGES 1 -#define HOST_TEXT_START_ADDR (u.start_code) -#define HOST_DATA_START_ADDR (u.start_data) -#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) - -#endif /* __ASM_AVR32_USER_H */ diff --git a/arch/avr32/include/uapi/asm/Kbuild b/arch/avr32/include/uapi/asm/Kbuild deleted file mode 100644 index 08d8a3d76ea8..000000000000 --- a/arch/avr32/include/uapi/asm/Kbuild +++ /dev/null @@ -1,36 +0,0 @@ -# UAPI Header export list -include include/uapi/asm-generic/Kbuild.asm - -header-y += auxvec.h -header-y += byteorder.h -header-y += cachectl.h -header-y += msgbuf.h -header-y += param.h -header-y += posix_types.h -header-y += ptrace.h -header-y += sembuf.h -header-y += setup.h -header-y += shmbuf.h -header-y += sigcontext.h -header-y += signal.h -header-y += socket.h -header-y += sockios.h -header-y += stat.h -header-y += swab.h -header-y += termbits.h -header-y += termios.h -header-y += types.h -header-y += unistd.h -generic-y += bitsperlong.h -generic-y += errno.h -generic-y += fcntl.h -generic-y += ioctl.h -generic-y += ioctls.h -generic-y += ipcbuf.h -generic-y += kvm_para.h -generic-y += mman.h -generic-y += param.h -generic-y += poll.h -generic-y += resource.h -generic-y += siginfo.h -generic-y += statfs.h diff --git a/arch/avr32/include/uapi/asm/auxvec.h b/arch/avr32/include/uapi/asm/auxvec.h deleted file mode 100644 index 4f02da3ffefa..000000000000 --- a/arch/avr32/include/uapi/asm/auxvec.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef _UAPI__ASM_AVR32_AUXVEC_H -#define _UAPI__ASM_AVR32_AUXVEC_H - -#endif /* _UAPI__ASM_AVR32_AUXVEC_H */ diff --git a/arch/avr32/include/uapi/asm/byteorder.h b/arch/avr32/include/uapi/asm/byteorder.h deleted file mode 100644 index 71242f0d39c6..000000000000 --- a/arch/avr32/include/uapi/asm/byteorder.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * AVR32 endian-conversion functions. - */ -#ifndef _UAPI__ASM_AVR32_BYTEORDER_H -#define _UAPI__ASM_AVR32_BYTEORDER_H - -#include <linux/byteorder/big_endian.h> - -#endif /* _UAPI__ASM_AVR32_BYTEORDER_H */ diff --git a/arch/avr32/include/uapi/asm/cachectl.h b/arch/avr32/include/uapi/asm/cachectl.h deleted file mode 100644 index 573a9584dd57..000000000000 --- a/arch/avr32/include/uapi/asm/cachectl.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _UAPI__ASM_AVR32_CACHECTL_H -#define _UAPI__ASM_AVR32_CACHECTL_H - -/* - * Operations that can be performed through the cacheflush system call - */ - -/* Clean the data cache, then invalidate the icache */ -#define CACHE_IFLUSH 0 - -#endif /* _UAPI__ASM_AVR32_CACHECTL_H */ diff --git a/arch/avr32/include/uapi/asm/msgbuf.h b/arch/avr32/include/uapi/asm/msgbuf.h deleted file mode 100644 index 9eae6effad14..000000000000 --- a/arch/avr32/include/uapi/asm/msgbuf.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _UAPI__ASM_AVR32_MSGBUF_H -#define _UAPI__ASM_AVR32_MSGBUF_H - -/* - * The msqid64_ds structure for i386 architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct msqid64_ds { - struct ipc64_perm msg_perm; - __kernel_time_t msg_stime; /* last msgsnd time */ - unsigned long __unused1; - __kernel_time_t msg_rtime; /* last msgrcv time */ - unsigned long __unused2; - __kernel_time_t msg_ctime; /* last change time */ - unsigned long __unused3; - unsigned long msg_cbytes; /* current number of bytes on queue */ - unsigned long msg_qnum; /* number of messages in queue */ - unsigned long msg_qbytes; /* max number of bytes on queue */ - __kernel_pid_t msg_lspid; /* pid of last msgsnd */ - __kernel_pid_t msg_lrpid; /* last receive pid */ - unsigned long __unused4; - unsigned long __unused5; -}; - -#endif /* _UAPI__ASM_AVR32_MSGBUF_H */ diff --git a/arch/avr32/include/uapi/asm/posix_types.h b/arch/avr32/include/uapi/asm/posix_types.h deleted file mode 100644 index 5b813a8abf09..000000000000 --- a/arch/avr32/include/uapi/asm/posix_types.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _UAPI__ASM_AVR32_POSIX_TYPES_H -#define _UAPI__ASM_AVR32_POSIX_TYPES_H - -/* - * This file is generally used by user-level software, so you need to - * be a little careful about namespace pollution etc. Also, we cannot - * assume GCC is being used. - */ - -typedef unsigned short __kernel_mode_t; -#define __kernel_mode_t __kernel_mode_t - -typedef unsigned short __kernel_ipc_pid_t; -#define __kernel_ipc_pid_t __kernel_ipc_pid_t - -typedef unsigned long __kernel_size_t; -typedef long __kernel_ssize_t; -typedef int __kernel_ptrdiff_t; -#define __kernel_size_t __kernel_size_t - -typedef unsigned short __kernel_old_uid_t; -typedef unsigned short __kernel_old_gid_t; -#define __kernel_old_uid_t __kernel_old_uid_t - -typedef unsigned short __kernel_old_dev_t; -#define __kernel_old_dev_t __kernel_old_dev_t - -#include <asm-generic/posix_types.h> - -#endif /* _UAPI__ASM_AVR32_POSIX_TYPES_H */ diff --git a/arch/avr32/include/uapi/asm/ptrace.h b/arch/avr32/include/uapi/asm/ptrace.h deleted file mode 100644 index fe8c16275bc0..000000000000 --- a/arch/avr32/include/uapi/asm/ptrace.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _UAPI__ASM_AVR32_PTRACE_H -#define _UAPI__ASM_AVR32_PTRACE_H - -#define PTRACE_GETREGS 12 -#define PTRACE_SETREGS 13 - -/* - * Status Register bits - */ -#define SR_H 0x20000000 -#define SR_J 0x10000000 -#define SR_DM 0x08000000 -#define SR_D 0x04000000 -#define MODE_NMI 0x01c00000 -#define MODE_EXCEPTION 0x01800000 -#define MODE_INT3 0x01400000 -#define MODE_INT2 0x01000000 -#define MODE_INT1 0x00c00000 -#define MODE_INT0 0x00800000 -#define MODE_SUPERVISOR 0x00400000 -#define MODE_USER 0x00000000 -#define MODE_MASK 0x01c00000 -#define SR_EM 0x00200000 -#define SR_I3M 0x00100000 -#define SR_I2M 0x00080000 -#define SR_I1M 0x00040000 -#define SR_I0M 0x00020000 -#define SR_GM 0x00010000 - -#define SR_H_BIT 29 -#define SR_J_BIT 28 -#define SR_DM_BIT 27 -#define SR_D_BIT 26 -#define MODE_SHIFT 22 -#define SR_EM_BIT 21 -#define SR_I3M_BIT 20 -#define SR_I2M_BIT 19 -#define SR_I1M_BIT 18 -#define SR_I0M_BIT 17 -#define SR_GM_BIT 16 - -/* The user-visible part */ -#define SR_L 0x00000020 -#define SR_Q 0x00000010 -#define SR_V 0x00000008 -#define SR_N 0x00000004 -#define SR_Z 0x00000002 -#define SR_C 0x00000001 - -#define SR_L_BIT 5 -#define SR_Q_BIT 4 -#define SR_V_BIT 3 -#define SR_N_BIT 2 -#define SR_Z_BIT 1 -#define SR_C_BIT 0 - -/* - * The order is defined by the stmts instruction. r0 is stored first, - * so it gets the highest address. - * - * Registers 0-12 are general-purpose registers (r12 is normally used for - * the function return value). - * Register 13 is the stack pointer - * Register 14 is the link register - * Register 15 is the program counter (retrieved from the RAR sysreg) - */ -#define FRAME_SIZE_FULL 72 -#define REG_R12_ORIG 68 -#define REG_R0 64 -#define REG_R1 60 -#define REG_R2 56 -#define REG_R3 52 -#define REG_R4 48 -#define REG_R5 44 -#define REG_R6 40 -#define REG_R7 36 -#define REG_R8 32 -#define REG_R9 28 -#define REG_R10 24 -#define REG_R11 20 -#define REG_R12 16 -#define REG_SP 12 -#define REG_LR 8 - -#define FRAME_SIZE_MIN 8 -#define REG_PC 4 -#define REG_SR 0 - -#ifndef __ASSEMBLY__ -struct pt_regs { - /* These are always saved */ - unsigned long sr; - unsigned long pc; - - /* These are sometimes saved */ - unsigned long lr; - unsigned long sp; - unsigned long r12; - unsigned long r11; - unsigned long r10; - unsigned long r9; - unsigned long r8; - unsigned long r7; - unsigned long r6; - unsigned long r5; - unsigned long r4; - unsigned long r3; - unsigned long r2; - unsigned long r1; - unsigned long r0; - - /* Only saved on system call */ - unsigned long r12_orig; -}; - - -#endif /* ! __ASSEMBLY__ */ - -#endif /* _UAPI__ASM_AVR32_PTRACE_H */ diff --git a/arch/avr32/include/uapi/asm/sembuf.h b/arch/avr32/include/uapi/asm/sembuf.h deleted file mode 100644 index 6c6f7cf1e75a..000000000000 --- a/arch/avr32/include/uapi/asm/sembuf.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _UAPI__ASM_AVR32_SEMBUF_H -#define _UAPI__ASM_AVR32_SEMBUF_H - -/* -* The semid64_ds structure for AVR32 architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct semid64_ds { - struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ - __kernel_time_t sem_otime; /* last semop time */ - unsigned long __unused1; - __kernel_time_t sem_ctime; /* last change time */ - unsigned long __unused2; - unsigned long sem_nsems; /* no. of semaphores in array */ - unsigned long __unused3; - unsigned long __unused4; -}; - -#endif /* _UAPI__ASM_AVR32_SEMBUF_H */ diff --git a/arch/avr32/include/uapi/asm/setup.h b/arch/avr32/include/uapi/asm/setup.h deleted file mode 100644 index a654df7dba46..000000000000 --- a/arch/avr32/include/uapi/asm/setup.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * Based on linux/include/asm-arm/setup.h - * Copyright (C) 1997-1999 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _UAPI__ASM_AVR32_SETUP_H__ -#define _UAPI__ASM_AVR32_SETUP_H__ - -#define COMMAND_LINE_SIZE 256 - -#endif /* _UAPI__ASM_AVR32_SETUP_H__ */ diff --git a/arch/avr32/include/uapi/asm/shmbuf.h b/arch/avr32/include/uapi/asm/shmbuf.h deleted file mode 100644 index b94cf8b60b73..000000000000 --- a/arch/avr32/include/uapi/asm/shmbuf.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _UAPI__ASM_AVR32_SHMBUF_H -#define _UAPI__ASM_AVR32_SHMBUF_H - -/* - * The shmid64_ds structure for i386 architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct shmid64_ds { - struct ipc64_perm shm_perm; /* operation perms */ - size_t shm_segsz; /* size of segment (bytes) */ - __kernel_time_t shm_atime; /* last attach time */ - unsigned long __unused1; - __kernel_time_t shm_dtime; /* last detach time */ - unsigned long __unused2; - __kernel_time_t shm_ctime; /* last change time */ - unsigned long __unused3; - __kernel_pid_t shm_cpid; /* pid of creator */ - __kernel_pid_t shm_lpid; /* pid of last operator */ - unsigned long shm_nattch; /* no. of current attaches */ - unsigned long __unused4; - unsigned long __unused5; -}; - -struct shminfo64 { - unsigned long shmmax; - unsigned long shmmin; - unsigned long shmmni; - unsigned long shmseg; - unsigned long shmall; - unsigned long __unused1; - unsigned long __unused2; - unsigned long __unused3; - unsigned long __unused4; -}; - -#endif /* _UAPI__ASM_AVR32_SHMBUF_H */ diff --git a/arch/avr32/include/uapi/asm/sigcontext.h b/arch/avr32/include/uapi/asm/sigcontext.h deleted file mode 100644 index 27e56bf6377f..000000000000 --- a/arch/avr32/include/uapi/asm/sigcontext.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _UAPI__ASM_AVR32_SIGCONTEXT_H -#define _UAPI__ASM_AVR32_SIGCONTEXT_H - -struct sigcontext { - unsigned long oldmask; - - /* CPU registers */ - unsigned long sr; - unsigned long pc; - unsigned long lr; - unsigned long sp; - unsigned long r12; - unsigned long r11; - unsigned long r10; - unsigned long r9; - unsigned long r8; - unsigned long r7; - unsigned long r6; - unsigned long r5; - unsigned long r4; - unsigned long r3; - unsigned long r2; - unsigned long r1; - unsigned long r0; -}; - -#endif /* _UAPI__ASM_AVR32_SIGCONTEXT_H */ diff --git a/arch/avr32/include/uapi/asm/signal.h b/arch/avr32/include/uapi/asm/signal.h deleted file mode 100644 index ffe8c770cafd..000000000000 --- a/arch/avr32/include/uapi/asm/signal.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _UAPI__ASM_AVR32_SIGNAL_H -#define _UAPI__ASM_AVR32_SIGNAL_H - -#include <linux/types.h> - -/* Avoid too many header ordering problems. */ -struct siginfo; - -#ifndef __KERNEL__ -/* Here we must cater to libcs that poke about in kernel headers. */ - -#define NSIG 32 -typedef unsigned long sigset_t; - -#endif /* __KERNEL__ */ - -#define SIGHUP 1 -#define SIGINT 2 -#define SIGQUIT 3 -#define SIGILL 4 -#define SIGTRAP 5 -#define SIGABRT 6 -#define SIGIOT 6 -#define SIGBUS 7 -#define SIGFPE 8 -#define SIGKILL 9 -#define SIGUSR1 10 -#define SIGSEGV 11 -#define SIGUSR2 12 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGTERM 15 -#define SIGSTKFLT 16 -#define SIGCHLD 17 -#define SIGCONT 18 -#define SIGSTOP 19 -#define SIGTSTP 20 -#define SIGTTIN 21 -#define SIGTTOU 22 -#define SIGURG 23 -#define SIGXCPU 24 -#define SIGXFSZ 25 -#define SIGVTALRM 26 -#define SIGPROF 27 -#define SIGWINCH 28 -#define SIGIO 29 -#define SIGPOLL SIGIO -/* -#define SIGLOST 29 -*/ -#define SIGPWR 30 -#define SIGSYS 31 -#define SIGUNUSED 31 - -/* These should not be considered constants from userland. */ -#define SIGRTMIN 32 -#define SIGRTMAX (_NSIG-1) - -/* - * SA_FLAGS values: - * - * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. - * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. - * SA_SIGINFO deliver the signal with SIGINFO structs - * SA_ONSTACK indicates that a registered stack_t will be used. - * SA_RESTART flag to get restarting signals (which were the default long ago) - * SA_NODEFER prevents the current signal from being masked in the handler. - * SA_RESETHAND clears the handler when the signal is delivered. - * - * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single - * Unix names RESETHAND and NODEFER respectively. - */ -#define SA_NOCLDSTOP 0x00000001 -#define SA_NOCLDWAIT 0x00000002 -#define SA_SIGINFO 0x00000004 -#define SA_RESTORER 0x04000000 -#define SA_ONSTACK 0x08000000 -#define SA_RESTART 0x10000000 -#define SA_NODEFER 0x40000000 -#define SA_RESETHAND 0x80000000 - -#define SA_NOMASK SA_NODEFER -#define SA_ONESHOT SA_RESETHAND - -#define MINSIGSTKSZ 2048 -#define SIGSTKSZ 8192 - -#include <asm-generic/signal-defs.h> - -#ifndef __KERNEL__ -/* Here we must cater to libcs that poke about in kernel headers. */ - -struct sigaction { - union { - __sighandler_t _sa_handler; - void (*_sa_sigaction)(int, struct siginfo *, void *); - } _u; - sigset_t sa_mask; - unsigned long sa_flags; - void (*sa_restorer)(void); -}; - -#define sa_handler _u._sa_handler -#define sa_sigaction _u._sa_sigaction - -#endif /* __KERNEL__ */ - -typedef struct sigaltstack { - void __user *ss_sp; - int ss_flags; - size_t ss_size; -} stack_t; - -#endif /* _UAPI__ASM_AVR32_SIGNAL_H */ diff --git a/arch/avr32/include/uapi/asm/socket.h b/arch/avr32/include/uapi/asm/socket.h deleted file mode 100644 index 5a650426f357..000000000000 --- a/arch/avr32/include/uapi/asm/socket.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef _UAPI__ASM_AVR32_SOCKET_H -#define _UAPI__ASM_AVR32_SOCKET_H - -#include <asm/sockios.h> - -/* For setsockopt(2) */ -#define SOL_SOCKET 1 - -#define SO_DEBUG 1 -#define SO_REUSEADDR 2 -#define SO_TYPE 3 -#define SO_ERROR 4 -#define SO_DONTROUTE 5 -#define SO_BROADCAST 6 -#define SO_SNDBUF 7 -#define SO_RCVBUF 8 -#define SO_SNDBUFFORCE 32 -#define SO_RCVBUFFORCE 33 -#define SO_KEEPALIVE 9 -#define SO_OOBINLINE 10 -#define SO_NO_CHECK 11 -#define SO_PRIORITY 12 -#define SO_LINGER 13 -#define SO_BSDCOMPAT 14 -#define SO_REUSEPORT 15 -#define SO_PASSCRED 16 -#define SO_PEERCRED 17 -#define SO_RCVLOWAT 18 -#define SO_SNDLOWAT 19 -#define SO_RCVTIMEO 20 -#define SO_SNDTIMEO 21 - -/* Security levels - as per NRL IPv6 - don't actually do anything */ -#define SO_SECURITY_AUTHENTICATION 22 -#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 -#define SO_SECURITY_ENCRYPTION_NETWORK 24 - -#define SO_BINDTODEVICE 25 - -/* Socket filtering */ -#define SO_ATTACH_FILTER 26 -#define SO_DETACH_FILTER 27 -#define SO_GET_FILTER SO_ATTACH_FILTER - -#define SO_PEERNAME 28 -#define SO_TIMESTAMP 29 -#define SCM_TIMESTAMP SO_TIMESTAMP - -#define SO_ACCEPTCONN 30 - -#define SO_PEERSEC 31 -#define SO_PASSSEC 34 -#define SO_TIMESTAMPNS 35 -#define SCM_TIMESTAMPNS SO_TIMESTAMPNS - -#define SO_MARK 36 - -#define SO_TIMESTAMPING 37 -#define SCM_TIMESTAMPING SO_TIMESTAMPING - -#define SO_PROTOCOL 38 -#define SO_DOMAIN 39 - -#define SO_RXQ_OVFL 40 - -#define SO_WIFI_STATUS 41 -#define SCM_WIFI_STATUS SO_WIFI_STATUS -#define SO_PEEK_OFF 42 - -/* Instruct lower device to use last 4-bytes of skb data as FCS */ -#define SO_NOFCS 43 - -#define SO_LOCK_FILTER 44 - -#define SO_SELECT_ERR_QUEUE 45 - -#define SO_BUSY_POLL 46 - -#define SO_MAX_PACING_RATE 47 - -#define SO_BPF_EXTENSIONS 48 - -#define SO_INCOMING_CPU 49 - -#define SO_ATTACH_BPF 50 -#define SO_DETACH_BPF SO_DETACH_FILTER - -#define SO_ATTACH_REUSEPORT_CBPF 51 -#define SO_ATTACH_REUSEPORT_EBPF 52 - -#define SO_CNX_ADVICE 53 - -#define SCM_TIMESTAMPING_OPT_STATS 54 - -#endif /* _UAPI__ASM_AVR32_SOCKET_H */ diff --git a/arch/avr32/include/uapi/asm/sockios.h b/arch/avr32/include/uapi/asm/sockios.h deleted file mode 100644 index d04785453532..000000000000 --- a/arch/avr32/include/uapi/asm/sockios.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _UAPI__ASM_AVR32_SOCKIOS_H -#define _UAPI__ASM_AVR32_SOCKIOS_H - -/* Socket-level I/O control calls. */ -#define FIOSETOWN 0x8901 -#define SIOCSPGRP 0x8902 -#define FIOGETOWN 0x8903 -#define SIOCGPGRP 0x8904 -#define SIOCATMARK 0x8905 -#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ -#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ - -#endif /* _UAPI__ASM_AVR32_SOCKIOS_H */ diff --git a/arch/avr32/include/uapi/asm/stat.h b/arch/avr32/include/uapi/asm/stat.h deleted file mode 100644 index c06acef7fce7..000000000000 --- a/arch/avr32/include/uapi/asm/stat.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _UAPI__ASM_AVR32_STAT_H -#define _UAPI__ASM_AVR32_STAT_H - -struct __old_kernel_stat { - unsigned short st_dev; - unsigned short st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned short st_rdev; - unsigned long st_size; - unsigned long st_atime; - unsigned long st_mtime; - unsigned long st_ctime; -}; - -struct stat { - unsigned long st_dev; - unsigned long st_ino; - unsigned short st_mode; - unsigned short st_nlink; - unsigned short st_uid; - unsigned short st_gid; - unsigned long st_rdev; - unsigned long st_size; - unsigned long st_blksize; - unsigned long st_blocks; - unsigned long st_atime; - unsigned long st_atime_nsec; - unsigned long st_mtime; - unsigned long st_mtime_nsec; - unsigned long st_ctime; - unsigned long st_ctime_nsec; - unsigned long __unused4; - unsigned long __unused5; -}; - -#define STAT_HAVE_NSEC 1 - -struct stat64 { - unsigned long long st_dev; - - unsigned long long st_ino; - unsigned int st_mode; - unsigned int st_nlink; - - unsigned long st_uid; - unsigned long st_gid; - - unsigned long long st_rdev; - - long long st_size; - unsigned long __pad1; /* align 64-bit st_blocks */ - unsigned long st_blksize; - - unsigned long long st_blocks; /* Number 512-byte blocks allocated. */ - - unsigned long st_atime; - unsigned long st_atime_nsec; - - unsigned long st_mtime; - unsigned long st_mtime_nsec; - - unsigned long st_ctime; - unsigned long st_ctime_nsec; - - unsigned long __unused1; - unsigned long __unused2; -}; - -#endif /* _UAPI__ASM_AVR32_STAT_H */ diff --git a/arch/avr32/include/uapi/asm/swab.h b/arch/avr32/include/uapi/asm/swab.h deleted file mode 100644 index 1a03549e7dc5..000000000000 --- a/arch/avr32/include/uapi/asm/swab.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * AVR32 byteswapping functions. - */ -#ifndef _UAPI__ASM_AVR32_SWAB_H -#define _UAPI__ASM_AVR32_SWAB_H - -#include <linux/types.h> -#include <linux/compiler.h> - -#define __SWAB_64_THRU_32__ - -#ifdef __CHECKER__ -extern unsigned long __builtin_bswap_32(unsigned long x); -extern unsigned short __builtin_bswap_16(unsigned short x); -#endif - -/* - * avr32-linux-gcc versions earlier than 4.2 improperly sign-extends - * the result. - */ -#if !(__GNUC__ == 4 && __GNUC_MINOR__ < 2) -static inline __attribute_const__ __u16 __arch_swab16(__u16 val) -{ - return __builtin_bswap_16(val); -} -#define __arch_swab16 __arch_swab16 - -static inline __attribute_const__ __u32 __arch_swab32(__u32 val) -{ - return __builtin_bswap_32(val); -} -#define __arch_swab32 __arch_swab32 -#endif - -#endif /* _UAPI__ASM_AVR32_SWAB_H */ diff --git a/arch/avr32/include/uapi/asm/termbits.h b/arch/avr32/include/uapi/asm/termbits.h deleted file mode 100644 index 32789ccb38f8..000000000000 --- a/arch/avr32/include/uapi/asm/termbits.h +++ /dev/null @@ -1,196 +0,0 @@ -#ifndef _UAPI__ASM_AVR32_TERMBITS_H -#define _UAPI__ASM_AVR32_TERMBITS_H - -#include <linux/posix_types.h> - -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -#define NCCS 19 -struct termios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ -}; - -struct termios2 { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -struct ktermios { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VTIME 5 -#define VMIN 6 -#define VSWTC 7 -#define VSTART 8 -#define VSTOP 9 -#define VSUSP 10 -#define VEOL 11 -#define VREPRINT 12 -#define VDISCARD 13 -#define VWERASE 14 -#define VLNEXT 15 -#define VEOL2 16 - -/* c_iflag bits */ -#define IGNBRK 0000001 -#define BRKINT 0000002 -#define IGNPAR 0000004 -#define PARMRK 0000010 -#define INPCK 0000020 -#define ISTRIP 0000040 -#define INLCR 0000100 -#define IGNCR 0000200 -#define ICRNL 0000400 -#define IUCLC 0001000 -#define IXON 0002000 -#define IXANY 0004000 -#define IXOFF 0010000 -#define IMAXBEL 0020000 -#define IUTF8 0040000 - -/* c_oflag bits */ -#define OPOST 0000001 -#define OLCUC 0000002 -#define ONLCR 0000004 -#define OCRNL 0000010 -#define ONOCR 0000020 -#define ONLRET 0000040 -#define OFILL 0000100 -#define OFDEL 0000200 -#define NLDLY 0000400 -#define NL0 0000000 -#define NL1 0000400 -#define CRDLY 0003000 -#define CR0 0000000 -#define CR1 0001000 -#define CR2 0002000 -#define CR3 0003000 -#define TABDLY 0014000 -#define TAB0 0000000 -#define TAB1 0004000 -#define TAB2 0010000 -#define TAB3 0014000 -#define XTABS 0014000 -#define BSDLY 0020000 -#define BS0 0000000 -#define BS1 0020000 -#define VTDLY 0040000 -#define VT0 0000000 -#define VT1 0040000 -#define FFDLY 0100000 -#define FF0 0000000 -#define FF1 0100000 - -/* c_cflag bit meaning */ -#define CBAUD 0010017 -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CSIZE 0000060 -#define CS5 0000000 -#define CS6 0000020 -#define CS7 0000040 -#define CS8 0000060 -#define CSTOPB 0000100 -#define CREAD 0000200 -#define PARENB 0000400 -#define PARODD 0001000 -#define HUPCL 0002000 -#define CLOCAL 0004000 -#define CBAUDEX 0010000 -#define B57600 0010001 -#define B115200 0010002 -#define B230400 0010003 -#define B460800 0010004 -#define B500000 0010005 -#define B576000 0010006 -#define B921600 0010007 -#define B1000000 0010010 -#define B1152000 0010011 -#define B1500000 0010012 -#define B2000000 0010013 -#define B2500000 0010014 -#define B3000000 0010015 -#define B3500000 0010016 -#define B4000000 0010017 -#define CIBAUD 002003600000 /* input baud rate (not used) */ -#define CMSPAR 010000000000 /* mark or space (stick) parity */ -#define CRTSCTS 020000000000 /* flow control */ - -/* c_lflag bits */ -#define ISIG 0000001 -#define ICANON 0000002 -#define XCASE 0000004 -#define ECHO 0000010 -#define ECHOE 0000020 -#define ECHOK 0000040 -#define ECHONL 0000100 -#define NOFLSH 0000200 -#define TOSTOP 0000400 -#define ECHOCTL 0001000 -#define ECHOPRT 0002000 -#define ECHOKE 0004000 -#define FLUSHO 0010000 -#define PENDIN 0040000 -#define IEXTEN 0100000 -#define EXTPROC 0200000 - -/* tcflow() and TCXONC use these */ -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -/* tcflush() and TCFLSH use these */ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/* tcsetattr uses these */ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -#endif /* _UAPI__ASM_AVR32_TERMBITS_H */ diff --git a/arch/avr32/include/uapi/asm/termios.h b/arch/avr32/include/uapi/asm/termios.h deleted file mode 100644 index c8a0081556c4..000000000000 --- a/arch/avr32/include/uapi/asm/termios.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _UAPI__ASM_AVR32_TERMIOS_H -#define _UAPI__ASM_AVR32_TERMIOS_H - -#include <asm/termbits.h> -#include <asm/ioctls.h> - -struct winsize { - unsigned short ws_row; - unsigned short ws_col; - unsigned short ws_xpixel; - unsigned short ws_ypixel; -}; - -#define NCC 8 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - -/* modem lines */ -#define TIOCM_LE 0x001 -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_ST 0x008 -#define TIOCM_SR 0x010 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RNG 0x080 -#define TIOCM_DSR 0x100 -#define TIOCM_CD TIOCM_CAR -#define TIOCM_RI TIOCM_RNG -#define TIOCM_OUT1 0x2000 -#define TIOCM_OUT2 0x4000 -#define TIOCM_LOOP 0x8000 - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ - -#endif /* _UAPI__ASM_AVR32_TERMIOS_H */ diff --git a/arch/avr32/include/uapi/asm/types.h b/arch/avr32/include/uapi/asm/types.h deleted file mode 100644 index 7c986c4e99b5..000000000000 --- a/arch/avr32/include/uapi/asm/types.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _UAPI__ASM_AVR32_TYPES_H -#define _UAPI__ASM_AVR32_TYPES_H - -#include <asm-generic/int-ll64.h> - -#endif /* _UAPI__ASM_AVR32_TYPES_H */ diff --git a/arch/avr32/include/uapi/asm/unistd.h b/arch/avr32/include/uapi/asm/unistd.h deleted file mode 100644 index 236505d889d0..000000000000 --- a/arch/avr32/include/uapi/asm/unistd.h +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _UAPI__ASM_AVR32_UNISTD_H -#define _UAPI__ASM_AVR32_UNISTD_H - -/* - * This file contains the system call numbers. - */ - -#define __NR_restart_syscall 0 -#define __NR_exit 1 -#define __NR_fork 2 -#define __NR_read 3 -#define __NR_write 4 -#define __NR_open 5 -#define __NR_close 6 -#define __NR_umask 7 -#define __NR_creat 8 -#define __NR_link 9 -#define __NR_unlink 10 -#define __NR_execve 11 -#define __NR_chdir 12 -#define __NR_time 13 -#define __NR_mknod 14 -#define __NR_chmod 15 -#define __NR_chown 16 -#define __NR_lchown 17 -#define __NR_lseek 18 -#define __NR__llseek 19 -#define __NR_getpid 20 -#define __NR_mount 21 -#define __NR_umount2 22 -#define __NR_setuid 23 -#define __NR_getuid 24 -#define __NR_stime 25 -#define __NR_ptrace 26 -#define __NR_alarm 27 -#define __NR_pause 28 -#define __NR_utime 29 -#define __NR_stat 30 -#define __NR_fstat 31 -#define __NR_lstat 32 -#define __NR_access 33 -#define __NR_chroot 34 -#define __NR_sync 35 -#define __NR_fsync 36 -#define __NR_kill 37 -#define __NR_rename 38 -#define __NR_mkdir 39 -#define __NR_rmdir 40 -#define __NR_dup 41 -#define __NR_pipe 42 -#define __NR_times 43 -#define __NR_clone 44 -#define __NR_brk 45 -#define __NR_setgid 46 -#define __NR_getgid 47 -#define __NR_getcwd 48 -#define __NR_geteuid 49 -#define __NR_getegid 50 -#define __NR_acct 51 -#define __NR_setfsuid 52 -#define __NR_setfsgid 53 -#define __NR_ioctl 54 -#define __NR_fcntl 55 -#define __NR_setpgid 56 -#define __NR_mremap 57 -#define __NR_setresuid 58 -#define __NR_getresuid 59 -#define __NR_setreuid 60 -#define __NR_setregid 61 -#define __NR_ustat 62 -#define __NR_dup2 63 -#define __NR_getppid 64 -#define __NR_getpgrp 65 -#define __NR_setsid 66 -#define __NR_rt_sigaction 67 -#define __NR_rt_sigreturn 68 -#define __NR_rt_sigprocmask 69 -#define __NR_rt_sigpending 70 -#define __NR_rt_sigtimedwait 71 -#define __NR_rt_sigqueueinfo 72 -#define __NR_rt_sigsuspend 73 -#define __NR_sethostname 74 -#define __NR_setrlimit 75 -#define __NR_getrlimit 76 /* SuS compliant getrlimit */ -#define __NR_getrusage 77 -#define __NR_gettimeofday 78 -#define __NR_settimeofday 79 -#define __NR_getgroups 80 -#define __NR_setgroups 81 -#define __NR_select 82 -#define __NR_symlink 83 -#define __NR_fchdir 84 -#define __NR_readlink 85 -#define __NR_pread 86 -#define __NR_pwrite 87 -#define __NR_swapon 88 -#define __NR_reboot 89 -#define __NR_mmap2 90 -#define __NR_munmap 91 -#define __NR_truncate 92 -#define __NR_ftruncate 93 -#define __NR_fchmod 94 -#define __NR_fchown 95 -#define __NR_getpriority 96 -#define __NR_setpriority 97 -#define __NR_wait4 98 -#define __NR_statfs 99 -#define __NR_fstatfs 100 -#define __NR_vhangup 101 -#define __NR_sigaltstack 102 -#define __NR_syslog 103 -#define __NR_setitimer 104 -#define __NR_getitimer 105 -#define __NR_swapoff 106 -#define __NR_sysinfo 107 -/* 108 was __NR_ipc for a little while */ -#define __NR_sendfile 109 -#define __NR_setdomainname 110 -#define __NR_uname 111 -#define __NR_adjtimex 112 -#define __NR_mprotect 113 -#define __NR_vfork 114 -#define __NR_init_module 115 -#define __NR_delete_module 116 -#define __NR_quotactl 117 -#define __NR_getpgid 118 -#define __NR_bdflush 119 -#define __NR_sysfs 120 -#define __NR_personality 121 -#define __NR_afs_syscall 122 /* Syscall for Andrew File System */ -#define __NR_getdents 123 -#define __NR_flock 124 -#define __NR_msync 125 -#define __NR_readv 126 -#define __NR_writev 127 -#define __NR_getsid 128 -#define __NR_fdatasync 129 -#define __NR__sysctl 130 -#define __NR_mlock 131 -#define __NR_munlock 132 -#define __NR_mlockall 133 -#define __NR_munlockall 134 -#define __NR_sched_setparam 135 -#define __NR_sched_getparam 136 -#define __NR_sched_setscheduler 137 -#define __NR_sched_getscheduler 138 -#define __NR_sched_yield 139 -#define __NR_sched_get_priority_max 140 -#define __NR_sched_get_priority_min 141 -#define __NR_sched_rr_get_interval 142 -#define __NR_nanosleep 143 -#define __NR_poll 144 -#define __NR_nfsservctl 145 -#define __NR_setresgid 146 -#define __NR_getresgid 147 -#define __NR_prctl 148 -#define __NR_socket 149 -#define __NR_bind 150 -#define __NR_connect 151 -#define __NR_listen 152 -#define __NR_accept 153 -#define __NR_getsockname 154 -#define __NR_getpeername 155 -#define __NR_socketpair 156 -#define __NR_send 157 -#define __NR_recv 158 -#define __NR_sendto 159 -#define __NR_recvfrom 160 -#define __NR_shutdown 161 -#define __NR_setsockopt 162 -#define __NR_getsockopt 163 -#define __NR_sendmsg 164 -#define __NR_recvmsg 165 -#define __NR_truncate64 166 -#define __NR_ftruncate64 167 -#define __NR_stat64 168 -#define __NR_lstat64 169 -#define __NR_fstat64 170 -#define __NR_pivot_root 171 -#define __NR_mincore 172 -#define __NR_madvise 173 -#define __NR_getdents64 174 -#define __NR_fcntl64 175 -#define __NR_gettid 176 -#define __NR_readahead 177 -#define __NR_setxattr 178 -#define __NR_lsetxattr 179 -#define __NR_fsetxattr 180 -#define __NR_getxattr 181 -#define __NR_lgetxattr 182 -#define __NR_fgetxattr 183 -#define __NR_listxattr 184 -#define __NR_llistxattr 185 -#define __NR_flistxattr 186 -#define __NR_removexattr 187 -#define __NR_lremovexattr 188 -#define __NR_fremovexattr 189 -#define __NR_tkill 190 -#define __NR_sendfile64 191 -#define __NR_futex 192 -#define __NR_sched_setaffinity 193 -#define __NR_sched_getaffinity 194 -#define __NR_capget 195 -#define __NR_capset 196 -#define __NR_io_setup 197 -#define __NR_io_destroy 198 -#define __NR_io_getevents 199 -#define __NR_io_submit 200 -#define __NR_io_cancel 201 -#define __NR_fadvise64 202 -#define __NR_exit_group 203 -#define __NR_lookup_dcookie 204 -#define __NR_epoll_create 205 -#define __NR_epoll_ctl 206 -#define __NR_epoll_wait 207 -#define __NR_remap_file_pages 208 -#define __NR_set_tid_address 209 -#define __NR_timer_create 210 -#define __NR_timer_settime 211 -#define __NR_timer_gettime 212 -#define __NR_timer_getoverrun 213 -#define __NR_timer_delete 214 -#define __NR_clock_settime 215 -#define __NR_clock_gettime 216 -#define __NR_clock_getres 217 -#define __NR_clock_nanosleep 218 -#define __NR_statfs64 219 -#define __NR_fstatfs64 220 -#define __NR_tgkill 221 -/* 222 reserved for tux */ -#define __NR_utimes 223 -#define __NR_fadvise64_64 224 -#define __NR_cacheflush 225 -#define __NR_vserver 226 -#define __NR_mq_open 227 -#define __NR_mq_unlink 228 -#define __NR_mq_timedsend 229 -#define __NR_mq_timedreceive 230 -#define __NR_mq_notify 231 -#define __NR_mq_getsetattr 232 -#define __NR_kexec_load 233 -#define __NR_waitid 234 -#define __NR_add_key 235 -#define __NR_request_key 236 -#define __NR_keyctl 237 -#define __NR_ioprio_set 238 -#define __NR_ioprio_get 239 -#define __NR_inotify_init 240 -#define __NR_inotify_add_watch 241 -#define __NR_inotify_rm_watch 242 -#define __NR_openat 243 -#define __NR_mkdirat 244 -#define __NR_mknodat 245 -#define __NR_fchownat 246 -#define __NR_futimesat 247 -#define __NR_fstatat64 248 -#define __NR_unlinkat 249 -#define __NR_renameat 250 -#define __NR_linkat 251 -#define __NR_symlinkat 252 -#define __NR_readlinkat 253 -#define __NR_fchmodat 254 -#define __NR_faccessat 255 -#define __NR_pselect6 256 -#define __NR_ppoll 257 -#define __NR_unshare 258 -#define __NR_set_robust_list 259 -#define __NR_get_robust_list 260 -#define __NR_splice 261 -#define __NR_sync_file_range 262 -#define __NR_tee 263 -#define __NR_vmsplice 264 -#define __NR_epoll_pwait 265 -#define __NR_msgget 266 -#define __NR_msgsnd 267 -#define __NR_msgrcv 268 -#define __NR_msgctl 269 -#define __NR_semget 270 -#define __NR_semop 271 -#define __NR_semctl 272 -#define __NR_semtimedop 273 -#define __NR_shmat 274 -#define __NR_shmget 275 -#define __NR_shmdt 276 -#define __NR_shmctl 277 -#define __NR_utimensat 278 -#define __NR_signalfd 279 -/* 280 was __NR_timerfd */ -#define __NR_eventfd 281 -/* 282 was half-implemented __NR_recvmmsg */ -#define __NR_setns 283 -#define __NR_pread64 284 -#define __NR_pwrite64 285 -#define __NR_timerfd_create 286 -#define __NR_fallocate 287 -#define __NR_timerfd_settime 288 -#define __NR_timerfd_gettime 289 -#define __NR_signalfd4 290 -#define __NR_eventfd2 291 -#define __NR_epoll_create1 292 -#define __NR_dup3 293 -#define __NR_pipe2 294 -#define __NR_inotify_init1 295 -#define __NR_preadv 296 -#define __NR_pwritev 297 -#define __NR_rt_tgsigqueueinfo 298 -#define __NR_perf_event_open 299 -#define __NR_recvmmsg 300 -#define __NR_fanotify_init 301 -#define __NR_fanotify_mark 302 -#define __NR_prlimit64 303 -#define __NR_name_to_handle_at 304 -#define __NR_open_by_handle_at 305 -#define __NR_clock_adjtime 306 -#define __NR_syncfs 307 -#define __NR_sendmmsg 308 -#define __NR_process_vm_readv 309 -#define __NR_process_vm_writev 310 -#define __NR_kcmp 311 -#define __NR_finit_module 312 -#define __NR_sched_setattr 313 -#define __NR_sched_getattr 314 -#define __NR_renameat2 315 -#define __NR_seccomp 316 -#define __NR_getrandom 317 -#define __NR_memfd_create 318 -#define __NR_bpf 319 -#define __NR_execveat 320 -#define __NR_accept4 321 -#define __NR_userfaultfd 322 -#define __NR_membarrier 323 -#define __NR_mlock2 324 -#define __NR_copy_file_range 325 -#define __NR_preadv2 326 -#define __NR_pwritev2 327 -#define __NR_pkey_mprotect 328 -#define __NR_pkey_alloc 329 -#define __NR_pkey_free 330 - -#endif /* _UAPI__ASM_AVR32_UNISTD_H */ diff --git a/arch/avr32/kernel/.gitignore b/arch/avr32/kernel/.gitignore deleted file mode 100644 index c5f676c3c224..000000000000 --- a/arch/avr32/kernel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vmlinux.lds diff --git a/arch/avr32/kernel/Makefile b/arch/avr32/kernel/Makefile deleted file mode 100644 index 119a2e41defe..000000000000 --- a/arch/avr32/kernel/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# Makefile for the Linux/AVR32 kernel. -# - -extra-y := head.o vmlinux.lds - -obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o -obj-y += syscall_table.o syscall-stubs.o irq.o -obj-y += setup.o traps.o ocd.o ptrace.o -obj-y += signal.o process.o time.o -obj-y += switch_to.o cpu.o -obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o -obj-$(CONFIG_KPROBES) += kprobes.o -obj-$(CONFIG_STACKTRACE) += stacktrace.o -obj-$(CONFIG_NMI_DEBUGGING) += nmi_debug.o diff --git a/arch/avr32/kernel/asm-offsets.c b/arch/avr32/kernel/asm-offsets.c deleted file mode 100644 index 2c9764fe3532..000000000000 --- a/arch/avr32/kernel/asm-offsets.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Generate definitions needed by assembly language modules. - * This code generates raw asm output which is post-processed - * to extract and format the required data. - */ - -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/thread_info.h> -#include <linux/kbuild.h> - -void foo(void) -{ - OFFSET(TI_task, thread_info, task); - OFFSET(TI_flags, thread_info, flags); - OFFSET(TI_cpu, thread_info, cpu); - OFFSET(TI_preempt_count, thread_info, preempt_count); - OFFSET(TI_rar_saved, thread_info, rar_saved); - OFFSET(TI_rsr_saved, thread_info, rsr_saved); - BLANK(); - OFFSET(TSK_active_mm, task_struct, active_mm); - BLANK(); - OFFSET(MM_pgd, mm_struct, pgd); -} diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c deleted file mode 100644 index 0d05fd095468..000000000000 --- a/arch/avr32/kernel/avr32_ksyms.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Export AVR32-specific functions for loadable modules. - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/module.h> - -#include <asm/checksum.h> -#include <linux/uaccess.h> - -/* - * GCC functions - */ -extern unsigned long long __avr32_lsl64(unsigned long long u, unsigned long b); -extern unsigned long long __avr32_lsr64(unsigned long long u, unsigned long b); -extern unsigned long long __avr32_asr64(unsigned long long u, unsigned long b); -EXPORT_SYMBOL(__avr32_lsl64); -EXPORT_SYMBOL(__avr32_lsr64); -EXPORT_SYMBOL(__avr32_asr64); - -/* - * String functions - */ -EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memcpy); - -EXPORT_SYMBOL(clear_page); -EXPORT_SYMBOL(copy_page); - -/* - * Userspace access stuff. - */ -EXPORT_SYMBOL(___copy_from_user); -EXPORT_SYMBOL(copy_to_user); -EXPORT_SYMBOL(__copy_user); -EXPORT_SYMBOL(strncpy_from_user); -EXPORT_SYMBOL(__strncpy_from_user); -EXPORT_SYMBOL(clear_user); -EXPORT_SYMBOL(__clear_user); -EXPORT_SYMBOL(strnlen_user); - -EXPORT_SYMBOL(csum_partial); -EXPORT_SYMBOL(csum_partial_copy_generic); - -/* Delay loops (lib/delay.S) */ -EXPORT_SYMBOL(__ndelay); -EXPORT_SYMBOL(__udelay); -EXPORT_SYMBOL(__const_udelay); - -/* Bit operations (lib/findbit.S) */ -EXPORT_SYMBOL(find_first_zero_bit); -EXPORT_SYMBOL(find_next_zero_bit); -EXPORT_SYMBOL(find_first_bit); -EXPORT_SYMBOL(find_next_bit); -EXPORT_SYMBOL(find_next_bit_le); -EXPORT_SYMBOL(find_next_zero_bit_le); - -/* I/O primitives (lib/io-*.S) */ -EXPORT_SYMBOL(__raw_readsb); -EXPORT_SYMBOL(__raw_readsw); -EXPORT_SYMBOL(__raw_readsl); -EXPORT_SYMBOL(__raw_writesb); -EXPORT_SYMBOL(__raw_writesw); -EXPORT_SYMBOL(__raw_writesl); diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c deleted file mode 100644 index 0341ae27c9ec..000000000000 --- a/arch/avr32/kernel/cpu.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/init.h> -#include <linux/device.h> -#include <linux/seq_file.h> -#include <linux/cpu.h> -#include <linux/module.h> -#include <linux/percpu.h> -#include <linux/param.h> -#include <linux/errno.h> -#include <linux/clk.h> - -#include <asm/setup.h> -#include <asm/sysreg.h> - -static DEFINE_PER_CPU(struct cpu, cpu_devices); - -#ifdef CONFIG_PERFORMANCE_COUNTERS - -/* - * XXX: If/when a SMP-capable implementation of AVR32 will ever be - * made, we must make sure that the code executes on the correct CPU. - */ -static ssize_t show_pc0event(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pccr; - - pccr = sysreg_read(PCCR); - return sprintf(buf, "0x%lx\n", (pccr >> 12) & 0x3f); -} -static ssize_t store_pc0event(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - if (val > 0x3f) - return -EINVAL; - val = (val << 12) | (sysreg_read(PCCR) & 0xfffc0fff); - sysreg_write(PCCR, val); - return count; -} -static ssize_t show_pc0count(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pcnt0; - - pcnt0 = sysreg_read(PCNT0); - return sprintf(buf, "%lu\n", pcnt0); -} -static ssize_t store_pc0count(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - sysreg_write(PCNT0, val); - - return count; -} - -static ssize_t show_pc1event(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pccr; - - pccr = sysreg_read(PCCR); - return sprintf(buf, "0x%lx\n", (pccr >> 18) & 0x3f); -} -static ssize_t store_pc1event(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - if (val > 0x3f) - return -EINVAL; - val = (val << 18) | (sysreg_read(PCCR) & 0xff03ffff); - sysreg_write(PCCR, val); - return count; -} -static ssize_t show_pc1count(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pcnt1; - - pcnt1 = sysreg_read(PCNT1); - return sprintf(buf, "%lu\n", pcnt1); -} -static ssize_t store_pc1count(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - sysreg_write(PCNT1, val); - - return count; -} - -static ssize_t show_pccycles(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pccnt; - - pccnt = sysreg_read(PCCNT); - return sprintf(buf, "%lu\n", pccnt); -} -static ssize_t store_pccycles(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - sysreg_write(PCCNT, val); - - return count; -} - -static ssize_t show_pcenable(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pccr; - - pccr = sysreg_read(PCCR); - return sprintf(buf, "%c\n", (pccr & 1)?'1':'0'); -} -static ssize_t store_pcenable(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long pccr, val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - if (val) - val = 1; - - pccr = sysreg_read(PCCR); - pccr = (pccr & ~1UL) | val; - sysreg_write(PCCR, pccr); - - return count; -} - -static DEVICE_ATTR(pc0event, 0600, show_pc0event, store_pc0event); -static DEVICE_ATTR(pc0count, 0600, show_pc0count, store_pc0count); -static DEVICE_ATTR(pc1event, 0600, show_pc1event, store_pc1event); -static DEVICE_ATTR(pc1count, 0600, show_pc1count, store_pc1count); -static DEVICE_ATTR(pccycles, 0600, show_pccycles, store_pccycles); -static DEVICE_ATTR(pcenable, 0600, show_pcenable, store_pcenable); - -#endif /* CONFIG_PERFORMANCE_COUNTERS */ - -static int __init topology_init(void) -{ - int cpu; - - for_each_possible_cpu(cpu) { - struct cpu *c = &per_cpu(cpu_devices, cpu); - - register_cpu(c, cpu); - -#ifdef CONFIG_PERFORMANCE_COUNTERS - device_create_file(&c->dev, &dev_attr_pc0event); - device_create_file(&c->dev, &dev_attr_pc0count); - device_create_file(&c->dev, &dev_attr_pc1event); - device_create_file(&c->dev, &dev_attr_pc1count); - device_create_file(&c->dev, &dev_attr_pccycles); - device_create_file(&c->dev, &dev_attr_pcenable); -#endif - } - - return 0; -} - -subsys_initcall(topology_init); - -struct chip_id_map { - u16 mid; - u16 pn; - const char *name; -}; - -static const struct chip_id_map chip_names[] = { - { .mid = 0x1f, .pn = 0x1e82, .name = "AT32AP700x" }, -}; -#define NR_CHIP_NAMES ARRAY_SIZE(chip_names) - -static const char *cpu_names[] = { - "Morgan", - "AP7", -}; -#define NR_CPU_NAMES ARRAY_SIZE(cpu_names) - -static const char *arch_names[] = { - "AVR32A", - "AVR32B", -}; -#define NR_ARCH_NAMES ARRAY_SIZE(arch_names) - -static const char *mmu_types[] = { - "No MMU", - "ITLB and DTLB", - "Shared TLB", - "MPU" -}; - -static const char *cpu_feature_flags[] = { - "rmw", "dsp", "simd", "ocd", "perfctr", "java", "fpu", -}; - -static const char *get_chip_name(struct avr32_cpuinfo *cpu) -{ - unsigned int i; - unsigned int mid = avr32_get_manufacturer_id(cpu); - unsigned int pn = avr32_get_product_number(cpu); - - for (i = 0; i < NR_CHIP_NAMES; i++) { - if (chip_names[i].mid == mid && chip_names[i].pn == pn) - return chip_names[i].name; - } - - return "(unknown)"; -} - -void __init setup_processor(void) -{ - unsigned long config0, config1; - unsigned long features; - unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type; - unsigned device_id; - unsigned tmp; - unsigned i; - - config0 = sysreg_read(CONFIG0); - config1 = sysreg_read(CONFIG1); - cpu_id = SYSREG_BFEXT(PROCESSORID, config0); - cpu_rev = SYSREG_BFEXT(PROCESSORREVISION, config0); - arch_id = SYSREG_BFEXT(AT, config0); - arch_rev = SYSREG_BFEXT(AR, config0); - mmu_type = SYSREG_BFEXT(MMUT, config0); - - device_id = ocd_read(DID); - - boot_cpu_data.arch_type = arch_id; - boot_cpu_data.cpu_type = cpu_id; - boot_cpu_data.arch_revision = arch_rev; - boot_cpu_data.cpu_revision = cpu_rev; - boot_cpu_data.tlb_config = mmu_type; - boot_cpu_data.device_id = device_id; - - tmp = SYSREG_BFEXT(ILSZ, config1); - if (tmp) { - boot_cpu_data.icache.ways = 1 << SYSREG_BFEXT(IASS, config1); - boot_cpu_data.icache.sets = 1 << SYSREG_BFEXT(ISET, config1); - boot_cpu_data.icache.linesz = 1 << (tmp + 1); - } - tmp = SYSREG_BFEXT(DLSZ, config1); - if (tmp) { - boot_cpu_data.dcache.ways = 1 << SYSREG_BFEXT(DASS, config1); - boot_cpu_data.dcache.sets = 1 << SYSREG_BFEXT(DSET, config1); - boot_cpu_data.dcache.linesz = 1 << (tmp + 1); - } - - if ((cpu_id >= NR_CPU_NAMES) || (arch_id >= NR_ARCH_NAMES)) { - printk ("Unknown CPU configuration (ID %02x, arch %02x), " - "continuing anyway...\n", - cpu_id, arch_id); - return; - } - - printk ("CPU: %s chip revision %c\n", get_chip_name(&boot_cpu_data), - avr32_get_chip_revision(&boot_cpu_data) + 'A'); - printk ("CPU: %s [%02x] core revision %d (%s arch revision %d)\n", - cpu_names[cpu_id], cpu_id, cpu_rev, - arch_names[arch_id], arch_rev); - printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]); - - printk ("CPU: features:"); - features = 0; - if (config0 & SYSREG_BIT(CONFIG0_R)) - features |= AVR32_FEATURE_RMW; - if (config0 & SYSREG_BIT(CONFIG0_D)) - features |= AVR32_FEATURE_DSP; - if (config0 & SYSREG_BIT(CONFIG0_S)) - features |= AVR32_FEATURE_SIMD; - if (config0 & SYSREG_BIT(CONFIG0_O)) - features |= AVR32_FEATURE_OCD; - if (config0 & SYSREG_BIT(CONFIG0_P)) - features |= AVR32_FEATURE_PCTR; - if (config0 & SYSREG_BIT(CONFIG0_J)) - features |= AVR32_FEATURE_JAVA; - if (config0 & SYSREG_BIT(CONFIG0_F)) - features |= AVR32_FEATURE_FPU; - - for (i = 0; i < ARRAY_SIZE(cpu_feature_flags); i++) - if (features & (1 << i)) - printk(" %s", cpu_feature_flags[i]); - - printk("\n"); - boot_cpu_data.features = features; -} - -#ifdef CONFIG_PROC_FS -static int c_show(struct seq_file *m, void *v) -{ - unsigned int icache_size, dcache_size; - unsigned int cpu = smp_processor_id(); - unsigned int freq; - unsigned int i; - - icache_size = boot_cpu_data.icache.ways * - boot_cpu_data.icache.sets * - boot_cpu_data.icache.linesz; - dcache_size = boot_cpu_data.dcache.ways * - boot_cpu_data.dcache.sets * - boot_cpu_data.dcache.linesz; - - seq_printf(m, "processor\t: %d\n", cpu); - - seq_printf(m, "chip type\t: %s revision %c\n", - get_chip_name(&boot_cpu_data), - avr32_get_chip_revision(&boot_cpu_data) + 'A'); - if (boot_cpu_data.arch_type < NR_ARCH_NAMES) - seq_printf(m, "cpu arch\t: %s revision %d\n", - arch_names[boot_cpu_data.arch_type], - boot_cpu_data.arch_revision); - if (boot_cpu_data.cpu_type < NR_CPU_NAMES) - seq_printf(m, "cpu core\t: %s revision %d\n", - cpu_names[boot_cpu_data.cpu_type], - boot_cpu_data.cpu_revision); - - freq = (clk_get_rate(boot_cpu_data.clk) + 500) / 1000; - seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, freq % 1000); - - seq_printf(m, "i-cache\t\t: %dK (%u ways x %u sets x %u)\n", - icache_size >> 10, - boot_cpu_data.icache.ways, - boot_cpu_data.icache.sets, - boot_cpu_data.icache.linesz); - seq_printf(m, "d-cache\t\t: %dK (%u ways x %u sets x %u)\n", - dcache_size >> 10, - boot_cpu_data.dcache.ways, - boot_cpu_data.dcache.sets, - boot_cpu_data.dcache.linesz); - - seq_printf(m, "features\t:"); - for (i = 0; i < ARRAY_SIZE(cpu_feature_flags); i++) - if (boot_cpu_data.features & (1 << i)) - seq_printf(m, " %s", cpu_feature_flags[i]); - - seq_printf(m, "\nbogomips\t: %lu.%02lu\n", - boot_cpu_data.loops_per_jiffy / (500000/HZ), - (boot_cpu_data.loops_per_jiffy / (5000/HZ)) % 100); - - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - return *pos < 1 ? (void *)1 : NULL; -} - -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return NULL; -} - -static void c_stop(struct seq_file *m, void *v) -{ - -} - -const struct seq_operations cpuinfo_op = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = c_show -}; -#endif /* CONFIG_PROC_FS */ diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S deleted file mode 100644 index 7301f4806bbe..000000000000 --- a/arch/avr32/kernel/entry-avr32b.S +++ /dev/null @@ -1,877 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* - * This file contains the low-level entry-points into the kernel, that is, - * exception handlers, debug trap handlers, interrupt handlers and the - * system call handler. - */ -#include <linux/errno.h> - -#include <asm/asm.h> -#include <asm/hardirq.h> -#include <asm/irq.h> -#include <asm/ocd.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/ptrace.h> -#include <asm/sysreg.h> -#include <asm/thread_info.h> -#include <asm/unistd.h> - -#ifdef CONFIG_PREEMPT -# define preempt_stop mask_interrupts -#else -# define preempt_stop -# define fault_resume_kernel fault_restore_all -#endif - -#define __MASK(x) ((1 << (x)) - 1) -#define IRQ_MASK ((__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) | \ - (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)) - - .section .ex.text,"ax",@progbits - .align 2 -exception_vectors: - bral handle_critical - .align 2 - bral handle_critical - .align 2 - bral do_bus_error_write - .align 2 - bral do_bus_error_read - .align 2 - bral do_nmi_ll - .align 2 - bral handle_address_fault - .align 2 - bral handle_protection_fault - .align 2 - bral handle_debug - .align 2 - bral do_illegal_opcode_ll - .align 2 - bral do_illegal_opcode_ll - .align 2 - bral do_illegal_opcode_ll - .align 2 - bral do_fpe_ll - .align 2 - bral do_illegal_opcode_ll - .align 2 - bral handle_address_fault - .align 2 - bral handle_address_fault - .align 2 - bral handle_protection_fault - .align 2 - bral handle_protection_fault - .align 2 - bral do_dtlb_modified - -#define tlbmiss_save pushm r0-r3 -#define tlbmiss_restore popm r0-r3 - - .org 0x50 - .global itlb_miss -itlb_miss: - tlbmiss_save - rjmp tlb_miss_common - - .org 0x60 -dtlb_miss_read: - tlbmiss_save - rjmp tlb_miss_common - - .org 0x70 -dtlb_miss_write: - tlbmiss_save - - .global tlb_miss_common - .align 2 -tlb_miss_common: - mfsr r0, SYSREG_TLBEAR - mfsr r1, SYSREG_PTBR - - /* - * First level lookup: The PGD contains virtual pointers to - * the second-level page tables, but they may be NULL if not - * present. - */ -pgtbl_lookup: - lsr r2, r0, PGDIR_SHIFT - ld.w r3, r1[r2 << 2] - bfextu r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT - cp.w r3, 0 - breq page_table_not_present - - /* Second level lookup */ - ld.w r2, r3[r1 << 2] - mfsr r0, SYSREG_TLBARLO - bld r2, _PAGE_BIT_PRESENT - brcc page_not_present - - /* Mark the page as accessed */ - sbr r2, _PAGE_BIT_ACCESSED - st.w r3[r1 << 2], r2 - - /* Drop software flags */ - andl r2, _PAGE_FLAGS_HARDWARE_MASK & 0xffff - mtsr SYSREG_TLBELO, r2 - - /* Figure out which entry we want to replace */ - mfsr r1, SYSREG_MMUCR - clz r2, r0 - brcc 1f - mov r3, -1 /* All entries have been accessed, */ - mov r2, 0 /* so start at 0 */ - mtsr SYSREG_TLBARLO, r3 /* and reset TLBAR */ - -1: bfins r1, r2, SYSREG_DRP_OFFSET, SYSREG_DRP_SIZE - mtsr SYSREG_MMUCR, r1 - tlbw - - tlbmiss_restore - rete - - /* The slow path of the TLB miss handler */ - .align 2 -page_table_not_present: - /* Do we need to synchronize with swapper_pg_dir? */ - bld r0, 31 - brcs sync_with_swapper_pg_dir - -page_not_present: - tlbmiss_restore - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mfsr r12, SYSREG_ECR - mov r11, sp - call do_page_fault - rjmp ret_from_exception - - .align 2 -sync_with_swapper_pg_dir: - /* - * If swapper_pg_dir contains a non-NULL second-level page - * table pointer, copy it into the current PGD. If not, we - * must handle it as a full-blown page fault. - * - * Jumping back to pgtbl_lookup causes an unnecessary lookup, - * but it is guaranteed to be a cache hit, it won't happen - * very often, and we absolutely do not want to sacrifice any - * performance in the fast path in order to improve this. - */ - mov r1, lo(swapper_pg_dir) - orh r1, hi(swapper_pg_dir) - ld.w r3, r1[r2 << 2] - cp.w r3, 0 - breq page_not_present - mfsr r1, SYSREG_PTBR - st.w r1[r2 << 2], r3 - rjmp pgtbl_lookup - - /* - * We currently have two bytes left at this point until we - * crash into the system call handler... - * - * Don't worry, the assembler will let us know. - */ - - - /* --- System Call --- */ - - .org 0x100 -system_call: -#ifdef CONFIG_PREEMPT - mask_interrupts -#endif - pushm r12 /* r12_orig */ - stmts --sp, r0-lr - - mfsr r0, SYSREG_RAR_SUP - mfsr r1, SYSREG_RSR_SUP -#ifdef CONFIG_PREEMPT - unmask_interrupts -#endif - zero_fp - stm --sp, r0-r1 - - /* check for syscall tracing */ - get_thread_info r0 - ld.w r1, r0[TI_flags] - bld r1, TIF_SYSCALL_TRACE - brcs syscall_trace_enter - -syscall_trace_cont: - cp.w r8, NR_syscalls - brhs syscall_badsys - - lddpc lr, syscall_table_addr - ld.w lr, lr[r8 << 2] - mov r8, r5 /* 5th argument (6th is pushed by stub) */ - icall lr - - .global syscall_return -syscall_return: - get_thread_info r0 - mask_interrupts /* make sure we don't miss an interrupt - setting need_resched or sigpending - between sampling and the rets */ - - /* Store the return value so that the correct value is loaded below */ - stdsp sp[REG_R12], r12 - - ld.w r1, r0[TI_flags] - andl r1, _TIF_ALLWORK_MASK, COH - brne syscall_exit_work - -syscall_exit_cont: - popm r8-r9 - mtsr SYSREG_RAR_SUP, r8 - mtsr SYSREG_RSR_SUP, r9 - ldmts sp++, r0-lr - sub sp, -4 /* r12_orig */ - rets - - .align 2 -syscall_table_addr: - .long sys_call_table - -syscall_badsys: - mov r12, -ENOSYS - rjmp syscall_return - - .global ret_from_fork -ret_from_fork: - call schedule_tail - mov r12, 0 - rjmp syscall_return - - .global ret_from_kernel_thread -ret_from_kernel_thread: - call schedule_tail - mov r12, r0 - mov lr, r2 /* syscall_return */ - mov pc, r1 - -syscall_trace_enter: - pushm r8-r12 - call syscall_trace - popm r8-r12 - rjmp syscall_trace_cont - -syscall_exit_work: - bld r1, TIF_SYSCALL_TRACE - brcc 1f - unmask_interrupts - call syscall_trace - mask_interrupts - ld.w r1, r0[TI_flags] - -1: bld r1, TIF_NEED_RESCHED - brcc 2f - unmask_interrupts - call schedule - mask_interrupts - ld.w r1, r0[TI_flags] - rjmp 1b - -2: mov r2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME - tst r1, r2 - breq 3f - unmask_interrupts - mov r12, sp - mov r11, r0 - call do_notify_resume - mask_interrupts - ld.w r1, r0[TI_flags] - rjmp 1b - -3: bld r1, TIF_BREAKPOINT - brcc syscall_exit_cont - rjmp enter_monitor_mode - - /* This function expects to find offending PC in SYSREG_RAR_EX */ - .type save_full_context_ex, @function - .align 2 -save_full_context_ex: - mfsr r11, SYSREG_RAR_EX - sub r9, pc, . - debug_trampoline - mfsr r8, SYSREG_RSR_EX - cp.w r9, r11 - breq 3f - mov r12, r8 - andh r8, (MODE_MASK >> 16), COH - brne 2f - -1: pushm r11, r12 /* PC and SR */ - unmask_exceptions - ret r12 - -2: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR) - stdsp sp[4], r10 /* replace saved SP */ - rjmp 1b - - /* - * The debug handler set up a trampoline to make us - * automatically enter monitor mode upon return, but since - * we're saving the full context, we must assume that the - * exception handler might want to alter the return address - * and/or status register. So we need to restore the original - * context and enter monitor mode manually after the exception - * has been handled. - */ -3: get_thread_info r8 - ld.w r11, r8[TI_rar_saved] - ld.w r12, r8[TI_rsr_saved] - rjmp 1b - .size save_full_context_ex, . - save_full_context_ex - - /* Low-level exception handlers */ -handle_critical: - /* - * AT32AP700x errata: - * - * After a Java stack overflow or underflow trap, any CPU - * memory access may cause erratic behavior. This will happen - * when the four least significant bits of the JOSP system - * register contains any value between 9 and 15 (inclusive). - * - * Possible workarounds: - * - Don't use the Java Extension Module - * - Ensure that the stack overflow and underflow trap - * handlers do not do any memory access or trigger any - * exceptions before the overflow/underflow condition is - * cleared (by incrementing or decrementing the JOSP) - * - Make sure that JOSP does not contain any problematic - * value before doing any exception or interrupt - * processing. - * - Set up a critical exception handler which writes a - * known-to-be-safe value, e.g. 4, to JOSP before doing - * any further processing. - * - * We'll use the last workaround for now since we cannot - * guarantee that user space processes don't use Java mode. - * Non-well-behaving userland will be terminated with extreme - * prejudice. - */ -#ifdef CONFIG_CPU_AT32AP700X - /* - * There's a chance we can't touch memory, so temporarily - * borrow PTBR to save the stack pointer while we fix things - * up... - */ - mtsr SYSREG_PTBR, sp - mov sp, 4 - mtsr SYSREG_JOSP, sp - mfsr sp, SYSREG_PTBR - sub pc, -2 - - /* Push most of pt_regs on stack. We'll do the rest later */ - sub sp, 4 - pushm r0-r12 - - /* PTBR mirrors current_thread_info()->task->active_mm->pgd */ - get_thread_info r0 - ld.w r1, r0[TI_task] - ld.w r2, r1[TSK_active_mm] - ld.w r3, r2[MM_pgd] - mtsr SYSREG_PTBR, r3 -#else - sub sp, 4 - pushm r0-r12 -#endif - sub r0, sp, -(14 * 4) - mov r1, lr - mfsr r2, SYSREG_RAR_EX - mfsr r3, SYSREG_RSR_EX - pushm r0-r3 - - mfsr r12, SYSREG_ECR - mov r11, sp - call do_critical_exception - - /* We should never get here... */ -bad_return: - sub r12, pc, (. - 1f) - lddpc pc, 2f - .align 2 -1: .asciz "Return from critical exception!" -2: .long panic - - .align 1 -do_bus_error_write: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mov r11, 1 - rjmp 1f - -do_bus_error_read: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mov r11, 0 -1: mfsr r12, SYSREG_BEAR - mov r10, sp - call do_bus_error - rjmp ret_from_exception - - .align 1 -do_nmi_ll: - sub sp, 4 - stmts --sp, r0-lr - mfsr r9, SYSREG_RSR_NMI - mfsr r8, SYSREG_RAR_NMI - bfextu r0, r9, MODE_SHIFT, 3 - brne 2f - -1: pushm r8, r9 /* PC and SR */ - mfsr r12, SYSREG_ECR - mov r11, sp - call do_nmi - popm r8-r9 - mtsr SYSREG_RAR_NMI, r8 - tst r0, r0 - mtsr SYSREG_RSR_NMI, r9 - brne 3f - - ldmts sp++, r0-lr - sub sp, -4 /* skip r12_orig */ - rete - -2: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR) - stdsp sp[4], r10 /* replace saved SP */ - rjmp 1b - -3: popm lr - sub sp, -4 /* skip sp */ - popm r0-r12 - sub sp, -4 /* skip r12_orig */ - rete - -handle_address_fault: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mfsr r12, SYSREG_ECR - mov r11, sp - call do_address_exception - rjmp ret_from_exception - -handle_protection_fault: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mfsr r12, SYSREG_ECR - mov r11, sp - call do_page_fault - rjmp ret_from_exception - - .align 1 -do_illegal_opcode_ll: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mfsr r12, SYSREG_ECR - mov r11, sp - call do_illegal_opcode - rjmp ret_from_exception - -do_dtlb_modified: - pushm r0-r3 - mfsr r1, SYSREG_TLBEAR - mfsr r0, SYSREG_PTBR - lsr r2, r1, PGDIR_SHIFT - ld.w r0, r0[r2 << 2] - lsl r1, (32 - PGDIR_SHIFT) - lsr r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT - - /* Translate to virtual address in P1 */ - andl r0, 0xf000 - sbr r0, 31 - add r2, r0, r1 << 2 - ld.w r3, r2[0] - sbr r3, _PAGE_BIT_DIRTY - mov r0, r3 - st.w r2[0], r3 - - /* The page table is up-to-date. Update the TLB entry as well */ - andl r0, lo(_PAGE_FLAGS_HARDWARE_MASK) - mtsr SYSREG_TLBELO, r0 - - /* MMUCR[DRP] is updated automatically, so let's go... */ - tlbw - - popm r0-r3 - rete - -do_fpe_ll: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - unmask_interrupts - mov r12, 26 - mov r11, sp - call do_fpe - rjmp ret_from_exception - -ret_from_exception: - mask_interrupts - lddsp r4, sp[REG_SR] - - andh r4, (MODE_MASK >> 16), COH - brne fault_resume_kernel - - get_thread_info r0 - ld.w r1, r0[TI_flags] - andl r1, _TIF_WORK_MASK, COH - brne fault_exit_work - -fault_resume_user: - popm r8-r9 - mask_exceptions - mtsr SYSREG_RAR_EX, r8 - mtsr SYSREG_RSR_EX, r9 - ldmts sp++, r0-lr - sub sp, -4 - rete - -fault_resume_kernel: -#ifdef CONFIG_PREEMPT - get_thread_info r0 - ld.w r2, r0[TI_preempt_count] - cp.w r2, 0 - brne 1f - ld.w r1, r0[TI_flags] - bld r1, TIF_NEED_RESCHED - brcc 1f - lddsp r4, sp[REG_SR] - bld r4, SYSREG_GM_OFFSET - brcs 1f - call preempt_schedule_irq -1: -#endif - - popm r8-r9 - mask_exceptions - mfsr r1, SYSREG_SR - mtsr SYSREG_RAR_EX, r8 - mtsr SYSREG_RSR_EX, r9 - popm lr - sub sp, -4 /* ignore SP */ - popm r0-r12 - sub sp, -4 /* ignore r12_orig */ - rete - -irq_exit_work: - /* Switch to exception mode so that we can share the same code. */ - mfsr r8, SYSREG_SR - cbr r8, SYSREG_M0_OFFSET - orh r8, hi(SYSREG_BIT(M1) | SYSREG_BIT(M2)) - mtsr SYSREG_SR, r8 - sub pc, -2 - get_thread_info r0 - ld.w r1, r0[TI_flags] - -fault_exit_work: - bld r1, TIF_NEED_RESCHED - brcc 1f - unmask_interrupts - call schedule - mask_interrupts - ld.w r1, r0[TI_flags] - rjmp fault_exit_work - -1: mov r2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME - tst r1, r2 - breq 2f - unmask_interrupts - mov r12, sp - mov r11, r0 - call do_notify_resume - mask_interrupts - ld.w r1, r0[TI_flags] - rjmp fault_exit_work - -2: bld r1, TIF_BREAKPOINT - brcc fault_resume_user - rjmp enter_monitor_mode - - .section .kprobes.text, "ax", @progbits - .type handle_debug, @function -handle_debug: - sub sp, 4 /* r12_orig */ - stmts --sp, r0-lr - mfsr r8, SYSREG_RAR_DBG - mfsr r9, SYSREG_RSR_DBG - unmask_exceptions - pushm r8-r9 - bfextu r9, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE - brne debug_fixup_regs - -.Ldebug_fixup_cont: -#ifdef CONFIG_TRACE_IRQFLAGS - call trace_hardirqs_off -#endif - mov r12, sp - call do_debug - mov sp, r12 - - lddsp r2, sp[REG_SR] - bfextu r3, r2, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE - brne debug_resume_kernel - - get_thread_info r0 - ld.w r1, r0[TI_flags] - mov r2, _TIF_DBGWORK_MASK - tst r1, r2 - brne debug_exit_work - - bld r1, TIF_SINGLE_STEP - brcc 1f - mfdr r4, OCD_DC - sbr r4, OCD_DC_SS_BIT - mtdr OCD_DC, r4 - -1: popm r10,r11 - mask_exceptions - mtsr SYSREG_RSR_DBG, r11 - mtsr SYSREG_RAR_DBG, r10 -#ifdef CONFIG_TRACE_IRQFLAGS - call trace_hardirqs_on -1: -#endif - ldmts sp++, r0-lr - sub sp, -4 - retd - .size handle_debug, . - handle_debug - - /* Mode of the trapped context is in r9 */ - .type debug_fixup_regs, @function -debug_fixup_regs: - mfsr r8, SYSREG_SR - mov r10, r8 - bfins r8, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE - mtsr SYSREG_SR, r8 - sub pc, -2 - stdsp sp[REG_LR], lr - mtsr SYSREG_SR, r10 - sub pc, -2 - sub r8, sp, -FRAME_SIZE_FULL - stdsp sp[REG_SP], r8 - rjmp .Ldebug_fixup_cont - .size debug_fixup_regs, . - debug_fixup_regs - - .type debug_resume_kernel, @function -debug_resume_kernel: - mask_exceptions - popm r10, r11 - mtsr SYSREG_RAR_DBG, r10 - mtsr SYSREG_RSR_DBG, r11 -#ifdef CONFIG_TRACE_IRQFLAGS - bld r11, SYSREG_GM_OFFSET - brcc 1f - call trace_hardirqs_on -1: -#endif - mfsr r2, SYSREG_SR - mov r1, r2 - bfins r2, r3, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE - mtsr SYSREG_SR, r2 - sub pc, -2 - popm lr - mtsr SYSREG_SR, r1 - sub pc, -2 - sub sp, -4 /* skip SP */ - popm r0-r12 - sub sp, -4 - retd - .size debug_resume_kernel, . - debug_resume_kernel - - .type debug_exit_work, @function -debug_exit_work: - /* - * We must return from Monitor Mode using a retd, and we must - * not schedule since that involves the D bit in SR getting - * cleared by something other than the debug hardware. This - * may cause undefined behaviour according to the Architecture - * manual. - * - * So we fix up the return address and status and return to a - * stub below in Exception mode. From there, we can follow the - * normal exception return path. - * - * The real return address and status registers are stored on - * the stack in the way the exception return path understands, - * so no need to fix anything up there. - */ - sub r8, pc, . - fault_exit_work - mtsr SYSREG_RAR_DBG, r8 - mov r9, 0 - orh r9, hi(SR_EM | SR_GM | MODE_EXCEPTION) - mtsr SYSREG_RSR_DBG, r9 - sub pc, -2 - retd - .size debug_exit_work, . - debug_exit_work - - .set rsr_int0, SYSREG_RSR_INT0 - .set rsr_int1, SYSREG_RSR_INT1 - .set rsr_int2, SYSREG_RSR_INT2 - .set rsr_int3, SYSREG_RSR_INT3 - .set rar_int0, SYSREG_RAR_INT0 - .set rar_int1, SYSREG_RAR_INT1 - .set rar_int2, SYSREG_RAR_INT2 - .set rar_int3, SYSREG_RAR_INT3 - - .macro IRQ_LEVEL level - .type irq_level\level, @function -irq_level\level: - sub sp, 4 /* r12_orig */ - stmts --sp,r0-lr - mfsr r8, rar_int\level - mfsr r9, rsr_int\level - -#ifdef CONFIG_PREEMPT - sub r11, pc, (. - system_call) - cp.w r11, r8 - breq 4f -#endif - - pushm r8-r9 - - mov r11, sp - mov r12, \level - - call do_IRQ - - lddsp r4, sp[REG_SR] - bfextu r4, r4, SYSREG_M0_OFFSET, 3 - cp.w r4, MODE_SUPERVISOR >> SYSREG_M0_OFFSET - breq 2f - cp.w r4, MODE_USER >> SYSREG_M0_OFFSET -#ifdef CONFIG_PREEMPT - brne 3f -#else - brne 1f -#endif - - get_thread_info r0 - ld.w r1, r0[TI_flags] - andl r1, _TIF_WORK_MASK, COH - brne irq_exit_work - -1: -#ifdef CONFIG_TRACE_IRQFLAGS - call trace_hardirqs_on -#endif - popm r8-r9 - mtsr rar_int\level, r8 - mtsr rsr_int\level, r9 - ldmts sp++,r0-lr - sub sp, -4 /* ignore r12_orig */ - rete - -#ifdef CONFIG_PREEMPT -4: mask_interrupts - mfsr r8, rsr_int\level - sbr r8, 16 - mtsr rsr_int\level, r8 - ldmts sp++, r0-lr - sub sp, -4 /* ignore r12_orig */ - rete -#endif - -2: get_thread_info r0 - ld.w r1, r0[TI_flags] - bld r1, TIF_CPU_GOING_TO_SLEEP -#ifdef CONFIG_PREEMPT - brcc 3f -#else - brcc 1b -#endif - sub r1, pc, . - cpu_idle_skip_sleep - stdsp sp[REG_PC], r1 -#ifdef CONFIG_PREEMPT -3: get_thread_info r0 - ld.w r2, r0[TI_preempt_count] - cp.w r2, 0 - brne 1b - ld.w r1, r0[TI_flags] - bld r1, TIF_NEED_RESCHED - brcc 1b - lddsp r4, sp[REG_SR] - bld r4, SYSREG_GM_OFFSET - brcs 1b - call preempt_schedule_irq -#endif - rjmp 1b - .endm - - .section .irq.text,"ax",@progbits - - .global irq_level0 - .global irq_level1 - .global irq_level2 - .global irq_level3 - IRQ_LEVEL 0 - IRQ_LEVEL 1 - IRQ_LEVEL 2 - IRQ_LEVEL 3 - - .section .kprobes.text, "ax", @progbits - .type enter_monitor_mode, @function -enter_monitor_mode: - /* - * We need to enter monitor mode to do a single step. The - * monitor code will alter the return address so that we - * return directly to the user instead of returning here. - */ - breakpoint - rjmp breakpoint_failed - - .size enter_monitor_mode, . - enter_monitor_mode - - .type debug_trampoline, @function - .global debug_trampoline -debug_trampoline: - /* - * Save the registers on the stack so that the monitor code - * can find them easily. - */ - sub sp, 4 /* r12_orig */ - stmts --sp, r0-lr - get_thread_info r0 - ld.w r8, r0[TI_rar_saved] - ld.w r9, r0[TI_rsr_saved] - pushm r8-r9 - - /* - * The monitor code will alter the return address so we don't - * return here. - */ - breakpoint - rjmp breakpoint_failed - .size debug_trampoline, . - debug_trampoline - - .type breakpoint_failed, @function -breakpoint_failed: - /* - * Something went wrong. Perhaps the debug hardware isn't - * enabled? - */ - lda.w r12, msg_breakpoint_failed - mov r11, sp - mov r10, 9 /* SIGKILL */ - call die -1: rjmp 1b - -msg_breakpoint_failed: - .asciz "Failed to enter Debug Mode" diff --git a/arch/avr32/kernel/head.S b/arch/avr32/kernel/head.S deleted file mode 100644 index 59eae6dfbed2..000000000000 --- a/arch/avr32/kernel/head.S +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Non-board-specific low-level startup code - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/linkage.h> - -#include <asm/page.h> - - .section .init.text,"ax" - .global kernel_entry -kernel_entry: - /* Start the show */ - lddpc pc, kernel_start_addr - - .align 2 -kernel_start_addr: - .long start_kernel diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c deleted file mode 100644 index 900e49b2258b..000000000000 --- a/arch/avr32/kernel/irq.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * Based on arch/i386/kernel/irq.c - * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/kernel_stat.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/device.h> - -/* May be overridden by platform code */ -int __weak nmi_enable(void) -{ - return -ENOSYS; -} - -void __weak nmi_disable(void) -{ - -} diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c deleted file mode 100644 index a94ece4a72c8..000000000000 --- a/arch/avr32/kernel/kprobes.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Kernel Probes (KProbes) - * - * Copyright (C) 2005-2006 Atmel Corporation - * - * Based on arch/ppc64/kernel/kprobes.c - * Copyright (C) IBM Corporation, 2002, 2004 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kprobes.h> -#include <linux/ptrace.h> - -#include <asm/cacheflush.h> -#include <linux/kdebug.h> -#include <asm/ocd.h> - -DEFINE_PER_CPU(struct kprobe *, current_kprobe); -static unsigned long kprobe_status; -static struct pt_regs jprobe_saved_regs; - -struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; - -int __kprobes arch_prepare_kprobe(struct kprobe *p) -{ - int ret = 0; - - if ((unsigned long)p->addr & 0x01) { - printk("Attempt to register kprobe at an unaligned address\n"); - ret = -EINVAL; - } - - /* XXX: Might be a good idea to check if p->addr is a valid - * kernel address as well... */ - - if (!ret) { - pr_debug("copy kprobe at %p\n", p->addr); - memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); - p->opcode = *p->addr; - } - - return ret; -} - -void __kprobes arch_arm_kprobe(struct kprobe *p) -{ - pr_debug("arming kprobe at %p\n", p->addr); - ocd_enable(NULL); - *p->addr = BREAKPOINT_INSTRUCTION; - flush_icache_range((unsigned long)p->addr, - (unsigned long)p->addr + sizeof(kprobe_opcode_t)); -} - -void __kprobes arch_disarm_kprobe(struct kprobe *p) -{ - pr_debug("disarming kprobe at %p\n", p->addr); - ocd_disable(NULL); - *p->addr = p->opcode; - flush_icache_range((unsigned long)p->addr, - (unsigned long)p->addr + sizeof(kprobe_opcode_t)); -} - -static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) -{ - unsigned long dc; - - pr_debug("preparing to singlestep over %p (PC=%08lx)\n", - p->addr, regs->pc); - - BUG_ON(!(sysreg_read(SR) & SYSREG_BIT(SR_D))); - - dc = ocd_read(DC); - dc |= 1 << OCD_DC_SS_BIT; - ocd_write(DC, dc); - - /* - * We must run the instruction from its original location - * since it may actually reference PC. - * - * TODO: Do the instruction replacement directly in icache. - */ - *p->addr = p->opcode; - flush_icache_range((unsigned long)p->addr, - (unsigned long)p->addr + sizeof(kprobe_opcode_t)); -} - -static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) -{ - unsigned long dc; - - pr_debug("resuming execution at PC=%08lx\n", regs->pc); - - dc = ocd_read(DC); - dc &= ~(1 << OCD_DC_SS_BIT); - ocd_write(DC, dc); - - *p->addr = BREAKPOINT_INSTRUCTION; - flush_icache_range((unsigned long)p->addr, - (unsigned long)p->addr + sizeof(kprobe_opcode_t)); -} - -static void __kprobes set_current_kprobe(struct kprobe *p) -{ - __this_cpu_write(current_kprobe, p); -} - -static int __kprobes kprobe_handler(struct pt_regs *regs) -{ - struct kprobe *p; - void *addr = (void *)regs->pc; - int ret = 0; - - pr_debug("kprobe_handler: kprobe_running=%p\n", - kprobe_running()); - - /* - * We don't want to be preempted for the entire - * duration of kprobe processing - */ - preempt_disable(); - - /* Check that we're not recursing */ - if (kprobe_running()) { - p = get_kprobe(addr); - if (p) { - if (kprobe_status == KPROBE_HIT_SS) { - printk("FIXME: kprobe hit while single-stepping!\n"); - goto no_kprobe; - } - - printk("FIXME: kprobe hit while handling another kprobe\n"); - goto no_kprobe; - } else { - p = kprobe_running(); - if (p->break_handler && p->break_handler(p, regs)) - goto ss_probe; - } - /* If it's not ours, can't be delete race, (we hold lock). */ - goto no_kprobe; - } - - p = get_kprobe(addr); - if (!p) - goto no_kprobe; - - kprobe_status = KPROBE_HIT_ACTIVE; - set_current_kprobe(p); - if (p->pre_handler && p->pre_handler(p, regs)) - /* handler has already set things up, so skip ss setup */ - return 1; - -ss_probe: - prepare_singlestep(p, regs); - kprobe_status = KPROBE_HIT_SS; - return 1; - -no_kprobe: - preempt_enable_no_resched(); - return ret; -} - -static int __kprobes post_kprobe_handler(struct pt_regs *regs) -{ - struct kprobe *cur = kprobe_running(); - - pr_debug("post_kprobe_handler, cur=%p\n", cur); - - if (!cur) - return 0; - - if (cur->post_handler) { - kprobe_status = KPROBE_HIT_SSDONE; - cur->post_handler(cur, regs, 0); - } - - resume_execution(cur, regs); - reset_current_kprobe(); - preempt_enable_no_resched(); - - return 1; -} - -int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) -{ - struct kprobe *cur = kprobe_running(); - - pr_debug("kprobe_fault_handler: trapnr=%d\n", trapnr); - - if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) - return 1; - - if (kprobe_status & KPROBE_HIT_SS) { - resume_execution(cur, regs); - preempt_enable_no_resched(); - } - return 0; -} - -/* - * Wrapper routine to for handling exceptions. - */ -int __kprobes kprobe_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - struct die_args *args = (struct die_args *)data; - int ret = NOTIFY_DONE; - - pr_debug("kprobe_exceptions_notify: val=%lu, data=%p\n", - val, data); - - switch (val) { - case DIE_BREAKPOINT: - if (kprobe_handler(args->regs)) - ret = NOTIFY_STOP; - break; - case DIE_SSTEP: - if (post_kprobe_handler(args->regs)) - ret = NOTIFY_STOP; - break; - default: - break; - } - - return ret; -} - -int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) -{ - struct jprobe *jp = container_of(p, struct jprobe, kp); - - memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs)); - - /* - * TODO: We should probably save some of the stack here as - * well, since gcc may pass arguments on the stack for certain - * functions (lots of arguments, large aggregates, varargs) - */ - - /* setup return addr to the jprobe handler routine */ - regs->pc = (unsigned long)jp->entry; - return 1; -} - -void __kprobes jprobe_return(void) -{ - asm volatile("breakpoint" ::: "memory"); -} - -int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) -{ - /* - * FIXME - we should ideally be validating that we got here 'cos - * of the "trap" in jprobe_return() above, before restoring the - * saved regs... - */ - memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs)); - return 1; -} - -int __init arch_init_kprobes(void) -{ - /* TODO: Register kretprobe trampoline */ - return 0; -} diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c deleted file mode 100644 index 2b4c54c04cb6..000000000000 --- a/arch/avr32/kernel/module.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * AVR32-specific kernel module loader - * - * Copyright (C) 2005-2006 Atmel Corporation - * - * GOT initialization parts are based on the s390 version - * Copyright (C) 2002, 2003 IBM Deutschland Entwicklung GmbH, - * IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/bug.h> -#include <linux/elf.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleloader.h> -#include <linux/vmalloc.h> - -void module_arch_freeing_init(struct module *mod) -{ - vfree(mod->arch.syminfo); - mod->arch.syminfo = NULL; -} - -static inline int check_rela(Elf32_Rela *rela, struct module *module, - char *strings, Elf32_Sym *symbols) -{ - struct mod_arch_syminfo *info; - - info = module->arch.syminfo + ELF32_R_SYM(rela->r_info); - switch (ELF32_R_TYPE(rela->r_info)) { - case R_AVR32_GOT32: - case R_AVR32_GOT16: - case R_AVR32_GOT8: - case R_AVR32_GOT21S: - case R_AVR32_GOT18SW: /* mcall */ - case R_AVR32_GOT16S: /* ld.w */ - if (rela->r_addend != 0) { - printk(KERN_ERR - "GOT relocation against %s at offset %u with addend\n", - strings + symbols[ELF32_R_SYM(rela->r_info)].st_name, - rela->r_offset); - return -ENOEXEC; - } - if (info->got_offset == -1UL) { - info->got_offset = module->arch.got_size; - module->arch.got_size += sizeof(void *); - } - pr_debug("GOT[%3lu] %s\n", info->got_offset, - strings + symbols[ELF32_R_SYM(rela->r_info)].st_name); - break; - } - - return 0; -} - -int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, - char *secstrings, struct module *module) -{ - Elf32_Shdr *symtab; - Elf32_Sym *symbols; - Elf32_Rela *rela; - char *strings; - int nrela, i, j; - int ret; - - /* Find the symbol table */ - symtab = NULL; - for (i = 0; i < hdr->e_shnum; i++) - switch (sechdrs[i].sh_type) { - case SHT_SYMTAB: - symtab = &sechdrs[i]; - break; - } - if (!symtab) { - printk(KERN_ERR "module %s: no symbol table\n", module->name); - return -ENOEXEC; - } - - /* Allocate room for one syminfo structure per symbol. */ - module->arch.nsyms = symtab->sh_size / sizeof(Elf_Sym); - module->arch.syminfo = vmalloc(module->arch.nsyms - * sizeof(struct mod_arch_syminfo)); - if (!module->arch.syminfo) - return -ENOMEM; - - symbols = (void *)hdr + symtab->sh_offset; - strings = (void *)hdr + sechdrs[symtab->sh_link].sh_offset; - for (i = 0; i < module->arch.nsyms; i++) { - if (symbols[i].st_shndx == SHN_UNDEF && - strcmp(strings + symbols[i].st_name, - "_GLOBAL_OFFSET_TABLE_") == 0) - /* "Define" it as absolute. */ - symbols[i].st_shndx = SHN_ABS; - module->arch.syminfo[i].got_offset = -1UL; - module->arch.syminfo[i].got_initialized = 0; - } - - /* Allocate GOT entries for symbols that need it. */ - module->arch.got_size = 0; - for (i = 0; i < hdr->e_shnum; i++) { - if (sechdrs[i].sh_type != SHT_RELA) - continue; - nrela = sechdrs[i].sh_size / sizeof(Elf32_Rela); - rela = (void *)hdr + sechdrs[i].sh_offset; - for (j = 0; j < nrela; j++) { - ret = check_rela(rela + j, module, - strings, symbols); - if (ret) - goto out_free_syminfo; - } - } - - /* - * Increase core size to make room for GOT and set start - * offset for GOT. - */ - module->core_layout.size = ALIGN(module->core_layout.size, 4); - module->arch.got_offset = module->core_layout.size; - module->core_layout.size += module->arch.got_size; - - return 0; - -out_free_syminfo: - vfree(module->arch.syminfo); - module->arch.syminfo = NULL; - - return ret; -} - -static inline int reloc_overflow(struct module *module, const char *reloc_name, - Elf32_Addr relocation) -{ - printk(KERN_ERR "module %s: Value %lx does not fit relocation %s\n", - module->name, (unsigned long)relocation, reloc_name); - return -ENOEXEC; -} - -#define get_u16(loc) (*((uint16_t *)loc)) -#define put_u16(loc, val) (*((uint16_t *)loc) = (val)) - -int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, - unsigned int symindex, unsigned int relindex, - struct module *module) -{ - Elf32_Shdr *symsec = sechdrs + symindex; - Elf32_Shdr *relsec = sechdrs + relindex; - Elf32_Shdr *dstsec = sechdrs + relsec->sh_info; - Elf32_Rela *rel = (void *)relsec->sh_addr; - unsigned int i; - int ret = 0; - - for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) { - struct mod_arch_syminfo *info; - Elf32_Sym *sym; - Elf32_Addr relocation; - uint32_t *location; - uint32_t value; - - location = (void *)dstsec->sh_addr + rel->r_offset; - sym = (Elf32_Sym *)symsec->sh_addr + ELF32_R_SYM(rel->r_info); - relocation = sym->st_value + rel->r_addend; - - info = module->arch.syminfo + ELF32_R_SYM(rel->r_info); - - /* Initialize GOT entry if necessary */ - switch (ELF32_R_TYPE(rel->r_info)) { - case R_AVR32_GOT32: - case R_AVR32_GOT16: - case R_AVR32_GOT8: - case R_AVR32_GOT21S: - case R_AVR32_GOT18SW: - case R_AVR32_GOT16S: - if (!info->got_initialized) { - Elf32_Addr *gotent; - - gotent = (module->core_layout.base - + module->arch.got_offset - + info->got_offset); - *gotent = relocation; - info->got_initialized = 1; - } - - relocation = info->got_offset; - break; - } - - switch (ELF32_R_TYPE(rel->r_info)) { - case R_AVR32_32: - case R_AVR32_32_CPENT: - *location = relocation; - break; - case R_AVR32_22H_PCREL: - relocation -= (Elf32_Addr)location; - if ((relocation & 0xffe00001) != 0 - && (relocation & 0xffc00001) != 0xffc00000) - return reloc_overflow(module, - "R_AVR32_22H_PCREL", - relocation); - relocation >>= 1; - - value = *location; - value = ((value & 0xe1ef0000) - | (relocation & 0xffff) - | ((relocation & 0x10000) << 4) - | ((relocation & 0x1e0000) << 8)); - *location = value; - break; - case R_AVR32_11H_PCREL: - relocation -= (Elf32_Addr)location; - if ((relocation & 0xfffffc01) != 0 - && (relocation & 0xfffff801) != 0xfffff800) - return reloc_overflow(module, - "R_AVR32_11H_PCREL", - relocation); - value = get_u16(location); - value = ((value & 0xf00c) - | ((relocation & 0x1fe) << 3) - | ((relocation & 0x600) >> 9)); - put_u16(location, value); - break; - case R_AVR32_9H_PCREL: - relocation -= (Elf32_Addr)location; - if ((relocation & 0xffffff01) != 0 - && (relocation & 0xfffffe01) != 0xfffffe00) - return reloc_overflow(module, - "R_AVR32_9H_PCREL", - relocation); - value = get_u16(location); - value = ((value & 0xf00f) - | ((relocation & 0x1fe) << 3)); - put_u16(location, value); - break; - case R_AVR32_9UW_PCREL: - relocation -= ((Elf32_Addr)location) & 0xfffffffc; - if ((relocation & 0xfffffc03) != 0) - return reloc_overflow(module, - "R_AVR32_9UW_PCREL", - relocation); - value = get_u16(location); - value = ((value & 0xf80f) - | ((relocation & 0x1fc) << 2)); - put_u16(location, value); - break; - case R_AVR32_GOTPC: - /* - * R6 = PC - (PC - GOT) - * - * At this point, relocation contains the - * value of PC. Just subtract the value of - * GOT, and we're done. - */ - pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n", - relocation, module->arch.got_offset, - module->core_layout.base); - relocation -= ((unsigned long)module->core_layout.base - + module->arch.got_offset); - *location = relocation; - break; - case R_AVR32_GOT18SW: - if ((relocation & 0xfffe0003) != 0 - && (relocation & 0xfffc0000) != 0xfffc0000) - return reloc_overflow(module, "R_AVR32_GOT18SW", - relocation); - relocation >>= 2; - /* fall through */ - case R_AVR32_GOT16S: - if ((relocation & 0xffff8000) != 0 - && (relocation & 0xffff0000) != 0xffff0000) - return reloc_overflow(module, "R_AVR32_GOT16S", - relocation); - pr_debug("GOT reloc @ 0x%x -> %u\n", - rel->r_offset, relocation); - value = *location; - value = ((value & 0xffff0000) - | (relocation & 0xffff)); - *location = value; - break; - - default: - printk(KERN_ERR "module %s: Unknown relocation: %u\n", - module->name, ELF32_R_TYPE(rel->r_info)); - return -ENOEXEC; - } - } - - return ret; -} diff --git a/arch/avr32/kernel/nmi_debug.c b/arch/avr32/kernel/nmi_debug.c deleted file mode 100644 index 25823049bb99..000000000000 --- a/arch/avr32/kernel/nmi_debug.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/delay.h> -#include <linux/kdebug.h> -#include <linux/notifier.h> -#include <linux/sched.h> -#include <linux/sched/debug.h> - -#include <asm/irq.h> - -enum nmi_action { - NMI_SHOW_STATE = 1 << 0, - NMI_SHOW_REGS = 1 << 1, - NMI_DIE = 1 << 2, - NMI_DEBOUNCE = 1 << 3, -}; - -static unsigned long nmi_actions; - -static int nmi_debug_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - struct die_args *args = data; - - if (likely(val != DIE_NMI)) - return NOTIFY_DONE; - - if (nmi_actions & NMI_SHOW_STATE) - show_state(); - if (nmi_actions & NMI_SHOW_REGS) - show_regs(args->regs); - if (nmi_actions & NMI_DEBOUNCE) - mdelay(10); - if (nmi_actions & NMI_DIE) - return NOTIFY_BAD; - - return NOTIFY_OK; -} - -static struct notifier_block nmi_debug_nb = { - .notifier_call = nmi_debug_notify, -}; - -static int __init nmi_debug_setup(char *str) -{ - char *p, *sep; - - register_die_notifier(&nmi_debug_nb); - if (nmi_enable()) { - printk(KERN_WARNING "Unable to enable NMI.\n"); - return 0; - } - - if (*str != '=') - return 0; - - for (p = str + 1; *p; p = sep + 1) { - sep = strchr(p, ','); - if (sep) - *sep = 0; - if (strcmp(p, "state") == 0) - nmi_actions |= NMI_SHOW_STATE; - else if (strcmp(p, "regs") == 0) - nmi_actions |= NMI_SHOW_REGS; - else if (strcmp(p, "debounce") == 0) - nmi_actions |= NMI_DEBOUNCE; - else if (strcmp(p, "die") == 0) - nmi_actions |= NMI_DIE; - else - printk(KERN_WARNING "NMI: Unrecognized action `%s'\n", - p); - if (!sep) - break; - } - - return 0; -} -__setup("nmi_debug", nmi_debug_setup); diff --git a/arch/avr32/kernel/ocd.c b/arch/avr32/kernel/ocd.c deleted file mode 100644 index 1b0245d4e0ca..000000000000 --- a/arch/avr32/kernel/ocd.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/spinlock.h> - -#include <asm/ocd.h> - -static long ocd_count; -static spinlock_t ocd_lock; - -/** - * ocd_enable - enable on-chip debugging - * @child: task to be debugged - * - * If @child is non-NULL, ocd_enable() first checks if debugging has - * already been enabled for @child, and if it has, does nothing. - * - * If @child is NULL (e.g. when debugging the kernel), or debugging - * has not already been enabled for it, ocd_enable() increments the - * reference count and enables the debugging hardware. - */ -void ocd_enable(struct task_struct *child) -{ - u32 dc; - - if (child) - pr_debug("ocd_enable: child=%s [%u]\n", - child->comm, child->pid); - else - pr_debug("ocd_enable (no child)\n"); - - if (!child || !test_and_set_tsk_thread_flag(child, TIF_DEBUG)) { - spin_lock(&ocd_lock); - ocd_count++; - dc = ocd_read(DC); - dc |= (1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT); - ocd_write(DC, dc); - spin_unlock(&ocd_lock); - } -} - -/** - * ocd_disable - disable on-chip debugging - * @child: task that was being debugged, but isn't anymore - * - * If @child is non-NULL, ocd_disable() checks if debugging is enabled - * for @child, and if it isn't, does nothing. - * - * If @child is NULL (e.g. when debugging the kernel), or debugging is - * enabled, ocd_disable() decrements the reference count, and if it - * reaches zero, disables the debugging hardware. - */ -void ocd_disable(struct task_struct *child) -{ - u32 dc; - - if (!child) - pr_debug("ocd_disable (no child)\n"); - else if (test_tsk_thread_flag(child, TIF_DEBUG)) - pr_debug("ocd_disable: child=%s [%u]\n", - child->comm, child->pid); - - if (!child || test_and_clear_tsk_thread_flag(child, TIF_DEBUG)) { - spin_lock(&ocd_lock); - ocd_count--; - - WARN_ON(ocd_count < 0); - - if (ocd_count <= 0) { - dc = ocd_read(DC); - dc &= ~((1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT)); - ocd_write(DC, dc); - } - spin_unlock(&ocd_lock); - } -} - -#ifdef CONFIG_DEBUG_FS -#include <linux/debugfs.h> -#include <linux/module.h> - -static struct dentry *ocd_debugfs_root; -static struct dentry *ocd_debugfs_DC; -static struct dentry *ocd_debugfs_DS; -static struct dentry *ocd_debugfs_count; - -static int ocd_DC_get(void *data, u64 *val) -{ - *val = ocd_read(DC); - return 0; -} -static int ocd_DC_set(void *data, u64 val) -{ - ocd_write(DC, val); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(fops_DC, ocd_DC_get, ocd_DC_set, "0x%08llx\n"); - -static int ocd_DS_get(void *data, u64 *val) -{ - *val = ocd_read(DS); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(fops_DS, ocd_DS_get, NULL, "0x%08llx\n"); - -static int ocd_count_get(void *data, u64 *val) -{ - *val = ocd_count; - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(fops_count, ocd_count_get, NULL, "%lld\n"); - -static void ocd_debugfs_init(void) -{ - struct dentry *root; - - root = debugfs_create_dir("ocd", NULL); - if (IS_ERR(root) || !root) - goto err_root; - ocd_debugfs_root = root; - - ocd_debugfs_DC = debugfs_create_file("DC", S_IRUSR | S_IWUSR, - root, NULL, &fops_DC); - if (!ocd_debugfs_DC) - goto err_DC; - - ocd_debugfs_DS = debugfs_create_file("DS", S_IRUSR, root, - NULL, &fops_DS); - if (!ocd_debugfs_DS) - goto err_DS; - - ocd_debugfs_count = debugfs_create_file("count", S_IRUSR, root, - NULL, &fops_count); - if (!ocd_debugfs_count) - goto err_count; - - return; - -err_count: - debugfs_remove(ocd_debugfs_DS); -err_DS: - debugfs_remove(ocd_debugfs_DC); -err_DC: - debugfs_remove(ocd_debugfs_root); -err_root: - printk(KERN_WARNING "OCD: Failed to create debugfs entries\n"); -} -#else -static inline void ocd_debugfs_init(void) -{ - -} -#endif - -static int __init ocd_init(void) -{ - spin_lock_init(&ocd_lock); - ocd_debugfs_init(); - return 0; -} -arch_initcall(ocd_init); diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c deleted file mode 100644 index ad0dfccedb79..000000000000 --- a/arch/avr32/kernel/process.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/sched.h> -#include <linux/sched/debug.h> -#include <linux/sched/task.h> -#include <linux/sched/task_stack.h> -#include <linux/module.h> -#include <linux/kallsyms.h> -#include <linux/fs.h> -#include <linux/pm.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/reboot.h> -#include <linux/tick.h> -#include <linux/uaccess.h> -#include <linux/unistd.h> - -#include <asm/sysreg.h> -#include <asm/ocd.h> -#include <asm/syscalls.h> - -#include <mach/pm.h> - -void (*pm_power_off)(void); -EXPORT_SYMBOL(pm_power_off); - -/* - * This file handles the architecture-dependent parts of process handling.. - */ - -void arch_cpu_idle(void) -{ - cpu_enter_idle(); -} - -void machine_halt(void) -{ - /* - * Enter Stop mode. The 32 kHz oscillator will keep running so - * the RTC will keep the time properly and the system will - * boot quickly. - */ - asm volatile("sleep 3\n\t" - "sub pc, -2"); -} - -void machine_power_off(void) -{ - if (pm_power_off) - pm_power_off(); -} - -void machine_restart(char *cmd) -{ - ocd_write(DC, (1 << OCD_DC_DBE_BIT)); - ocd_write(DC, (1 << OCD_DC_RES_BIT)); - while (1) ; -} - -/* - * Free current thread data structures etc - */ -void exit_thread(struct task_struct *tsk) -{ - ocd_disable(tsk); -} - -void flush_thread(void) -{ - /* nothing to do */ -} - -void release_thread(struct task_struct *dead_task) -{ - /* do nothing */ -} - -static void dump_mem(const char *str, const char *log_lvl, - unsigned long bottom, unsigned long top) -{ - unsigned long p; - int i; - - printk("%s%s(0x%08lx to 0x%08lx)\n", log_lvl, str, bottom, top); - - for (p = bottom & ~31; p < top; ) { - printk("%s%04lx: ", log_lvl, p & 0xffff); - - for (i = 0; i < 8; i++, p += 4) { - unsigned int val; - - if (p < bottom || p >= top) - printk(" "); - else { - if (__get_user(val, (unsigned int __user *)p)) { - printk("\n"); - goto out; - } - printk("%08x ", val); - } - } - printk("\n"); - } - -out: - return; -} - -static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p) -{ - return (p > (unsigned long)tinfo) - && (p < (unsigned long)tinfo + THREAD_SIZE - 3); -} - -#ifdef CONFIG_FRAME_POINTER -static void show_trace_log_lvl(struct task_struct *tsk, unsigned long *sp, - struct pt_regs *regs, const char *log_lvl) -{ - unsigned long lr, fp; - struct thread_info *tinfo; - - if (regs) - fp = regs->r7; - else if (tsk == current) - asm("mov %0, r7" : "=r"(fp)); - else - fp = tsk->thread.cpu_context.r7; - - /* - * Walk the stack as long as the frame pointer (a) is within - * the kernel stack of the task, and (b) it doesn't move - * downwards. - */ - tinfo = task_thread_info(tsk); - printk("%sCall trace:\n", log_lvl); - while (valid_stack_ptr(tinfo, fp)) { - unsigned long new_fp; - - lr = *(unsigned long *)fp; -#ifdef CONFIG_KALLSYMS - printk("%s [<%08lx>] ", log_lvl, lr); -#else - printk(" [<%08lx>] ", lr); -#endif - print_symbol("%s\n", lr); - - new_fp = *(unsigned long *)(fp + 4); - if (new_fp <= fp) - break; - fp = new_fp; - } - printk("\n"); -} -#else -static void show_trace_log_lvl(struct task_struct *tsk, unsigned long *sp, - struct pt_regs *regs, const char *log_lvl) -{ - unsigned long addr; - - printk("%sCall trace:\n", log_lvl); - - while (!kstack_end(sp)) { - addr = *sp++; - if (kernel_text_address(addr)) { -#ifdef CONFIG_KALLSYMS - printk("%s [<%08lx>] ", log_lvl, addr); -#else - printk(" [<%08lx>] ", addr); -#endif - print_symbol("%s\n", addr); - } - } - printk("\n"); -} -#endif - -void show_stack_log_lvl(struct task_struct *tsk, unsigned long sp, - struct pt_regs *regs, const char *log_lvl) -{ - struct thread_info *tinfo; - - if (sp == 0) { - if (tsk) - sp = tsk->thread.cpu_context.ksp; - else - sp = (unsigned long)&tinfo; - } - if (!tsk) - tsk = current; - - tinfo = task_thread_info(tsk); - - if (valid_stack_ptr(tinfo, sp)) { - dump_mem("Stack: ", log_lvl, sp, - THREAD_SIZE + (unsigned long)tinfo); - show_trace_log_lvl(tsk, (unsigned long *)sp, regs, log_lvl); - } -} - -void show_stack(struct task_struct *tsk, unsigned long *stack) -{ - show_stack_log_lvl(tsk, (unsigned long)stack, NULL, ""); -} - -static const char *cpu_modes[] = { - "Application", "Supervisor", "Interrupt level 0", "Interrupt level 1", - "Interrupt level 2", "Interrupt level 3", "Exception", "NMI" -}; - -void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl) -{ - unsigned long sp = regs->sp; - unsigned long lr = regs->lr; - unsigned long mode = (regs->sr & MODE_MASK) >> MODE_SHIFT; - - show_regs_print_info(log_lvl); - - if (!user_mode(regs)) { - sp = (unsigned long)regs + FRAME_SIZE_FULL; - - printk("%s", log_lvl); - print_symbol("PC is at %s\n", instruction_pointer(regs)); - printk("%s", log_lvl); - print_symbol("LR is at %s\n", lr); - } - - printk("%spc : [<%08lx>] lr : [<%08lx>] %s\n" - "%ssp : %08lx r12: %08lx r11: %08lx\n", - log_lvl, instruction_pointer(regs), lr, print_tainted(), - log_lvl, sp, regs->r12, regs->r11); - printk("%sr10: %08lx r9 : %08lx r8 : %08lx\n", - log_lvl, regs->r10, regs->r9, regs->r8); - printk("%sr7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", - log_lvl, regs->r7, regs->r6, regs->r5, regs->r4); - printk("%sr3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", - log_lvl, regs->r3, regs->r2, regs->r1, regs->r0); - printk("%sFlags: %c%c%c%c%c\n", log_lvl, - regs->sr & SR_Q ? 'Q' : 'q', - regs->sr & SR_V ? 'V' : 'v', - regs->sr & SR_N ? 'N' : 'n', - regs->sr & SR_Z ? 'Z' : 'z', - regs->sr & SR_C ? 'C' : 'c'); - printk("%sMode bits: %c%c%c%c%c%c%c%c%c%c\n", log_lvl, - regs->sr & SR_H ? 'H' : 'h', - regs->sr & SR_J ? 'J' : 'j', - regs->sr & SR_DM ? 'M' : 'm', - regs->sr & SR_D ? 'D' : 'd', - regs->sr & SR_EM ? 'E' : 'e', - regs->sr & SR_I3M ? '3' : '.', - regs->sr & SR_I2M ? '2' : '.', - regs->sr & SR_I1M ? '1' : '.', - regs->sr & SR_I0M ? '0' : '.', - regs->sr & SR_GM ? 'G' : 'g'); - printk("%sCPU Mode: %s\n", log_lvl, cpu_modes[mode]); -} - -void show_regs(struct pt_regs *regs) -{ - unsigned long sp = regs->sp; - - if (!user_mode(regs)) - sp = (unsigned long)regs + FRAME_SIZE_FULL; - - show_regs_log_lvl(regs, ""); - show_trace_log_lvl(current, (unsigned long *)sp, regs, ""); -} -EXPORT_SYMBOL(show_regs); - -/* Fill in the fpu structure for a core dump. This is easy -- we don't have any */ -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) -{ - /* Not valid */ - return 0; -} - -asmlinkage void ret_from_fork(void); -asmlinkage void ret_from_kernel_thread(void); -asmlinkage void syscall_return(void); - -int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long arg, - struct task_struct *p) -{ - struct pt_regs *childregs = task_pt_regs(p); - - if (unlikely(p->flags & PF_KTHREAD)) { - memset(childregs, 0, sizeof(struct pt_regs)); - p->thread.cpu_context.r0 = arg; - p->thread.cpu_context.r1 = usp; /* fn */ - p->thread.cpu_context.r2 = (unsigned long)syscall_return; - p->thread.cpu_context.pc = (unsigned long)ret_from_kernel_thread; - childregs->sr = MODE_SUPERVISOR; - } else { - *childregs = *current_pt_regs(); - if (usp) - childregs->sp = usp; - childregs->r12 = 0; /* Set return value for child */ - p->thread.cpu_context.pc = (unsigned long)ret_from_fork; - } - - p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM; - p->thread.cpu_context.ksp = (unsigned long)childregs; - - clear_tsk_thread_flag(p, TIF_DEBUG); - if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG)) - ocd_enable(p); - - return 0; -} - -/* - * This function is supposed to answer the question "who called - * schedule()?" - */ -unsigned long get_wchan(struct task_struct *p) -{ - unsigned long pc; - unsigned long stack_page; - - if (!p || p == current || p->state == TASK_RUNNING) - return 0; - - stack_page = (unsigned long)task_stack_page(p); - BUG_ON(!stack_page); - - /* - * The stored value of PC is either the address right after - * the call to __switch_to() or ret_from_fork. - */ - pc = thread_saved_pc(p); - if (in_sched_functions(pc)) { -#ifdef CONFIG_FRAME_POINTER - unsigned long fp = p->thread.cpu_context.r7; - BUG_ON(fp < stack_page || fp > (THREAD_SIZE + stack_page)); - pc = *(unsigned long *)fp; -#else - /* - * We depend on the frame size of schedule here, which - * is actually quite ugly. It might be possible to - * determine the frame size automatically at build - * time by doing this: - * - compile sched/core.c - * - disassemble the resulting sched.o - * - look for 'sub sp,??' shortly after '<schedule>:' - */ - unsigned long sp = p->thread.cpu_context.ksp + 16; - BUG_ON(sp < stack_page || sp > (THREAD_SIZE + stack_page)); - pc = *(unsigned long *)sp; -#endif - } - - return pc; -} diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c deleted file mode 100644 index 41a14e96a1db..000000000000 --- a/arch/avr32/kernel/ptrace.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#undef DEBUG -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/sched/task_stack.h> -#include <linux/mm.h> -#include <linux/ptrace.h> -#include <linux/errno.h> -#include <linux/user.h> -#include <linux/security.h> -#include <linux/unistd.h> -#include <linux/notifier.h> - -#include <asm/traps.h> -#include <linux/uaccess.h> -#include <asm/ocd.h> -#include <asm/mmu_context.h> -#include <linux/kdebug.h> - -static struct pt_regs *get_user_regs(struct task_struct *tsk) -{ - return (struct pt_regs *)((unsigned long)task_stack_page(tsk) + - THREAD_SIZE - sizeof(struct pt_regs)); -} - -void user_enable_single_step(struct task_struct *tsk) -{ - pr_debug("user_enable_single_step: pid=%u, PC=0x%08lx, SR=0x%08lx\n", - tsk->pid, task_pt_regs(tsk)->pc, task_pt_regs(tsk)->sr); - - /* - * We can't schedule in Debug mode, so when TIF_BREAKPOINT is - * set, the system call or exception handler will do a - * breakpoint to enter monitor mode before returning to - * userspace. - * - * The monitor code will then notice that TIF_SINGLE_STEP is - * set and return to userspace with single stepping enabled. - * The CPU will then enter monitor mode again after exactly - * one instruction has been executed, and the monitor code - * will then send a SIGTRAP to the process. - */ - set_tsk_thread_flag(tsk, TIF_BREAKPOINT); - set_tsk_thread_flag(tsk, TIF_SINGLE_STEP); -} - -void user_disable_single_step(struct task_struct *child) -{ - /* XXX(hch): a no-op here seems wrong.. */ -} - -/* - * Called by kernel/ptrace.c when detaching - * - * Make sure any single step bits, etc. are not set - */ -void ptrace_disable(struct task_struct *child) -{ - clear_tsk_thread_flag(child, TIF_SINGLE_STEP); - clear_tsk_thread_flag(child, TIF_BREAKPOINT); - ocd_disable(child); -} - -/* - * Read the word at offset "offset" into the task's "struct user". We - * actually access the pt_regs struct stored on the kernel stack. - */ -static int ptrace_read_user(struct task_struct *tsk, unsigned long offset, - unsigned long __user *data) -{ - unsigned long *regs; - unsigned long value; - - if (offset & 3 || offset >= sizeof(struct user)) { - printk("ptrace_read_user: invalid offset 0x%08lx\n", offset); - return -EIO; - } - - regs = (unsigned long *)get_user_regs(tsk); - - value = 0; - if (offset < sizeof(struct pt_regs)) - value = regs[offset / sizeof(regs[0])]; - - pr_debug("ptrace_read_user(%s[%u], %#lx, %p) -> %#lx\n", - tsk->comm, tsk->pid, offset, data, value); - - return put_user(value, data); -} - -/* - * Write the word "value" to offset "offset" into the task's "struct - * user". We actually access the pt_regs struct stored on the kernel - * stack. - */ -static int ptrace_write_user(struct task_struct *tsk, unsigned long offset, - unsigned long value) -{ - unsigned long *regs; - - pr_debug("ptrace_write_user(%s[%u], %#lx, %#lx)\n", - tsk->comm, tsk->pid, offset, value); - - if (offset & 3 || offset >= sizeof(struct user)) { - pr_debug(" invalid offset 0x%08lx\n", offset); - return -EIO; - } - - if (offset >= sizeof(struct pt_regs)) - return 0; - - regs = (unsigned long *)get_user_regs(tsk); - regs[offset / sizeof(regs[0])] = value; - - return 0; -} - -static int ptrace_getregs(struct task_struct *tsk, void __user *uregs) -{ - struct pt_regs *regs = get_user_regs(tsk); - - return copy_to_user(uregs, regs, sizeof(*regs)) ? -EFAULT : 0; -} - -static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs) -{ - struct pt_regs newregs; - int ret; - - ret = -EFAULT; - if (copy_from_user(&newregs, uregs, sizeof(newregs)) == 0) { - struct pt_regs *regs = get_user_regs(tsk); - - ret = -EINVAL; - if (valid_user_regs(&newregs)) { - *regs = newregs; - ret = 0; - } - } - - return ret; -} - -long arch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret; - void __user *datap = (void __user *) data; - - switch (request) { - /* Read the word at location addr in the child process */ - case PTRACE_PEEKTEXT: - case PTRACE_PEEKDATA: - ret = generic_ptrace_peekdata(child, addr, data); - break; - - case PTRACE_PEEKUSR: - ret = ptrace_read_user(child, addr, datap); - break; - - /* Write the word in data at location addr */ - case PTRACE_POKETEXT: - case PTRACE_POKEDATA: - ret = generic_ptrace_pokedata(child, addr, data); - break; - - case PTRACE_POKEUSR: - ret = ptrace_write_user(child, addr, data); - break; - - case PTRACE_GETREGS: - ret = ptrace_getregs(child, datap); - break; - - case PTRACE_SETREGS: - ret = ptrace_setregs(child, datap); - break; - - default: - ret = ptrace_request(child, request, addr, data); - break; - } - - return ret; -} - -asmlinkage void syscall_trace(void) -{ - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - if (!(current->ptrace & PT_PTRACED)) - return; - - /* The 0x80 provides a way for the tracing parent to - * distinguish between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it - * will do for normal use. strace only continues with a - * signal if the stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - pr_debug("syscall_trace: sending signal %d to PID %u\n", - current->exit_code, current->pid); - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} - -/* - * debug_trampoline() is an assembly stub which will store all user - * registers on the stack and execute a breakpoint instruction. - * - * If we single-step into an exception handler which runs with - * interrupts disabled the whole time so it doesn't have to check for - * pending work, its return address will be modified so that it ends - * up returning to debug_trampoline. - * - * If the exception handler decides to store the user context and - * enable interrupts after all, it will restore the original return - * address and status register value. Before it returns, it will - * notice that TIF_BREAKPOINT is set and execute a breakpoint - * instruction. - */ -extern void debug_trampoline(void); - -asmlinkage struct pt_regs *do_debug(struct pt_regs *regs) -{ - struct thread_info *ti; - unsigned long trampoline_addr; - u32 status; - u32 ctrl; - int code; - - status = ocd_read(DS); - ti = current_thread_info(); - code = TRAP_BRKPT; - - pr_debug("do_debug: status=0x%08x PC=0x%08lx SR=0x%08lx tif=0x%08lx\n", - status, regs->pc, regs->sr, ti->flags); - - if (!user_mode(regs)) { - unsigned long die_val = DIE_BREAKPOINT; - - if (status & (1 << OCD_DS_SSS_BIT)) - die_val = DIE_SSTEP; - - if (notify_die(die_val, "ptrace", regs, 0, 0, SIGTRAP) - == NOTIFY_STOP) - return regs; - - if ((status & (1 << OCD_DS_SWB_BIT)) - && test_and_clear_ti_thread_flag( - ti, TIF_BREAKPOINT)) { - /* - * Explicit breakpoint from trampoline or - * exception/syscall/interrupt handler. - * - * The real saved regs are on the stack right - * after the ones we saved on entry. - */ - regs++; - pr_debug(" -> TIF_BREAKPOINT done, adjusted regs:" - "PC=0x%08lx SR=0x%08lx\n", - regs->pc, regs->sr); - BUG_ON(!user_mode(regs)); - - if (test_thread_flag(TIF_SINGLE_STEP)) { - pr_debug("Going to do single step...\n"); - return regs; - } - - /* - * No TIF_SINGLE_STEP means we're done - * stepping over a syscall. Do the trap now. - */ - code = TRAP_TRACE; - } else if ((status & (1 << OCD_DS_SSS_BIT)) - && test_ti_thread_flag(ti, TIF_SINGLE_STEP)) { - - pr_debug("Stepped into something, " - "setting TIF_BREAKPOINT...\n"); - set_ti_thread_flag(ti, TIF_BREAKPOINT); - - /* - * We stepped into an exception, interrupt or - * syscall handler. Some exception handlers - * don't check for pending work, so we need to - * set up a trampoline just in case. - * - * The exception entry code will undo the - * trampoline stuff if it does a full context - * save (which also means that it'll check for - * pending work later.) - */ - if ((regs->sr & MODE_MASK) == MODE_EXCEPTION) { - trampoline_addr - = (unsigned long)&debug_trampoline; - - pr_debug("Setting up trampoline...\n"); - ti->rar_saved = sysreg_read(RAR_EX); - ti->rsr_saved = sysreg_read(RSR_EX); - sysreg_write(RAR_EX, trampoline_addr); - sysreg_write(RSR_EX, (MODE_EXCEPTION - | SR_EM | SR_GM)); - BUG_ON(ti->rsr_saved & MODE_MASK); - } - - /* - * If we stepped into a system call, we - * shouldn't do a single step after we return - * since the return address is right after the - * "scall" instruction we were told to step - * over. - */ - if ((regs->sr & MODE_MASK) == MODE_SUPERVISOR) { - pr_debug("Supervisor; no single step\n"); - clear_ti_thread_flag(ti, TIF_SINGLE_STEP); - } - - ctrl = ocd_read(DC); - ctrl &= ~(1 << OCD_DC_SS_BIT); - ocd_write(DC, ctrl); - - return regs; - } else { - printk(KERN_ERR "Unexpected OCD_DS value: 0x%08x\n", - status); - printk(KERN_ERR "Thread flags: 0x%08lx\n", ti->flags); - die("Unhandled debug trap in kernel mode", - regs, SIGTRAP); - } - } else if (status & (1 << OCD_DS_SSS_BIT)) { - /* Single step in user mode */ - code = TRAP_TRACE; - - ctrl = ocd_read(DC); - ctrl &= ~(1 << OCD_DC_SS_BIT); - ocd_write(DC, ctrl); - } - - pr_debug("Sending SIGTRAP: code=%d PC=0x%08lx SR=0x%08lx\n", - code, regs->pc, regs->sr); - - clear_thread_flag(TIF_SINGLE_STEP); - _exception(SIGTRAP, regs, code, instruction_pointer(regs)); - - return regs; -} diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c deleted file mode 100644 index e6928896da2a..000000000000 --- a/arch/avr32/kernel/setup.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/clk.h> -#include <linux/init.h> -#include <linux/initrd.h> -#include <linux/sched.h> -#include <linux/console.h> -#include <linux/ioport.h> -#include <linux/bootmem.h> -#include <linux/fs.h> -#include <linux/module.h> -#include <linux/pfn.h> -#include <linux/root_dev.h> -#include <linux/cpu.h> -#include <linux/kernel.h> - -#include <asm/sections.h> -#include <asm/processor.h> -#include <asm/pgtable.h> -#include <asm/setup.h> -#include <asm/sysreg.h> - -#include <mach/board.h> -#include <mach/init.h> - -extern int root_mountflags; - -/* - * Initialize loops_per_jiffy as 5000000 (500MIPS). - * Better make it too large than too small... - */ -struct avr32_cpuinfo boot_cpu_data = { - .loops_per_jiffy = 5000000 -}; -EXPORT_SYMBOL(boot_cpu_data); - -static char __initdata command_line[COMMAND_LINE_SIZE]; - -/* - * Standard memory resources - */ -static struct resource __initdata kernel_data = { - .name = "Kernel data", - .start = 0, - .end = 0, - .flags = IORESOURCE_SYSTEM_RAM, -}; -static struct resource __initdata kernel_code = { - .name = "Kernel code", - .start = 0, - .end = 0, - .flags = IORESOURCE_SYSTEM_RAM, - .sibling = &kernel_data, -}; - -/* - * Available system RAM and reserved regions as singly linked - * lists. These lists are traversed using the sibling pointer in - * struct resource and are kept sorted at all times. - */ -static struct resource *__initdata system_ram; -static struct resource *__initdata reserved = &kernel_code; - -/* - * We need to allocate these before the bootmem allocator is up and - * running, so we need this "cache". 32 entries are probably enough - * for all but the most insanely complex systems. - */ -static struct resource __initdata res_cache[32]; -static unsigned int __initdata res_cache_next_free; - -static void __init resource_init(void) -{ - struct resource *mem, *res; - struct resource *new; - - kernel_code.start = __pa(init_mm.start_code); - - for (mem = system_ram; mem; mem = mem->sibling) { - new = alloc_bootmem_low(sizeof(struct resource)); - memcpy(new, mem, sizeof(struct resource)); - - new->sibling = NULL; - if (request_resource(&iomem_resource, new)) - printk(KERN_WARNING "Bad RAM resource %08x-%08x\n", - mem->start, mem->end); - } - - for (res = reserved; res; res = res->sibling) { - new = alloc_bootmem_low(sizeof(struct resource)); - memcpy(new, res, sizeof(struct resource)); - - new->sibling = NULL; - if (insert_resource(&iomem_resource, new)) - printk(KERN_WARNING - "Bad reserved resource %s (%08x-%08x)\n", - res->name, res->start, res->end); - } -} - -static void __init -add_physical_memory(resource_size_t start, resource_size_t end) -{ - struct resource *new, *next, **pprev; - - for (pprev = &system_ram, next = system_ram; next; - pprev = &next->sibling, next = next->sibling) { - if (end < next->start) - break; - if (start <= next->end) { - printk(KERN_WARNING - "Warning: Physical memory map is broken\n"); - printk(KERN_WARNING - "Warning: %08x-%08x overlaps %08x-%08x\n", - start, end, next->start, next->end); - return; - } - } - - if (res_cache_next_free >= ARRAY_SIZE(res_cache)) { - printk(KERN_WARNING - "Warning: Failed to add physical memory %08x-%08x\n", - start, end); - return; - } - - new = &res_cache[res_cache_next_free++]; - new->start = start; - new->end = end; - new->name = "System RAM"; - new->flags = IORESOURCE_SYSTEM_RAM; - - *pprev = new; -} - -static int __init -add_reserved_region(resource_size_t start, resource_size_t end, - const char *name) -{ - struct resource *new, *next, **pprev; - - if (end < start) - return -EINVAL; - - if (res_cache_next_free >= ARRAY_SIZE(res_cache)) - return -ENOMEM; - - for (pprev = &reserved, next = reserved; next; - pprev = &next->sibling, next = next->sibling) { - if (end < next->start) - break; - if (start <= next->end) - return -EBUSY; - } - - new = &res_cache[res_cache_next_free++]; - new->start = start; - new->end = end; - new->name = name; - new->sibling = next; - new->flags = IORESOURCE_MEM; - - *pprev = new; - - return 0; -} - -static unsigned long __init -find_free_region(const struct resource *mem, resource_size_t size, - resource_size_t align) -{ - struct resource *res; - unsigned long target; - - target = ALIGN(mem->start, align); - for (res = reserved; res; res = res->sibling) { - if ((target + size) <= res->start) - break; - if (target <= res->end) - target = ALIGN(res->end + 1, align); - } - - if ((target + size) > (mem->end + 1)) - return mem->end + 1; - - return target; -} - -static int __init -alloc_reserved_region(resource_size_t *start, resource_size_t size, - resource_size_t align, const char *name) -{ - struct resource *mem; - resource_size_t target; - int ret; - - for (mem = system_ram; mem; mem = mem->sibling) { - target = find_free_region(mem, size, align); - if (target <= mem->end) { - ret = add_reserved_region(target, target + size - 1, - name); - if (!ret) - *start = target; - return ret; - } - } - - return -ENOMEM; -} - -/* - * Early framebuffer allocation. Works as follows: - * - If fbmem_size is zero, nothing will be allocated or reserved. - * - If fbmem_start is zero when setup_bootmem() is called, - * a block of fbmem_size bytes will be reserved before bootmem - * initialization. It will be aligned to the largest page size - * that fbmem_size is a multiple of. - * - If fbmem_start is nonzero, an area of size fbmem_size will be - * reserved at the physical address fbmem_start if possible. If - * it collides with other reserved memory, a different block of - * same size will be allocated, just as if fbmem_start was zero. - * - * Board-specific code may use these variables to set up platform data - * for the framebuffer driver if fbmem_size is nonzero. - */ -resource_size_t __initdata fbmem_start; -resource_size_t __initdata fbmem_size; - -/* - * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for - * use as framebuffer. - * - * "fbmem=xxx[kKmM]@yyy[kKmM]" defines a memory region of size xxx and - * starting at yyy to be reserved for use as framebuffer. - * - * The kernel won't verify that the memory region starting at yyy - * actually contains usable RAM. - */ -static int __init early_parse_fbmem(char *p) -{ - int ret; - unsigned long align; - - fbmem_size = memparse(p, &p); - if (*p == '@') { - fbmem_start = memparse(p + 1, &p); - ret = add_reserved_region(fbmem_start, - fbmem_start + fbmem_size - 1, - "Framebuffer"); - if (ret) { - printk(KERN_WARNING - "Failed to reserve framebuffer memory\n"); - fbmem_start = 0; - } - } - - if (!fbmem_start) { - if ((fbmem_size & 0x000fffffUL) == 0) - align = 0x100000; /* 1 MiB */ - else if ((fbmem_size & 0x0000ffffUL) == 0) - align = 0x10000; /* 64 KiB */ - else - align = 0x1000; /* 4 KiB */ - - ret = alloc_reserved_region(&fbmem_start, fbmem_size, - align, "Framebuffer"); - if (ret) { - printk(KERN_WARNING - "Failed to allocate framebuffer memory\n"); - fbmem_size = 0; - } else { - memset(__va(fbmem_start), 0, fbmem_size); - } - } - - return 0; -} -early_param("fbmem", early_parse_fbmem); - -/* - * Pick out the memory size. We look for mem=size@start, - * where start and size are "size[KkMmGg]" - */ -static int __init early_mem(char *p) -{ - resource_size_t size, start; - - start = system_ram->start; - size = memparse(p, &p); - if (*p == '@') - start = memparse(p + 1, &p); - - system_ram->start = start; - system_ram->end = system_ram->start + size - 1; - return 0; -} -early_param("mem", early_mem); - -static int __init parse_tag_core(struct tag *tag) -{ - if (tag->hdr.size > 2) { - if ((tag->u.core.flags & 1) == 0) - root_mountflags &= ~MS_RDONLY; - ROOT_DEV = new_decode_dev(tag->u.core.rootdev); - } - return 0; -} -__tagtable(ATAG_CORE, parse_tag_core); - -static int __init parse_tag_mem(struct tag *tag) -{ - unsigned long start, end; - - /* - * Ignore zero-sized entries. If we're running standalone, the - * SDRAM code may emit such entries if something goes - * wrong... - */ - if (tag->u.mem_range.size == 0) - return 0; - - start = tag->u.mem_range.addr; - end = tag->u.mem_range.addr + tag->u.mem_range.size - 1; - - add_physical_memory(start, end); - return 0; -} -__tagtable(ATAG_MEM, parse_tag_mem); - -static int __init parse_tag_rdimg(struct tag *tag) -{ -#ifdef CONFIG_BLK_DEV_INITRD - struct tag_mem_range *mem = &tag->u.mem_range; - int ret; - - if (initrd_start) { - printk(KERN_WARNING - "Warning: Only the first initrd image will be used\n"); - return 0; - } - - ret = add_reserved_region(mem->addr, mem->addr + mem->size - 1, - "initrd"); - if (ret) { - printk(KERN_WARNING - "Warning: Failed to reserve initrd memory\n"); - return ret; - } - - initrd_start = (unsigned long)__va(mem->addr); - initrd_end = initrd_start + mem->size; -#else - printk(KERN_WARNING "RAM disk image present, but " - "no initrd support in kernel, ignoring\n"); -#endif - - return 0; -} -__tagtable(ATAG_RDIMG, parse_tag_rdimg); - -static int __init parse_tag_rsvd_mem(struct tag *tag) -{ - struct tag_mem_range *mem = &tag->u.mem_range; - - return add_reserved_region(mem->addr, mem->addr + mem->size - 1, - "Reserved"); -} -__tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem); - -static int __init parse_tag_cmdline(struct tag *tag) -{ - strlcpy(boot_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE); - return 0; -} -__tagtable(ATAG_CMDLINE, parse_tag_cmdline); - -static int __init parse_tag_clock(struct tag *tag) -{ - /* - * We'll figure out the clocks by peeking at the system - * manager regs directly. - */ - return 0; -} -__tagtable(ATAG_CLOCK, parse_tag_clock); - -/* - * The board_number correspond to the bd->bi_board_number in U-Boot. This - * parameter is only available during initialisation and can be used in some - * kind of board identification. - */ -u32 __initdata board_number; - -static int __init parse_tag_boardinfo(struct tag *tag) -{ - board_number = tag->u.boardinfo.board_number; - - return 0; -} -__tagtable(ATAG_BOARDINFO, parse_tag_boardinfo); - -/* - * Scan the tag table for this tag, and call its parse function. The - * tag table is built by the linker from all the __tagtable - * declarations. - */ -static int __init parse_tag(struct tag *tag) -{ - extern struct tagtable __tagtable_begin, __tagtable_end; - struct tagtable *t; - - for (t = &__tagtable_begin; t < &__tagtable_end; t++) - if (tag->hdr.tag == t->tag) { - t->parse(tag); - break; - } - - return t < &__tagtable_end; -} - -/* - * Parse all tags in the list we got from the boot loader - */ -static void __init parse_tags(struct tag *t) -{ - for (; t->hdr.tag != ATAG_NONE; t = tag_next(t)) - if (!parse_tag(t)) - printk(KERN_WARNING - "Ignoring unrecognised tag 0x%08x\n", - t->hdr.tag); -} - -/* - * Find a free memory region large enough for storing the - * bootmem bitmap. - */ -static unsigned long __init -find_bootmap_pfn(const struct resource *mem) -{ - unsigned long bootmap_pages, bootmap_len; - unsigned long node_pages = PFN_UP(resource_size(mem)); - unsigned long bootmap_start; - - bootmap_pages = bootmem_bootmap_pages(node_pages); - bootmap_len = bootmap_pages << PAGE_SHIFT; - - /* - * Find a large enough region without reserved pages for - * storing the bootmem bitmap. We can take advantage of the - * fact that all lists have been sorted. - * - * We have to check that we don't collide with any reserved - * regions, which includes the kernel image and any RAMDISK - * images. - */ - bootmap_start = find_free_region(mem, bootmap_len, PAGE_SIZE); - - return bootmap_start >> PAGE_SHIFT; -} - -#define MAX_LOWMEM HIGHMEM_START -#define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM) - -static void __init setup_bootmem(void) -{ - unsigned bootmap_size; - unsigned long first_pfn, bootmap_pfn, pages; - unsigned long max_pfn, max_low_pfn; - unsigned node = 0; - struct resource *res; - - printk(KERN_INFO "Physical memory:\n"); - for (res = system_ram; res; res = res->sibling) - printk(" %08x-%08x\n", res->start, res->end); - printk(KERN_INFO "Reserved memory:\n"); - for (res = reserved; res; res = res->sibling) - printk(" %08x-%08x: %s\n", - res->start, res->end, res->name); - - nodes_clear(node_online_map); - - if (system_ram->sibling) - printk(KERN_WARNING "Only using first memory bank\n"); - - for (res = system_ram; res; res = NULL) { - first_pfn = PFN_UP(res->start); - max_low_pfn = max_pfn = PFN_DOWN(res->end + 1); - bootmap_pfn = find_bootmap_pfn(res); - if (bootmap_pfn > max_pfn) - panic("No space for bootmem bitmap!\n"); - - if (max_low_pfn > MAX_LOWMEM_PFN) { - max_low_pfn = MAX_LOWMEM_PFN; -#ifndef CONFIG_HIGHMEM - /* - * Lowmem is memory that can be addressed - * directly through P1/P2 - */ - printk(KERN_WARNING - "Node %u: Only %ld MiB of memory will be used.\n", - node, MAX_LOWMEM >> 20); - printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); -#else -#error HIGHMEM is not supported by AVR32 yet -#endif - } - - /* Initialize the boot-time allocator with low memory only. */ - bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn, - first_pfn, max_low_pfn); - - /* - * Register fully available RAM pages with the bootmem - * allocator. - */ - pages = max_low_pfn - first_pfn; - free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn), - PFN_PHYS(pages)); - - /* Reserve space for the bootmem bitmap... */ - reserve_bootmem_node(NODE_DATA(node), - PFN_PHYS(bootmap_pfn), - bootmap_size, - BOOTMEM_DEFAULT); - - /* ...and any other reserved regions. */ - for (res = reserved; res; res = res->sibling) { - if (res->start > PFN_PHYS(max_pfn)) - break; - - /* - * resource_init will complain about partial - * overlaps, so we'll just ignore such - * resources for now. - */ - if (res->start >= PFN_PHYS(first_pfn) - && res->end < PFN_PHYS(max_pfn)) - reserve_bootmem_node(NODE_DATA(node), - res->start, - resource_size(res), - BOOTMEM_DEFAULT); - } - - node_set_online(node); - } -} - -void __init setup_arch (char **cmdline_p) -{ - struct clk *cpu_clk; - - init_mm.start_code = (unsigned long)_stext; - init_mm.end_code = (unsigned long)_etext; - init_mm.end_data = (unsigned long)_edata; - init_mm.brk = (unsigned long)_end; - - /* - * Include .init section to make allocations easier. It will - * be removed before the resource is actually requested. - */ - kernel_code.start = __pa(__init_begin); - kernel_code.end = __pa(init_mm.end_code - 1); - kernel_data.start = __pa(init_mm.end_code); - kernel_data.end = __pa(init_mm.brk - 1); - - parse_tags(bootloader_tags); - - setup_processor(); - setup_platform(); - setup_board(); - - cpu_clk = clk_get(NULL, "cpu"); - if (IS_ERR(cpu_clk)) { - printk(KERN_WARNING "Warning: Unable to get CPU clock\n"); - } else { - unsigned long cpu_hz = clk_get_rate(cpu_clk); - - /* - * Well, duh, but it's probably a good idea to - * increment the use count. - */ - clk_enable(cpu_clk); - - boot_cpu_data.clk = cpu_clk; - boot_cpu_data.loops_per_jiffy = cpu_hz * 4; - printk("CPU: Running at %lu.%03lu MHz\n", - ((cpu_hz + 500) / 1000) / 1000, - ((cpu_hz + 500) / 1000) % 1000); - } - - strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - parse_early_param(); - - setup_bootmem(); - -#ifdef CONFIG_VT - conswitchp = &dummy_con; -#endif - - paging_init(); - resource_init(); -} diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c deleted file mode 100644 index b5fcc4914fe4..000000000000 --- a/arch/avr32/kernel/signal.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * Based on linux/arch/sh/kernel/signal.c - * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/errno.h> -#include <linux/ptrace.h> -#include <linux/unistd.h> -#include <linux/tracehook.h> - -#include <linux/uaccess.h> -#include <asm/ucontext.h> -#include <asm/syscalls.h> - -struct rt_sigframe -{ - struct siginfo info; - struct ucontext uc; - unsigned long retcode; -}; - -static int -restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) -{ - int err = 0; - -#define COPY(x) err |= __get_user(regs->x, &sc->x) - COPY(sr); - COPY(pc); - COPY(lr); - COPY(sp); - COPY(r12); - COPY(r11); - COPY(r10); - COPY(r9); - COPY(r8); - COPY(r7); - COPY(r6); - COPY(r5); - COPY(r4); - COPY(r3); - COPY(r2); - COPY(r1); - COPY(r0); -#undef COPY - - /* - * Don't allow anyone to pretend they're running in supervisor - * mode or something... - */ - err |= !valid_user_regs(regs); - - return err; -} - - -asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) -{ - struct rt_sigframe __user *frame; - sigset_t set; - - /* Always make any pending restarted system calls return -EINTR */ - current->restart_block.fn = do_no_restart_syscall; - - frame = (struct rt_sigframe __user *)regs->sp; - pr_debug("SIG return: frame = %p\n", frame); - - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - - if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) - goto badframe; - - set_current_blocked(&set); - - if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) - goto badframe; - - if (restore_altstack(&frame->uc.uc_stack)) - goto badframe; - - pr_debug("Context restored: pc = %08lx, lr = %08lx, sp = %08lx\n", - regs->pc, regs->lr, regs->sp); - - return regs->r12; - -badframe: - force_sig(SIGSEGV, current); - return 0; -} - -static int -setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) -{ - int err = 0; - -#define COPY(x) err |= __put_user(regs->x, &sc->x) - COPY(sr); - COPY(pc); - COPY(lr); - COPY(sp); - COPY(r12); - COPY(r11); - COPY(r10); - COPY(r9); - COPY(r8); - COPY(r7); - COPY(r6); - COPY(r5); - COPY(r4); - COPY(r3); - COPY(r2); - COPY(r1); - COPY(r0); -#undef COPY - - return err; -} - -static inline void __user * -get_sigframe(struct ksignal *ksig, struct pt_regs *regs, int framesize) -{ - unsigned long sp = sigsp(regs->sp, ksig); - - return (void __user *)((sp - framesize) & ~3); -} - -static int -setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) -{ - struct rt_sigframe __user *frame; - int err = 0; - - frame = get_sigframe(ksig, regs, sizeof(*frame)); - err = -EFAULT; - if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) - goto out; - - /* - * Set up the return code: - * - * mov r8, __NR_rt_sigreturn - * scall - * - * Note: This will blow up since we're using a non-executable - * stack. Better use SA_RESTORER. - */ -#if __NR_rt_sigreturn > 127 -# error __NR_rt_sigreturn must be < 127 to fit in a short mov -#endif - err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20), - &frame->retcode); - - err |= copy_siginfo_to_user(&frame->info, &ksig->info); - - /* Set up the ucontext */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(NULL, &frame->uc.uc_link); - err |= __save_altstack(&frame->uc.uc_stack, regs->sp); - err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); - err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - - if (err) - goto out; - - regs->r12 = ksig->sig; - regs->r11 = (unsigned long) &frame->info; - regs->r10 = (unsigned long) &frame->uc; - regs->sp = (unsigned long) frame; - if (ksig->ka.sa.sa_flags & SA_RESTORER) - regs->lr = (unsigned long)ksig->ka.sa.sa_restorer; - else { - printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n", - current->comm, current->pid); - regs->lr = (unsigned long) &frame->retcode; - } - - pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n", - current->comm, current->pid, ksig->sig, regs->sp, - regs->pc, ksig->ka.sa.sa_handler, regs->lr); - - regs->pc = (unsigned long)ksig->ka.sa.sa_handler; - -out: - return err; -} - -static inline void setup_syscall_restart(struct pt_regs *regs) -{ - if (regs->r12 == -ERESTART_RESTARTBLOCK) - regs->r8 = __NR_restart_syscall; - else - regs->r12 = regs->r12_orig; - regs->pc -= 2; -} - -static inline void -handle_signal(struct ksignal *ksig, struct pt_regs *regs, int syscall) -{ - int ret; - - /* - * Set up the stack frame - */ - ret = setup_rt_frame(ksig, sigmask_to_save(), regs); - - /* - * Check that the resulting registers are sane - */ - ret |= !valid_user_regs(regs); - - /* - * Block the signal if we were successful. - */ - signal_setup_done(ret, ksig, 0); -} - -/* - * Note that 'init' is a special process: it doesn't get signals it - * doesn't want to handle. Thus you cannot kill init even with a - * SIGKILL even by mistake. - */ -static void do_signal(struct pt_regs *regs, int syscall) -{ - struct ksignal ksig; - - /* - * We want the common case to go fast, which is why we may in - * certain cases get here from kernel mode. Just return - * without doing anything if so. - */ - if (!user_mode(regs)) - return; - - get_signal(&ksig); - if (syscall) { - switch (regs->r12) { - case -ERESTART_RESTARTBLOCK: - case -ERESTARTNOHAND: - if (ksig.sig > 0) { - regs->r12 = -EINTR; - break; - } - /* fall through */ - case -ERESTARTSYS: - if (ksig.sig > 0 && !(ksig.ka.sa.sa_flags & SA_RESTART)) { - regs->r12 = -EINTR; - break; - } - /* fall through */ - case -ERESTARTNOINTR: - setup_syscall_restart(regs); - } - } - - if (!ksig.sig) { - /* No signal to deliver -- put the saved sigmask back */ - restore_saved_sigmask(); - return; - } - - handle_signal(&ksig, regs, syscall); -} - -asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) -{ - int syscall = 0; - - if ((sysreg_read(SR) & MODE_MASK) == MODE_SUPERVISOR) - syscall = 1; - - if (ti->flags & _TIF_SIGPENDING) - do_signal(regs, syscall); - - if (ti->flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - } -} diff --git a/arch/avr32/kernel/stacktrace.c b/arch/avr32/kernel/stacktrace.c deleted file mode 100644 index f8cc995cf0e0..000000000000 --- a/arch/avr32/kernel/stacktrace.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Stack trace management functions - * - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/sched.h> -#include <linux/sched/task_stack.h> -#include <linux/stacktrace.h> -#include <linux/thread_info.h> -#include <linux/module.h> - -register unsigned long current_frame_pointer asm("r7"); - -struct stackframe { - unsigned long lr; - unsigned long fp; -}; - -/* - * Save stack-backtrace addresses into a stack_trace buffer. - */ -void save_stack_trace(struct stack_trace *trace) -{ - unsigned long low, high; - unsigned long fp; - struct stackframe *frame; - int skip = trace->skip; - - low = (unsigned long)task_stack_page(current); - high = low + THREAD_SIZE; - fp = current_frame_pointer; - - while (fp >= low && fp <= (high - 8)) { - frame = (struct stackframe *)fp; - - if (skip) { - skip--; - } else { - trace->entries[trace->nr_entries++] = frame->lr; - if (trace->nr_entries >= trace->max_entries) - break; - } - - /* - * The next frame must be at a higher address than the - * current frame. - */ - low = fp + 8; - fp = frame->fp; - } -} -EXPORT_SYMBOL_GPL(save_stack_trace); diff --git a/arch/avr32/kernel/switch_to.S b/arch/avr32/kernel/switch_to.S deleted file mode 100644 index a48d046723c5..000000000000 --- a/arch/avr32/kernel/switch_to.S +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <asm/sysreg.h> - - .text - .global __switch_to - .type __switch_to, @function - - /* Switch thread context from "prev" to "next", returning "last" - * r12 : prev - * r11 : &prev->thread + 1 - * r10 : &next->thread - */ -__switch_to: - stm --r11, r0,r1,r2,r3,r4,r5,r6,r7,sp,lr - mfsr r9, SYSREG_SR - st.w --r11, r9 - ld.w r8, r10++ - /* - * schedule() may have been called from a mode with a different - * set of registers. Make sure we don't lose anything here. - */ - pushm r10,r12 - mtsr SYSREG_SR, r8 - frs /* flush the return stack */ - sub pc, -2 /* flush the pipeline */ - popm r10,r12 - ldm r10++, r0,r1,r2,r3,r4,r5,r6,r7,sp,pc - .size __switch_to, . - __switch_to diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S deleted file mode 100644 index cb256534ed92..000000000000 --- a/arch/avr32/kernel/syscall-stubs.S +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* - * Stubs for syscalls that require access to pt_regs or that take more - * than five parameters. - */ - -#define ARG6 r3 - - .text - .global __sys_rt_sigsuspend - .type __sys_rt_sigsuspend,@function -__sys_rt_sigsuspend: - mov r10, sp - rjmp sys_rt_sigsuspend - - .global __sys_rt_sigreturn - .type __sys_rt_sigreturn,@function -__sys_rt_sigreturn: - mov r12, sp - rjmp sys_rt_sigreturn - - .global __sys_mmap2 - .type __sys_mmap2,@function -__sys_mmap2: - pushm lr - st.w --sp, ARG6 - call sys_mmap_pgoff - sub sp, -4 - popm pc - - .global __sys_sendto - .type __sys_sendto,@function -__sys_sendto: - pushm lr - st.w --sp, ARG6 - call sys_sendto - sub sp, -4 - popm pc - - .global __sys_recvfrom - .type __sys_recvfrom,@function -__sys_recvfrom: - pushm lr - st.w --sp, ARG6 - call sys_recvfrom - sub sp, -4 - popm pc - - .global __sys_pselect6 - .type __sys_pselect6,@function -__sys_pselect6: - pushm lr - st.w --sp, ARG6 - call sys_pselect6 - sub sp, -4 - popm pc - - .global __sys_splice - .type __sys_splice,@function -__sys_splice: - pushm lr - st.w --sp, ARG6 - call sys_splice - sub sp, -4 - popm pc - - .global __sys_epoll_pwait - .type __sys_epoll_pwait,@function -__sys_epoll_pwait: - pushm lr - st.w --sp, ARG6 - call sys_epoll_pwait - sub sp, -4 - popm pc - - .global __sys_sync_file_range - .type __sys_sync_file_range,@function -__sys_sync_file_range: - pushm lr - st.w --sp, ARG6 - call sys_sync_file_range - sub sp, -4 - popm pc - - .global __sys_fallocate - .type __sys_fallocate,@function -__sys_fallocate: - pushm lr - st.w --sp, ARG6 - call sys_fallocate - sub sp, -4 - popm pc - - .global __sys_fanotify_mark - .type __sys_fanotify_mark,@function -__sys_fanotify_mark: - pushm lr - st.w --sp, ARG6 - call sys_fanotify_mark - sub sp, -4 - popm pc - - .global __sys_process_vm_readv - .type __sys_process_vm_readv,@function -__sys_process_vm_readv: - pushm lr - st.w --sp, ARG6 - call sys_process_vm_readv - sub sp, -4 - popm pc - - .global __sys_process_vm_writev - .type __sys_process_vm_writev,@function -__sys_process_vm_writev: - pushm lr - st.w --sp, ARG6 - call sys_process_vm_writev - sub sp, -4 - popm pc - - .global __sys_copy_file_range - .type __sys_copy_file_range,@function -__sys_copy_file_range: - pushm lr - st.w --sp, ARG6 - call sys_copy_file_range - sub sp, -4 - popm pc - - .global __sys_preadv2 - .type __sys_preadv2,@function -__sys_preadv2: - pushm lr - st.w --sp, ARG6 - call sys_preadv2 - sub sp, -4 - popm pc - - .global __sys_pwritev2 - .type __sys_pwritev2,@function -__sys_pwritev2: - pushm lr - st.w --sp, ARG6 - call sys_pwritev2 - sub sp, -4 - popm pc diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S deleted file mode 100644 index 774ce57f4948..000000000000 --- a/arch/avr32/kernel/syscall_table.S +++ /dev/null @@ -1,347 +0,0 @@ -/* - * AVR32 system call table - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - .section .rodata,"a",@progbits - .type sys_call_table,@object - .global sys_call_table - .align 2 -sys_call_table: - .long sys_restart_syscall - .long sys_exit - .long sys_fork - .long sys_read - .long sys_write - .long sys_open - .long sys_close - .long sys_umask - .long sys_creat - .long sys_link - .long sys_unlink /* 10 */ - .long sys_execve - .long sys_chdir - .long sys_time - .long sys_mknod - .long sys_chmod - .long sys_chown - .long sys_lchown - .long sys_lseek - .long sys_llseek - .long sys_getpid /* 20 */ - .long sys_mount - .long sys_umount - .long sys_setuid - .long sys_getuid - .long sys_stime - .long sys_ptrace - .long sys_alarm - .long sys_pause - .long sys_utime - .long sys_newstat /* 30 */ - .long sys_newfstat - .long sys_newlstat - .long sys_access - .long sys_chroot - .long sys_sync - .long sys_fsync - .long sys_kill - .long sys_rename - .long sys_mkdir - .long sys_rmdir /* 40 */ - .long sys_dup - .long sys_pipe - .long sys_times - .long sys_clone - .long sys_brk - .long sys_setgid - .long sys_getgid - .long sys_getcwd - .long sys_geteuid - .long sys_getegid /* 50 */ - .long sys_acct - .long sys_setfsuid - .long sys_setfsgid - .long sys_ioctl - .long sys_fcntl - .long sys_setpgid - .long sys_mremap - .long sys_setresuid - .long sys_getresuid - .long sys_setreuid /* 60 */ - .long sys_setregid - .long sys_ustat - .long sys_dup2 - .long sys_getppid - .long sys_getpgrp - .long sys_setsid - .long sys_rt_sigaction - .long __sys_rt_sigreturn - .long sys_rt_sigprocmask - .long sys_rt_sigpending /* 70 */ - .long sys_rt_sigtimedwait - .long sys_rt_sigqueueinfo - .long __sys_rt_sigsuspend - .long sys_sethostname - .long sys_setrlimit - .long sys_getrlimit - .long sys_getrusage - .long sys_gettimeofday - .long sys_settimeofday - .long sys_getgroups /* 80 */ - .long sys_setgroups - .long sys_select - .long sys_symlink - .long sys_fchdir - .long sys_readlink - .long sys_pread64 - .long sys_pwrite64 - .long sys_swapon - .long sys_reboot - .long __sys_mmap2 /* 90 */ - .long sys_munmap - .long sys_truncate - .long sys_ftruncate - .long sys_fchmod - .long sys_fchown - .long sys_getpriority - .long sys_setpriority - .long sys_wait4 - .long sys_statfs - .long sys_fstatfs /* 100 */ - .long sys_vhangup - .long sys_sigaltstack - .long sys_syslog - .long sys_setitimer - .long sys_getitimer - .long sys_swapoff - .long sys_sysinfo - .long sys_ni_syscall /* was sys_ipc briefly */ - .long sys_sendfile - .long sys_setdomainname /* 110 */ - .long sys_newuname - .long sys_adjtimex - .long sys_mprotect - .long sys_vfork - .long sys_init_module - .long sys_delete_module - .long sys_quotactl - .long sys_getpgid - .long sys_bdflush - .long sys_sysfs /* 120 */ - .long sys_personality - .long sys_ni_syscall /* reserved for afs_syscall */ - .long sys_getdents - .long sys_flock - .long sys_msync - .long sys_readv - .long sys_writev - .long sys_getsid - .long sys_fdatasync - .long sys_sysctl /* 130 */ - .long sys_mlock - .long sys_munlock - .long sys_mlockall - .long sys_munlockall - .long sys_sched_setparam - .long sys_sched_getparam - .long sys_sched_setscheduler - .long sys_sched_getscheduler - .long sys_sched_yield - .long sys_sched_get_priority_max /* 140 */ - .long sys_sched_get_priority_min - .long sys_sched_rr_get_interval - .long sys_nanosleep - .long sys_poll - .long sys_ni_syscall /* 145 was nfsservctl */ - .long sys_setresgid - .long sys_getresgid - .long sys_prctl - .long sys_socket - .long sys_bind /* 150 */ - .long sys_connect - .long sys_listen - .long sys_accept - .long sys_getsockname - .long sys_getpeername - .long sys_socketpair - .long sys_send - .long sys_recv - .long __sys_sendto - .long __sys_recvfrom /* 160 */ - .long sys_shutdown - .long sys_setsockopt - .long sys_getsockopt - .long sys_sendmsg - .long sys_recvmsg - .long sys_truncate64 - .long sys_ftruncate64 - .long sys_stat64 - .long sys_lstat64 - .long sys_fstat64 /* 170 */ - .long sys_pivot_root - .long sys_mincore - .long sys_madvise - .long sys_getdents64 - .long sys_fcntl64 - .long sys_gettid - .long sys_readahead - .long sys_setxattr - .long sys_lsetxattr - .long sys_fsetxattr /* 180 */ - .long sys_getxattr - .long sys_lgetxattr - .long sys_fgetxattr - .long sys_listxattr - .long sys_llistxattr - .long sys_flistxattr - .long sys_removexattr - .long sys_lremovexattr - .long sys_fremovexattr - .long sys_tkill /* 190 */ - .long sys_sendfile64 - .long sys_futex - .long sys_sched_setaffinity - .long sys_sched_getaffinity - .long sys_capget - .long sys_capset - .long sys_io_setup - .long sys_io_destroy - .long sys_io_getevents - .long sys_io_submit /* 200 */ - .long sys_io_cancel - .long sys_fadvise64 - .long sys_exit_group - .long sys_lookup_dcookie - .long sys_epoll_create - .long sys_epoll_ctl - .long sys_epoll_wait - .long sys_remap_file_pages - .long sys_set_tid_address - .long sys_timer_create /* 210 */ - .long sys_timer_settime - .long sys_timer_gettime - .long sys_timer_getoverrun - .long sys_timer_delete - .long sys_clock_settime - .long sys_clock_gettime - .long sys_clock_getres - .long sys_clock_nanosleep - .long sys_statfs64 - .long sys_fstatfs64 /* 220 */ - .long sys_tgkill - .long sys_ni_syscall /* reserved for TUX */ - .long sys_utimes - .long sys_fadvise64_64 - .long sys_cacheflush - .long sys_ni_syscall /* sys_vserver */ - .long sys_mq_open - .long sys_mq_unlink - .long sys_mq_timedsend - .long sys_mq_timedreceive /* 230 */ - .long sys_mq_notify - .long sys_mq_getsetattr - .long sys_kexec_load - .long sys_waitid - .long sys_add_key - .long sys_request_key - .long sys_keyctl - .long sys_ioprio_set - .long sys_ioprio_get - .long sys_inotify_init /* 240 */ - .long sys_inotify_add_watch - .long sys_inotify_rm_watch - .long sys_openat - .long sys_mkdirat - .long sys_mknodat - .long sys_fchownat - .long sys_futimesat - .long sys_fstatat64 - .long sys_unlinkat - .long sys_renameat /* 250 */ - .long sys_linkat - .long sys_symlinkat - .long sys_readlinkat - .long sys_fchmodat - .long sys_faccessat - .long __sys_pselect6 - .long sys_ppoll - .long sys_unshare - .long sys_set_robust_list - .long sys_get_robust_list /* 260 */ - .long __sys_splice - .long __sys_sync_file_range - .long sys_tee - .long sys_vmsplice - .long __sys_epoll_pwait - .long sys_msgget - .long sys_msgsnd - .long sys_msgrcv - .long sys_msgctl - .long sys_semget /* 270 */ - .long sys_semop - .long sys_semctl - .long sys_semtimedop - .long sys_shmat - .long sys_shmget - .long sys_shmdt - .long sys_shmctl - .long sys_utimensat - .long sys_signalfd - .long sys_ni_syscall /* 280, was sys_timerfd */ - .long sys_eventfd - .long sys_ni_syscall /* 282, was half-implemented recvmmsg */ - .long sys_setns - .long sys_pread64 - .long sys_pwrite64 - .long sys_timerfd_create - .long __sys_fallocate - .long sys_timerfd_settime - .long sys_timerfd_gettime - .long sys_signalfd4 /* 290 */ - .long sys_eventfd2 - .long sys_epoll_create1 - .long sys_dup3 - .long sys_pipe2 - .long sys_inotify_init1 - .long sys_preadv - .long sys_pwritev - .long sys_rt_tgsigqueueinfo - .long sys_perf_event_open - .long sys_recvmmsg /* 300 */ - .long sys_fanotify_init - .long __sys_fanotify_mark - .long sys_prlimit64 - .long sys_name_to_handle_at - .long sys_open_by_handle_at - .long sys_clock_adjtime - .long sys_syncfs - .long sys_sendmmsg - .long __sys_process_vm_readv - .long __sys_process_vm_writev /* 310 */ - .long sys_kcmp - .long sys_finit_module - .long sys_sched_setattr - .long sys_sched_getattr - .long sys_renameat2 - .long sys_seccomp - .long sys_getrandom - .long sys_memfd_create - .long sys_bpf - .long sys_execveat /* 320 */ - .long sys_accept4 - .long sys_userfaultfd - .long sys_membarrier - .long sys_mlock2 - .long __sys_copy_file_range - .long __sys_preadv2 - .long __sys_pwritev2 - .long sys_pkey_mprotect - .long sys_pkey_alloc - .long sys_pkey_free /* 330 */ - .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c deleted file mode 100644 index 4d9b69615979..000000000000 --- a/arch/avr32/kernel/time.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2004-2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/clockchips.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/time.h> -#include <linux/cpu.h> - -#include <asm/sysreg.h> - -#include <mach/pm.h> - -static bool disable_cpu_idle_poll; - -static u64 read_cycle_count(struct clocksource *cs) -{ - return (u64)sysreg_read(COUNT); -} - -/* - * The architectural cycle count registers are a fine clocksource unless - * the system idle loop use sleep states like "idle": the CPU cycles - * measured by COUNT (and COMPARE) don't happen during sleep states. - * Their duration also changes if cpufreq changes the CPU clock rate. - * So we rate the clocksource using COUNT as very low quality. - */ -static struct clocksource counter = { - .name = "avr32_counter", - .rating = 50, - .read = read_cycle_count, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evdev = dev_id; - - if (unlikely(!(intc_get_pending(0) & 1))) - return IRQ_NONE; - - /* - * Disable the interrupt until the clockevent subsystem - * reprograms it. - */ - sysreg_write(COMPARE, 0); - - evdev->event_handler(evdev); - return IRQ_HANDLED; -} - -static struct irqaction timer_irqaction = { - .handler = timer_interrupt, - /* Oprofile uses the same irq as the timer, so allow it to be shared */ - .flags = IRQF_TIMER | IRQF_SHARED, - .name = "avr32_comparator", -}; - -static int comparator_next_event(unsigned long delta, - struct clock_event_device *evdev) -{ - unsigned long flags; - - raw_local_irq_save(flags); - - /* The time to read COUNT then update COMPARE must be less - * than the min_delta_ns value for this clockevent source. - */ - sysreg_write(COMPARE, (sysreg_read(COUNT) + delta) ? : 1); - - raw_local_irq_restore(flags); - - return 0; -} - -static int comparator_shutdown(struct clock_event_device *evdev) -{ - pr_debug("%s: %s\n", __func__, evdev->name); - sysreg_write(COMPARE, 0); - - if (disable_cpu_idle_poll) { - disable_cpu_idle_poll = false; - /* - * Only disable idle poll if we have forced that - * in a previous call. - */ - cpu_idle_poll_ctrl(false); - } - return 0; -} - -static int comparator_set_oneshot(struct clock_event_device *evdev) -{ - pr_debug("%s: %s\n", __func__, evdev->name); - - disable_cpu_idle_poll = true; - /* - * If we're using the COUNT and COMPARE registers we - * need to force idle poll. - */ - cpu_idle_poll_ctrl(true); - - return 0; -} - -static struct clock_event_device comparator = { - .name = "avr32_comparator", - .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 16, - .rating = 50, - .set_next_event = comparator_next_event, - .set_state_shutdown = comparator_shutdown, - .set_state_oneshot = comparator_set_oneshot, - .tick_resume = comparator_set_oneshot, -}; - -void read_persistent_clock(struct timespec *ts) -{ - ts->tv_sec = mktime(2007, 1, 1, 0, 0, 0); - ts->tv_nsec = 0; -} - -void __init time_init(void) -{ - unsigned long counter_hz; - int ret; - - /* figure rate for counter */ - counter_hz = clk_get_rate(boot_cpu_data.clk); - ret = clocksource_register_hz(&counter, counter_hz); - if (ret) - pr_debug("timer: could not register clocksource: %d\n", ret); - - /* setup COMPARE clockevent */ - comparator.mult = div_sc(counter_hz, NSEC_PER_SEC, comparator.shift); - comparator.max_delta_ns = clockevent_delta2ns((u32)~0, &comparator); - comparator.min_delta_ns = clockevent_delta2ns(50, &comparator) + 1; - comparator.cpumask = cpumask_of(0); - - sysreg_write(COMPARE, 0); - timer_irqaction.dev_id = &comparator; - - ret = setup_irq(0, &timer_irqaction); - if (ret) - pr_debug("timer: could not request IRQ 0: %d\n", ret); - else { - clockevents_register_device(&comparator); - - pr_info("%s: irq 0, %lu.%03lu MHz\n", comparator.name, - ((counter_hz + 500) / 1000) / 1000, - ((counter_hz + 500) / 1000) % 1000); - } -} diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c deleted file mode 100644 index 50b541325025..000000000000 --- a/arch/avr32/kernel/traps.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/bug.h> -#include <linux/hardirq.h> -#include <linux/init.h> -#include <linux/kallsyms.h> -#include <linux/kdebug.h> -#include <linux/extable.h> -#include <linux/module.h> /* print_modules */ -#include <linux/notifier.h> -#include <linux/sched/signal.h> -#include <linux/uaccess.h> - -#include <asm/addrspace.h> -#include <asm/mmu_context.h> -#include <asm/ocd.h> -#include <asm/sysreg.h> -#include <asm/traps.h> - -static DEFINE_SPINLOCK(die_lock); - -void die(const char *str, struct pt_regs *regs, long err) -{ - static int die_counter; - - console_verbose(); - spin_lock_irq(&die_lock); - bust_spinlocks(1); - - printk(KERN_ALERT "Oops: %s, sig: %ld [#%d]\n", - str, err, ++die_counter); - - printk(KERN_EMERG); - -#ifdef CONFIG_PREEMPT - printk(KERN_CONT "PREEMPT "); -#endif -#ifdef CONFIG_FRAME_POINTER - printk(KERN_CONT "FRAME_POINTER "); -#endif - if (current_cpu_data.features & AVR32_FEATURE_OCD) { - unsigned long did = ocd_read(DID); - printk(KERN_CONT "chip: 0x%03lx:0x%04lx rev %lu\n", - (did >> 1) & 0x7ff, - (did >> 12) & 0x7fff, - (did >> 28) & 0xf); - } else { - printk(KERN_CONT "cpu: arch %u r%u / core %u r%u\n", - current_cpu_data.arch_type, - current_cpu_data.arch_revision, - current_cpu_data.cpu_type, - current_cpu_data.cpu_revision); - } - - print_modules(); - show_regs_log_lvl(regs, KERN_EMERG); - show_stack_log_lvl(current, regs->sp, regs, KERN_EMERG); - bust_spinlocks(0); - add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); - spin_unlock_irq(&die_lock); - - if (in_interrupt()) - panic("Fatal exception in interrupt"); - - if (panic_on_oops) - panic("Fatal exception"); - - do_exit(err); -} - -void _exception(long signr, struct pt_regs *regs, int code, - unsigned long addr) -{ - siginfo_t info; - - if (!user_mode(regs)) { - const struct exception_table_entry *fixup; - - /* Are we prepared to handle this kernel fault? */ - fixup = search_exception_tables(regs->pc); - if (fixup) { - regs->pc = fixup->fixup; - return; - } - die("Unhandled exception in kernel mode", regs, signr); - } - - memset(&info, 0, sizeof(info)); - info.si_signo = signr; - info.si_code = code; - info.si_addr = (void __user *)addr; - force_sig_info(signr, &info, current); -} - -asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs) -{ - int ret; - - nmi_enter(); - - ret = notify_die(DIE_NMI, "NMI", regs, 0, ecr, SIGINT); - switch (ret) { - case NOTIFY_OK: - case NOTIFY_STOP: - break; - case NOTIFY_BAD: - die("Fatal Non-Maskable Interrupt", regs, SIGINT); - default: - printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n"); - nmi_disable(); - break; - } - nmi_exit(); -} - -asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs) -{ - die("Critical exception", regs, SIGKILL); -} - -asmlinkage void do_address_exception(unsigned long ecr, struct pt_regs *regs) -{ - _exception(SIGBUS, regs, BUS_ADRALN, regs->pc); -} - -/* This way of handling undefined instructions is stolen from ARM */ -static LIST_HEAD(undef_hook); -static DEFINE_SPINLOCK(undef_lock); - -void register_undef_hook(struct undef_hook *hook) -{ - spin_lock_irq(&undef_lock); - list_add(&hook->node, &undef_hook); - spin_unlock_irq(&undef_lock); -} - -void unregister_undef_hook(struct undef_hook *hook) -{ - spin_lock_irq(&undef_lock); - list_del(&hook->node); - spin_unlock_irq(&undef_lock); -} - -static int do_cop_absent(u32 insn) -{ - int cop_nr; - u32 cpucr; - - if ((insn & 0xfdf00000) == 0xf1900000) - /* LDC0 */ - cop_nr = 0; - else - cop_nr = (insn >> 13) & 0x7; - - /* Try enabling the coprocessor */ - cpucr = sysreg_read(CPUCR); - cpucr |= (1 << (24 + cop_nr)); - sysreg_write(CPUCR, cpucr); - - cpucr = sysreg_read(CPUCR); - if (!(cpucr & (1 << (24 + cop_nr)))) - return -ENODEV; - - return 0; -} - -#ifdef CONFIG_BUG -int is_valid_bugaddr(unsigned long pc) -{ - unsigned short opcode; - - if (pc < PAGE_OFFSET) - return 0; - if (probe_kernel_address((u16 *)pc, opcode)) - return 0; - - return opcode == AVR32_BUG_OPCODE; -} -#endif - -asmlinkage void do_illegal_opcode(unsigned long ecr, struct pt_regs *regs) -{ - u32 insn; - struct undef_hook *hook; - void __user *pc; - long code; - -#ifdef CONFIG_BUG - if (!user_mode(regs) && (ecr == ECR_ILLEGAL_OPCODE)) { - enum bug_trap_type type; - - type = report_bug(regs->pc, regs); - switch (type) { - case BUG_TRAP_TYPE_NONE: - break; - case BUG_TRAP_TYPE_WARN: - regs->pc += 2; - return; - case BUG_TRAP_TYPE_BUG: - die("Kernel BUG", regs, SIGKILL); - } - } -#endif - - local_irq_enable(); - - if (user_mode(regs)) { - pc = (void __user *)instruction_pointer(regs); - if (get_user(insn, (u32 __user *)pc)) - goto invalid_area; - - if (ecr == ECR_COPROC_ABSENT && !do_cop_absent(insn)) - return; - - spin_lock_irq(&undef_lock); - list_for_each_entry(hook, &undef_hook, node) { - if ((insn & hook->insn_mask) == hook->insn_val) { - if (hook->fn(regs, insn) == 0) { - spin_unlock_irq(&undef_lock); - return; - } - } - } - spin_unlock_irq(&undef_lock); - } - - switch (ecr) { - case ECR_PRIVILEGE_VIOLATION: - code = ILL_PRVOPC; - break; - case ECR_COPROC_ABSENT: - code = ILL_COPROC; - break; - default: - code = ILL_ILLOPC; - break; - } - - _exception(SIGILL, regs, code, regs->pc); - return; - -invalid_area: - _exception(SIGSEGV, regs, SEGV_MAPERR, regs->pc); -} - -asmlinkage void do_fpe(unsigned long ecr, struct pt_regs *regs) -{ - /* We have no FPU yet */ - _exception(SIGILL, regs, ILL_COPROC, regs->pc); -} - - -void __init trap_init(void) -{ - -} diff --git a/arch/avr32/kernel/vmlinux.lds.S b/arch/avr32/kernel/vmlinux.lds.S deleted file mode 100644 index 17f2730eb497..000000000000 --- a/arch/avr32/kernel/vmlinux.lds.S +++ /dev/null @@ -1,89 +0,0 @@ -/* - * AVR32 linker script for the Linux kernel - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#define LOAD_OFFSET 0x00000000 -#include <asm-generic/vmlinux.lds.h> -#include <asm/cache.h> -#include <asm/thread_info.h> - -OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32") -OUTPUT_ARCH(avr32) -ENTRY(_start) - -/* Big endian */ -jiffies = jiffies_64 + 4; - -SECTIONS -{ - . = CONFIG_ENTRY_ADDRESS; - .init : AT(ADDR(.init) - LOAD_OFFSET) { - _text = .; - __init_begin = .; - _sinittext = .; - *(.text.reset) - INIT_TEXT - /* - * .exit.text is discarded at runtime, not - * link time, to deal with references from - * __bug_table - */ - EXIT_TEXT - _einittext = .; - . = ALIGN(4); - __tagtable_begin = .; - *(.taglist.init) - __tagtable_end = .; - } - INIT_DATA_SECTION(16) - . = ALIGN(PAGE_SIZE); - __init_end = .; - - .text : AT(ADDR(.text) - LOAD_OFFSET) { - _evba = .; - _stext = .; - *(.ex.text) - *(.irq.text) - KPROBES_TEXT - TEXT_TEXT - SCHED_TEXT - CPUIDLE_TEXT - LOCK_TEXT - *(.fixup) - *(.gnu.warning) - _etext = .; - } = 0xd703d703 - - EXCEPTION_TABLE(4) - RODATA - - .data : AT(ADDR(.data) - LOAD_OFFSET) { - _data = .; - _sdata = .; - - INIT_TASK_DATA(THREAD_SIZE) - PAGE_ALIGNED_DATA(PAGE_SIZE); - CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) - *(.data.rel*) - DATA_DATA - CONSTRUCTORS - - _edata = .; - } - - BSS_SECTION(0, 8, 8) - _end = .; - - DWARF_DEBUG - - /* When something in the kernel is NOT compiled as a module, the module - * cleanup code and data are put into these segments. Both can then be - * thrown away, as cleanup code is never called unless it's a module. - */ - DISCARDS -} diff --git a/arch/avr32/lib/Makefile b/arch/avr32/lib/Makefile deleted file mode 100644 index 084d95bac5e7..000000000000 --- a/arch/avr32/lib/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for AVR32-specific library files -# - -lib-y := copy_user.o clear_user.o -lib-y += strncpy_from_user.o strnlen_user.o -lib-y += delay.o memset.o memcpy.o findbit.o -lib-y += csum_partial.o csum_partial_copy_generic.o -lib-y += io-readsw.o io-readsl.o io-writesw.o io-writesl.o -lib-y += io-readsb.o io-writesb.o -lib-y += __avr32_lsl64.o __avr32_lsr64.o __avr32_asr64.o diff --git a/arch/avr32/lib/__avr32_asr64.S b/arch/avr32/lib/__avr32_asr64.S deleted file mode 100644 index 368b6bca4c76..000000000000 --- a/arch/avr32/lib/__avr32_asr64.S +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - /* - * DWtype __avr32_asr64(DWtype u, word_type b) - */ - .text - .global __avr32_asr64 - .type __avr32_asr64,@function -__avr32_asr64: - cp.w r12, 0 - reteq r12 - - rsub r9, r12, 32 - brle 1f - - lsl r8, r11, r9 - lsr r10, r10, r12 - asr r11, r11, r12 - or r10, r8 - retal r12 - -1: neg r9 - asr r10, r11, r9 - asr r11, 31 - retal r12 diff --git a/arch/avr32/lib/__avr32_lsl64.S b/arch/avr32/lib/__avr32_lsl64.S deleted file mode 100644 index f1dbc2b36257..000000000000 --- a/arch/avr32/lib/__avr32_lsl64.S +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - /* - * DWtype __avr32_lsl64(DWtype u, word_type b) - */ - .text - .global __avr32_lsl64 - .type __avr32_lsl64,@function -__avr32_lsl64: - cp.w r12, 0 - reteq r12 - - rsub r9, r12, 32 - brle 1f - - lsr r8, r10, r9 - lsl r10, r10, r12 - lsl r11, r11, r12 - or r11, r8 - retal r12 - -1: neg r9 - lsl r11, r10, r9 - mov r10, 0 - retal r12 diff --git a/arch/avr32/lib/__avr32_lsr64.S b/arch/avr32/lib/__avr32_lsr64.S deleted file mode 100644 index e65bb7f0d24c..000000000000 --- a/arch/avr32/lib/__avr32_lsr64.S +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - /* - * DWtype __avr32_lsr64(DWtype u, word_type b) - */ - .text - .global __avr32_lsr64 - .type __avr32_lsr64,@function -__avr32_lsr64: - cp.w r12, 0 - reteq r12 - - rsub r9, r12, 32 - brle 1f - - lsl r8, r11, r9 - lsr r11, r11, r12 - lsr r10, r10, r12 - or r10, r8 - retal r12 - -1: neg r9 - lsr r10, r11, r9 - mov r11, 0 - retal r12 diff --git a/arch/avr32/lib/clear_user.S b/arch/avr32/lib/clear_user.S deleted file mode 100644 index d8991b6f8eb7..000000000000 --- a/arch/avr32/lib/clear_user.S +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <asm/page.h> -#include <asm/thread_info.h> -#include <asm/asm.h> - - .text - .align 1 - .global clear_user - .type clear_user, "function" -clear_user: - branch_if_kernel r8, __clear_user - ret_if_privileged r8, r12, r11, r11 - - .global __clear_user - .type __clear_user, "function" -__clear_user: - mov r9, r12 - mov r8, 0 - andl r9, 3, COH - brne 5f - -1: sub r11, 4 - brlt 2f - -10: st.w r12++, r8 - sub r11, 4 - brge 10b - -2: sub r11, -4 - reteq 0 - - /* Unaligned count or address */ - bld r11, 1 - brcc 12f -11: st.h r12++, r8 - sub r11, 2 - reteq 0 -12: st.b r12++, r8 - retal 0 - - /* Unaligned address */ -5: cp.w r11, 4 - brlt 2b - - lsl r9, 2 - add pc, pc, r9 -13: st.b r12++, r8 - sub r11, 1 -14: st.b r12++, r8 - sub r11, 1 -15: st.b r12++, r8 - sub r11, 1 - rjmp 1b - - .size clear_user, . - clear_user - .size __clear_user, . - __clear_user - - .section .fixup, "ax" - .align 1 -18: sub r11, -4 -19: retal r11 - - .section __ex_table, "a" - .align 2 - .long 10b, 18b - .long 11b, 19b - .long 12b, 19b - .long 13b, 19b - .long 14b, 19b - .long 15b, 19b diff --git a/arch/avr32/lib/copy_user.S b/arch/avr32/lib/copy_user.S deleted file mode 100644 index 075373471da1..000000000000 --- a/arch/avr32/lib/copy_user.S +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copy to/from userspace with optional address space checking. - * - * Copyright 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <asm/page.h> -#include <asm/thread_info.h> -#include <asm/asm.h> - - /* - * __kernel_size_t - * __copy_user(void *to, const void *from, __kernel_size_t n) - * - * Returns the number of bytes not copied. Might be off by - * max 3 bytes if we get a fault in the main loop. - * - * The address-space checking functions simply fall through to - * the non-checking version. - */ - .text - .align 1 - .global ___copy_from_user - .type ___copy_from_user, @function -___copy_from_user: - branch_if_kernel r8, __copy_user - ret_if_privileged r8, r11, r10, r10 - rjmp __copy_user - .size ___copy_from_user, . - ___copy_from_user - - .global copy_to_user - .type copy_to_user, @function -copy_to_user: - branch_if_kernel r8, __copy_user - ret_if_privileged r8, r12, r10, r10 - .size copy_to_user, . - copy_to_user - - .global __copy_user - .type __copy_user, @function -__copy_user: - mov r9, r11 - andl r9, 3, COH - brne 6f - - /* At this point, from is word-aligned */ -1: sub r10, 4 - brlt 3f - -2: -10: ld.w r8, r11++ -11: st.w r12++, r8 - sub r10, 4 - brge 2b - -3: sub r10, -4 - reteq 0 - - /* - * Handle unaligned count. Need to be careful with r10 here so - * that we return the correct value even if we get a fault - */ -4: -20: ld.ub r8, r11++ -21: st.b r12++, r8 - sub r10, 1 - reteq 0 -22: ld.ub r8, r11++ -23: st.b r12++, r8 - sub r10, 1 - reteq 0 -24: ld.ub r8, r11++ -25: st.b r12++, r8 - retal 0 - - /* Handle unaligned from-pointer */ -6: cp.w r10, 4 - brlt 4b - rsub r9, r9, 4 - -30: ld.ub r8, r11++ -31: st.b r12++, r8 - sub r10, 1 - sub r9, 1 - breq 1b -32: ld.ub r8, r11++ -33: st.b r12++, r8 - sub r10, 1 - sub r9, 1 - breq 1b -34: ld.ub r8, r11++ -35: st.b r12++, r8 - sub r10, 1 - rjmp 1b - .size __copy_user, . - __copy_user - - .section .fixup,"ax" - .align 1 -19: sub r10, -4 -29: retal r10 - - .section __ex_table,"a" - .align 2 - .long 10b, 19b - .long 11b, 19b - .long 20b, 29b - .long 21b, 29b - .long 22b, 29b - .long 23b, 29b - .long 24b, 29b - .long 25b, 29b - .long 30b, 29b - .long 31b, 29b - .long 32b, 29b - .long 33b, 29b - .long 34b, 29b - .long 35b, 29b diff --git a/arch/avr32/lib/csum_partial.S b/arch/avr32/lib/csum_partial.S deleted file mode 100644 index 6a262b528eb7..000000000000 --- a/arch/avr32/lib/csum_partial.S +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - /* - * unsigned int csum_partial(const unsigned char *buff, - * int len, unsigned int sum) - */ - .text - .global csum_partial - .type csum_partial,"function" - .align 1 -csum_partial: - /* checksum complete words, aligned or not */ -3: sub r11, 4 - brlt 5f -4: ld.w r9, r12++ - add r10, r9 - acr r10 - sub r11, 4 - brge 4b - - /* return if we had a whole number of words */ -5: sub r11, -4 - reteq r10 - - /* checksum any remaining bytes at the end */ - mov r9, 0 - mov r8, 0 - cp r11, 2 - brlt 6f - ld.uh r9, r12++ - sub r11, 2 - breq 7f - lsl r9, 16 -6: ld.ub r8, r12++ - lsl r8, 8 -7: or r9, r8 - add r10, r9 - acr r10 - - retal r10 - .size csum_partial, . - csum_partial diff --git a/arch/avr32/lib/csum_partial_copy_generic.S b/arch/avr32/lib/csum_partial_copy_generic.S deleted file mode 100644 index a3a0f9b8929c..000000000000 --- a/arch/avr32/lib/csum_partial_copy_generic.S +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <asm/errno.h> -#include <asm/asm.h> - - /* - * unsigned int csum_partial_copy_generic(const char *src, char *dst, int len - * int sum, int *src_err_ptr, - * int *dst_err_ptr) - * - * Copy src to dst while checksumming, otherwise like csum_partial. - */ - - .macro ld_src size, reg, ptr -9999: ld.\size \reg, \ptr - .section __ex_table, "a" - .long 9999b, fixup_ld_src - .previous - .endm - - .macro st_dst size, ptr, reg -9999: st.\size \ptr, \reg - .section __ex_table, "a" - .long 9999b, fixup_st_dst - .previous - .endm - - .text - .global csum_partial_copy_generic - .type csum_partial_copy_generic,"function" - .align 1 -csum_partial_copy_generic: - pushm r4-r7,lr - - /* The inner loop */ -1: sub r10, 4 - brlt 5f -2: ld_src w, r5, r12++ - st_dst w, r11++, r5 - add r9, r5 - acr r9 - sub r10, 4 - brge 2b - - /* return if we had a whole number of words */ -5: sub r10, -4 - brne 7f - -6: mov r12, r9 - popm r4-r7,pc - - /* handle additional bytes at the tail */ -7: mov r5, 0 - mov r4, 32 -8: ld_src ub, r6, r12++ - st_dst b, r11++, r6 - lsl r5, 8 - sub r4, 8 - bfins r5, r6, 0, 8 - sub r10, 1 - brne 8b - - lsl r5, r5, r4 - add r9, r5 - acr r9 - rjmp 6b - - /* Exception handler */ - .section .fixup,"ax" - .align 1 -fixup_ld_src: - mov r9, -EFAULT - cp.w r8, 0 - breq 1f - st.w r8[0], r9 - -1: /* - * TODO: zero the complete destination - computing the rest - * is too much work - */ - - mov r9, 0 - rjmp 6b - -fixup_st_dst: - mov r9, -EFAULT - lddsp r8, sp[20] - cp.w r8, 0 - breq 1f - st.w r8[0], r9 -1: mov r9, 0 - rjmp 6b - - .previous diff --git a/arch/avr32/lib/delay.c b/arch/avr32/lib/delay.c deleted file mode 100644 index c2f4a07dcda1..000000000000 --- a/arch/avr32/lib/delay.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Precise Delay Loops for avr32 - * - * Copyright (C) 1993 Linus Torvalds - * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/delay.h> -#include <linux/module.h> -#include <linux/timex.h> -#include <linux/param.h> -#include <linux/types.h> -#include <linux/init.h> - -#include <asm/processor.h> -#include <asm/sysreg.h> - -int read_current_timer(unsigned long *timer_value) -{ - *timer_value = sysreg_read(COUNT); - return 0; -} - -void __delay(unsigned long loops) -{ - unsigned bclock, now; - - bclock = sysreg_read(COUNT); - do { - now = sysreg_read(COUNT); - } while ((now - bclock) < loops); -} - -inline void __const_udelay(unsigned long xloops) -{ - unsigned long long loops; - - asm("mulu.d %0, %1, %2" - : "=r"(loops) - : "r"(current_cpu_data.loops_per_jiffy * HZ), "r"(xloops)); - __delay(loops >> 32); -} - -void __udelay(unsigned long usecs) -{ - __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ -} - -void __ndelay(unsigned long nsecs) -{ - __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ -} diff --git a/arch/avr32/lib/findbit.S b/arch/avr32/lib/findbit.S deleted file mode 100644 index b93586460be6..000000000000 --- a/arch/avr32/lib/findbit.S +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/linkage.h> - - .text - /* - * unsigned long find_first_zero_bit(const unsigned long *addr, - * unsigned long size) - */ -ENTRY(find_first_zero_bit) - cp.w r11, 0 - reteq r11 - mov r9, r11 -1: ld.w r8, r12[0] - com r8 - brne .L_found - sub r12, -4 - sub r9, 32 - brgt 1b - retal r11 - - /* - * unsigned long find_next_zero_bit(const unsigned long *addr, - * unsigned long size, - * unsigned long offset) - */ -ENTRY(find_next_zero_bit) - lsr r8, r10, 5 - sub r9, r11, r10 - retle r11 - - lsl r8, 2 - add r12, r8 - andl r10, 31, COH - breq 1f - - /* offset is not word-aligned. Handle the first (32 - r10) bits */ - ld.w r8, r12[0] - com r8 - sub r12, -4 - lsr r8, r8, r10 - brne .L_found - - /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ - add r9, r10 - sub r9, 32 - retle r11 - - /* Main loop. offset must be word-aligned */ -1: ld.w r8, r12[0] - com r8 - brne .L_found - sub r12, -4 - sub r9, 32 - brgt 1b - retal r11 - - /* Common return path for when a bit is actually found. */ -.L_found: - brev r8 - clz r10, r8 - rsub r9, r11 - add r10, r9 - - /* XXX: If we don't have to return exactly "size" when the bit - is not found, we may drop this "min" thing */ - min r12, r11, r10 - retal r12 - - /* - * unsigned long find_first_bit(const unsigned long *addr, - * unsigned long size) - */ -ENTRY(find_first_bit) - cp.w r11, 0 - reteq r11 - mov r9, r11 -1: ld.w r8, r12[0] - cp.w r8, 0 - brne .L_found - sub r12, -4 - sub r9, 32 - brgt 1b - retal r11 - - /* - * unsigned long find_next_bit(const unsigned long *addr, - * unsigned long size, - * unsigned long offset) - */ -ENTRY(find_next_bit) - lsr r8, r10, 5 - sub r9, r11, r10 - retle r11 - - lsl r8, 2 - add r12, r8 - andl r10, 31, COH - breq 1f - - /* offset is not word-aligned. Handle the first (32 - r10) bits */ - ld.w r8, r12[0] - sub r12, -4 - lsr r8, r8, r10 - brne .L_found - - /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ - add r9, r10 - sub r9, 32 - retle r11 - - /* Main loop. offset must be word-aligned */ -1: ld.w r8, r12[0] - cp.w r8, 0 - brne .L_found - sub r12, -4 - sub r9, 32 - brgt 1b - retal r11 - -ENTRY(find_next_bit_le) - lsr r8, r10, 5 - sub r9, r11, r10 - retle r11 - - lsl r8, 2 - add r12, r8 - andl r10, 31, COH - breq 1f - - /* offset is not word-aligned. Handle the first (32 - r10) bits */ - ldswp.w r8, r12[0] - sub r12, -4 - lsr r8, r8, r10 - brne .L_found - - /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ - add r9, r10 - sub r9, 32 - retle r11 - - /* Main loop. offset must be word-aligned */ -1: ldswp.w r8, r12[0] - cp.w r8, 0 - brne .L_found - sub r12, -4 - sub r9, 32 - brgt 1b - retal r11 - -ENTRY(find_next_zero_bit_le) - lsr r8, r10, 5 - sub r9, r11, r10 - retle r11 - - lsl r8, 2 - add r12, r8 - andl r10, 31, COH - breq 1f - - /* offset is not word-aligned. Handle the first (32 - r10) bits */ - ldswp.w r8, r12[0] - sub r12, -4 - com r8 - lsr r8, r8, r10 - brne .L_found - - /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */ - add r9, r10 - sub r9, 32 - retle r11 - - /* Main loop. offset must be word-aligned */ -1: ldswp.w r8, r12[0] - com r8 - brne .L_found - sub r12, -4 - sub r9, 32 - brgt 1b - retal r11 diff --git a/arch/avr32/lib/io-readsb.S b/arch/avr32/lib/io-readsb.S deleted file mode 100644 index cb2d86945559..000000000000 --- a/arch/avr32/lib/io-readsb.S +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - .text -.Lnot_word_aligned: -1: ld.ub r8, r12[0] - sub r10, 1 - st.b r11++, r8 - reteq r12 - tst r11, r9 - brne 1b - - /* fall through */ - - .global __raw_readsb - .type __raw_readsb,@function -__raw_readsb: - cp.w r10, 0 - mov r9, 3 - reteq r12 - - tst r11, r9 - brne .Lnot_word_aligned - - sub r10, 4 - brlt 2f - -1: ldins.b r8:t, r12[0] - ldins.b r8:u, r12[0] - ldins.b r8:l, r12[0] - ldins.b r8:b, r12[0] - st.w r11++, r8 - sub r10, 4 - brge 1b - -2: sub r10, -4 - reteq r12 - -3: ld.ub r8, r12[0] - sub r10, 1 - st.b r11++, r8 - brne 3b - - retal r12 diff --git a/arch/avr32/lib/io-readsl.S b/arch/avr32/lib/io-readsl.S deleted file mode 100644 index b103511ed6c4..000000000000 --- a/arch/avr32/lib/io-readsl.S +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - .global __raw_readsl - .type __raw_readsl,@function -__raw_readsl: - cp.w r10, 0 - reteq r12 - - /* - * If r11 isn't properly aligned, we might get an exception on - * some implementations. But there's not much we can do about it. - */ -1: ld.w r8, r12[0] - sub r10, 1 - st.w r11++, r8 - brne 1b - - retal r12 diff --git a/arch/avr32/lib/io-readsw.S b/arch/avr32/lib/io-readsw.S deleted file mode 100644 index 456be9909027..000000000000 --- a/arch/avr32/lib/io-readsw.S +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -.Lnot_word_aligned: - /* - * Bad alignment will cause a hardware exception, which is as - * good as anything. No need for us to check for proper alignment. - */ - ld.uh r8, r12[0] - sub r10, 1 - st.h r11++, r8 - - /* fall through */ - - .global __raw_readsw - .type __raw_readsw,@function -__raw_readsw: - cp.w r10, 0 - reteq r12 - mov r9, 3 - tst r11, r9 - brne .Lnot_word_aligned - - sub r10, 2 - brlt 2f - -1: ldins.h r8:t, r12[0] - ldins.h r8:b, r12[0] - st.w r11++, r8 - sub r10, 2 - brge 1b - -2: sub r10, -2 - reteq r12 - - ld.uh r8, r12[0] - st.h r11++, r8 - retal r12 diff --git a/arch/avr32/lib/io-writesb.S b/arch/avr32/lib/io-writesb.S deleted file mode 100644 index b4ebaacccf68..000000000000 --- a/arch/avr32/lib/io-writesb.S +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - .text -.Lnot_word_aligned: -1: ld.ub r8, r11++ - sub r10, 1 - st.b r12[0], r8 - reteq r12 - tst r11, r9 - brne 1b - - /* fall through */ - - .global __raw_writesb - .type __raw_writesb,@function -__raw_writesb: - cp.w r10, 0 - mov r9, 3 - reteq r12 - - tst r11, r9 - brne .Lnot_word_aligned - - sub r10, 4 - brlt 2f - -1: ld.w r8, r11++ - bfextu r9, r8, 24, 8 - st.b r12[0], r9 - bfextu r9, r8, 16, 8 - st.b r12[0], r9 - bfextu r9, r8, 8, 8 - st.b r12[0], r9 - st.b r12[0], r8 - sub r10, 4 - brge 1b - -2: sub r10, -4 - reteq r12 - -3: ld.ub r8, r11++ - sub r10, 1 - st.b r12[0], r8 - brne 3b - - retal r12 diff --git a/arch/avr32/lib/io-writesl.S b/arch/avr32/lib/io-writesl.S deleted file mode 100644 index 22138b3a16e5..000000000000 --- a/arch/avr32/lib/io-writesl.S +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - .global __raw_writesl - .type __raw_writesl,@function -__raw_writesl: - cp.w r10, 0 - reteq r12 - -1: ld.w r8, r11++ - sub r10, 1 - st.w r12[0], r8 - brne 1b - - retal r12 diff --git a/arch/avr32/lib/io-writesw.S b/arch/avr32/lib/io-writesw.S deleted file mode 100644 index 8c4a53f1c52a..000000000000 --- a/arch/avr32/lib/io-writesw.S +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -.Lnot_word_aligned: - ld.uh r8, r11++ - sub r10, 1 - st.h r12[0], r8 - - .global __raw_writesw - .type __raw_writesw,@function -__raw_writesw: - cp.w r10, 0 - mov r9, 3 - reteq r12 - tst r11, r9 - brne .Lnot_word_aligned - - sub r10, 2 - brlt 2f - -1: ld.w r8, r11++ - bfextu r9, r8, 16, 16 - st.h r12[0], r9 - st.h r12[0], r8 - sub r10, 2 - brge 1b - -2: sub r10, -2 - reteq r12 - - ld.uh r8, r11++ - st.h r12[0], r8 - retal r12 diff --git a/arch/avr32/lib/memcpy.S b/arch/avr32/lib/memcpy.S deleted file mode 100644 index c2ca49d705af..000000000000 --- a/arch/avr32/lib/memcpy.S +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - /* - * void *memcpy(void *to, const void *from, unsigned long n) - * - * This implementation does word-aligned loads in the main loop, - * possibly sacrificing alignment of stores. - * - * Hopefully, in most cases, both "to" and "from" will be - * word-aligned to begin with. - */ - .text - .global memcpy - .type memcpy, @function -memcpy: - mov r9, r11 - andl r9, 3, COH - brne 1f - - /* At this point, "from" is word-aligned */ -2: mov r9, r12 -5: sub r10, 4 - brlt 4f - -3: ld.w r8, r11++ - sub r10, 4 - st.w r12++, r8 - brge 3b - -4: neg r10 - reteq r9 - - /* Handle unaligned count */ - lsl r10, 2 - add pc, pc, r10 - ld.ub r8, r11++ - st.b r12++, r8 - ld.ub r8, r11++ - st.b r12++, r8 - ld.ub r8, r11++ - st.b r12++, r8 - retal r9 - - /* Handle unaligned "from" pointer */ -1: sub r10, 4 - movlt r9, r12 - brlt 4b - add r10, r9 - lsl r9, 2 - add pc, pc, r9 - ld.ub r8, r11++ - st.b r12++, r8 - ld.ub r8, r11++ - st.b r12++, r8 - ld.ub r8, r11++ - st.b r12++, r8 - mov r8, r12 - add pc, pc, r9 - sub r8, 1 - nop - sub r8, 1 - nop - sub r8, 1 - nop - mov r9, r8 - rjmp 5b diff --git a/arch/avr32/lib/memset.S b/arch/avr32/lib/memset.S deleted file mode 100644 index 40da32c0480c..000000000000 --- a/arch/avr32/lib/memset.S +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * Based on linux/arch/arm/lib/memset.S - * Copyright (C) 1995-2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * ASM optimised string functions - */ -#include <asm/asm.h> - - /* - * r12: void *b - * r11: int c - * r10: size_t len - * - * Returns b in r12 - */ - .text - .global memset - .type memset, @function - .align 5 -memset: - mov r9, r12 - mov r8, r12 - or r11, r11, r11 << 8 - andl r9, 3, COH - brne 1f - -2: or r11, r11, r11 << 16 - sub r10, 4 - brlt 5f - - /* Let's do some real work */ -4: st.w r8++, r11 - sub r10, 4 - brge 4b - - /* - * When we get here, we've got less than 4 bytes to set. r10 - * might be negative. - */ -5: sub r10, -4 - reteq r12 - - /* Fastpath ends here, exactly 32 bytes from memset */ - - /* Handle unaligned count or pointer */ - bld r10, 1 - brcc 6f - st.b r8++, r11 - st.b r8++, r11 - bld r10, 0 - retcc r12 -6: st.b r8++, r11 - retal r12 - - /* Handle unaligned pointer */ -1: sub r10, 4 - brlt 5b - add r10, r9 - lsl r9, 1 - add pc, r9 - st.b r8++, r11 - st.b r8++, r11 - st.b r8++, r11 - rjmp 2b - - .size memset, . - memset diff --git a/arch/avr32/lib/strncpy_from_user.S b/arch/avr32/lib/strncpy_from_user.S deleted file mode 100644 index 72bd50599ec6..000000000000 --- a/arch/avr32/lib/strncpy_from_user.S +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copy to/from userspace with optional address space checking. - * - * Copyright 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/errno.h> - -#include <asm/page.h> -#include <asm/thread_info.h> -#include <asm/asm.h> - - /* - * long strncpy_from_user(char *dst, const char *src, long count) - * - * On success, returns the length of the string, not including - * the terminating NUL. - * - * If the string is longer than count, returns count - * - * If userspace access fails, returns -EFAULT - */ - .text - .align 1 - .global strncpy_from_user - .type strncpy_from_user, "function" -strncpy_from_user: - mov r9, -EFAULT - branch_if_kernel r8, __strncpy_from_user - ret_if_privileged r8, r11, r10, r9 - - .global __strncpy_from_user - .type __strncpy_from_user, "function" -__strncpy_from_user: - cp.w r10, 0 - reteq 0 - - mov r9, r10 - -1: ld.ub r8, r11++ - st.b r12++, r8 - cp.w r8, 0 - breq 2f - sub r9, 1 - brne 1b - -2: sub r10, r9 - retal r10 - - .section .fixup, "ax" - .align 1 -3: mov r12, -EFAULT - retal r12 - - .section __ex_table, "a" - .align 2 - .long 1b, 3b diff --git a/arch/avr32/lib/strnlen_user.S b/arch/avr32/lib/strnlen_user.S deleted file mode 100644 index e46f4724962b..000000000000 --- a/arch/avr32/lib/strnlen_user.S +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copy to/from userspace with optional address space checking. - * - * Copyright 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <asm/page.h> -#include <asm/thread_info.h> -#include <asm/processor.h> -#include <asm/asm.h> - - .text - .align 1 - .global strnlen_user - .type strnlen_user, "function" -strnlen_user: - branch_if_kernel r8, __strnlen_user - sub r8, r11, 1 - add r8, r12 - retcs 0 - brmi adjust_length /* do a closer inspection */ - - .global __strnlen_user - .type __strnlen_user, "function" -__strnlen_user: - mov r10, r12 - -10: ld.ub r8, r12++ - cp.w r8, 0 - breq 2f - sub r11, 1 - brne 10b - - sub r12, -1 -2: sub r12, r10 - retal r12 - - - .type adjust_length, "function" -adjust_length: - cp.w r12, 0 /* addr must always be < TASK_SIZE */ - retmi 0 - - pushm lr - lddpc lr, _task_size - sub r11, lr, r12 - mov r9, r11 - call __strnlen_user - cp.w r12, r9 - brgt 1f - popm pc -1: popm pc, r12=0 - - .align 2 -_task_size: - .long TASK_SIZE - - .section .fixup, "ax" - .align 1 -19: retal 0 - - .section __ex_table, "a" - .align 2 - .long 10b, 19b diff --git a/arch/avr32/mach-at32ap/Kconfig b/arch/avr32/mach-at32ap/Kconfig deleted file mode 100644 index a7bbcc82058e..000000000000 --- a/arch/avr32/mach-at32ap/Kconfig +++ /dev/null @@ -1,31 +0,0 @@ -if PLATFORM_AT32AP - -menu "Atmel AVR32 AP options" - -choice - prompt "AT32AP700x static memory bus width" - depends on CPU_AT32AP700X - default AP700X_16_BIT_SMC - help - Define the width of the AP7000 external static memory interface. - This is used to determine how to mangle the address and/or data - when doing little-endian port access. - - The current code can only support a single external memory bus - width for all chip selects, excluding the flash (which is using - raw access and is thus not affected by any of this.) - -config AP700X_32_BIT_SMC - bool "32 bit" - -config AP700X_16_BIT_SMC - bool "16 bit" - -config AP700X_8_BIT_SMC - bool "8 bit" - -endchoice - -endmenu - -endif # PLATFORM_AT32AP diff --git a/arch/avr32/mach-at32ap/Makefile b/arch/avr32/mach-at32ap/Makefile deleted file mode 100644 index fc09ec4bc725..000000000000 --- a/arch/avr32/mach-at32ap/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -obj-y += pdc.o clock.o intc.o extint.o pio.o hsmc.o -obj-y += hmatrix.o -obj-$(CONFIG_CPU_AT32AP700X) += at32ap700x.o pm-at32ap700x.o -obj-$(CONFIG_PM) += pm.o - -ifeq ($(CONFIG_PM_DEBUG),y) -CFLAGS_pm.o += -DDEBUG -endif diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c deleted file mode 100644 index 00d6dcc1d9b6..000000000000 --- a/arch/avr32/mach-at32ap/at32ap700x.c +++ /dev/null @@ -1,2368 +0,0 @@ -/* - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/platform_data/dma-dw.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/dma-mapping.h> -#include <linux/slab.h> -#include <linux/gpio.h> -#include <linux/spi/spi.h> -#include <linux/usb/atmel_usba_udc.h> - -#include <linux/atmel-mci.h> - -#include <asm/io.h> -#include <asm/irq.h> - -#include <mach/at32ap700x.h> -#include <mach/board.h> -#include <mach/hmatrix.h> -#include <mach/portmux.h> -#include <mach/sram.h> - -#include <sound/atmel-abdac.h> -#include <sound/atmel-ac97c.h> - -#include <video/atmel_lcdc.h> - -#include "clock.h" -#include "pio.h" -#include "pm.h" - - -#define PBMEM(base) \ - { \ - .start = base, \ - .end = base + 0x3ff, \ - .flags = IORESOURCE_MEM, \ - } -#define IRQ(num) \ - { \ - .start = num, \ - .end = num, \ - .flags = IORESOURCE_IRQ, \ - } -#define NAMED_IRQ(num, _name) \ - { \ - .start = num, \ - .end = num, \ - .name = _name, \ - .flags = IORESOURCE_IRQ, \ - } - -/* REVISIT these assume *every* device supports DMA, but several - * don't ... tc, smc, pio, rtc, watchdog, pwm, ps2, and more. - */ -#define DEFINE_DEV(_name, _id) \ -static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32); \ -static struct platform_device _name##_id##_device = { \ - .name = #_name, \ - .id = _id, \ - .dev = { \ - .dma_mask = &_name##_id##_dma_mask, \ - .coherent_dma_mask = DMA_BIT_MASK(32), \ - }, \ - .resource = _name##_id##_resource, \ - .num_resources = ARRAY_SIZE(_name##_id##_resource), \ -} -#define DEFINE_DEV_DATA(_name, _id) \ -static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32); \ -static struct platform_device _name##_id##_device = { \ - .name = #_name, \ - .id = _id, \ - .dev = { \ - .dma_mask = &_name##_id##_dma_mask, \ - .platform_data = &_name##_id##_data, \ - .coherent_dma_mask = DMA_BIT_MASK(32), \ - }, \ - .resource = _name##_id##_resource, \ - .num_resources = ARRAY_SIZE(_name##_id##_resource), \ -} - -#define select_peripheral(port, pin_mask, periph, flags) \ - at32_select_periph(GPIO_##port##_BASE, pin_mask, \ - GPIO_##periph, flags) - -#define DEV_CLK(_name, devname, bus, _index) \ -static struct clk devname##_##_name = { \ - .name = #_name, \ - .dev = &devname##_device.dev, \ - .parent = &bus##_clk, \ - .mode = bus##_clk_mode, \ - .get_rate = bus##_clk_get_rate, \ - .index = _index, \ -} - -static DEFINE_SPINLOCK(pm_lock); - -static struct clk osc0; -static struct clk osc1; - -static unsigned long osc_get_rate(struct clk *clk) -{ - return at32_board_osc_rates[clk->index]; -} - -static unsigned long pll_get_rate(struct clk *clk, unsigned long control) -{ - unsigned long div, mul, rate; - - div = PM_BFEXT(PLLDIV, control) + 1; - mul = PM_BFEXT(PLLMUL, control) + 1; - - rate = clk->parent->get_rate(clk->parent); - rate = (rate + div / 2) / div; - rate *= mul; - - return rate; -} - -static long pll_set_rate(struct clk *clk, unsigned long rate, - u32 *pll_ctrl) -{ - unsigned long mul; - unsigned long mul_best_fit = 0; - unsigned long div; - unsigned long div_min; - unsigned long div_max; - unsigned long div_best_fit = 0; - unsigned long base; - unsigned long pll_in; - unsigned long actual = 0; - unsigned long rate_error; - unsigned long rate_error_prev = ~0UL; - u32 ctrl; - - /* Rate must be between 80 MHz and 200 Mhz. */ - if (rate < 80000000UL || rate > 200000000UL) - return -EINVAL; - - ctrl = PM_BF(PLLOPT, 4); - base = clk->parent->get_rate(clk->parent); - - /* PLL input frequency must be between 6 MHz and 32 MHz. */ - div_min = DIV_ROUND_UP(base, 32000000UL); - div_max = base / 6000000UL; - - if (div_max < div_min) - return -EINVAL; - - for (div = div_min; div <= div_max; div++) { - pll_in = (base + div / 2) / div; - mul = (rate + pll_in / 2) / pll_in; - - if (mul == 0) - continue; - - actual = pll_in * mul; - rate_error = abs(actual - rate); - - if (rate_error < rate_error_prev) { - mul_best_fit = mul; - div_best_fit = div; - rate_error_prev = rate_error; - } - - if (rate_error == 0) - break; - } - - if (div_best_fit == 0) - return -EINVAL; - - ctrl |= PM_BF(PLLMUL, mul_best_fit - 1); - ctrl |= PM_BF(PLLDIV, div_best_fit - 1); - ctrl |= PM_BF(PLLCOUNT, 16); - - if (clk->parent == &osc1) - ctrl |= PM_BIT(PLLOSC); - - *pll_ctrl = ctrl; - - return actual; -} - -static unsigned long pll0_get_rate(struct clk *clk) -{ - u32 control; - - control = pm_readl(PLL0); - - return pll_get_rate(clk, control); -} - -static void pll1_mode(struct clk *clk, int enabled) -{ - unsigned long timeout; - u32 status; - u32 ctrl; - - ctrl = pm_readl(PLL1); - - if (enabled) { - if (!PM_BFEXT(PLLMUL, ctrl) && !PM_BFEXT(PLLDIV, ctrl)) { - pr_debug("clk %s: failed to enable, rate not set\n", - clk->name); - return; - } - - ctrl |= PM_BIT(PLLEN); - pm_writel(PLL1, ctrl); - - /* Wait for PLL lock. */ - for (timeout = 10000; timeout; timeout--) { - status = pm_readl(ISR); - if (status & PM_BIT(LOCK1)) - break; - udelay(10); - } - - if (!(status & PM_BIT(LOCK1))) - printk(KERN_ERR "clk %s: timeout waiting for lock\n", - clk->name); - } else { - ctrl &= ~PM_BIT(PLLEN); - pm_writel(PLL1, ctrl); - } -} - -static unsigned long pll1_get_rate(struct clk *clk) -{ - u32 control; - - control = pm_readl(PLL1); - - return pll_get_rate(clk, control); -} - -static long pll1_set_rate(struct clk *clk, unsigned long rate, int apply) -{ - u32 ctrl = 0; - unsigned long actual_rate; - - actual_rate = pll_set_rate(clk, rate, &ctrl); - - if (apply) { - if (actual_rate != rate) - return -EINVAL; - if (clk->users > 0) - return -EBUSY; - pr_debug(KERN_INFO "clk %s: new rate %lu (actual rate %lu)\n", - clk->name, rate, actual_rate); - pm_writel(PLL1, ctrl); - } - - return actual_rate; -} - -static int pll1_set_parent(struct clk *clk, struct clk *parent) -{ - u32 ctrl; - - if (clk->users > 0) - return -EBUSY; - - ctrl = pm_readl(PLL1); - WARN_ON(ctrl & PM_BIT(PLLEN)); - - if (parent == &osc0) - ctrl &= ~PM_BIT(PLLOSC); - else if (parent == &osc1) - ctrl |= PM_BIT(PLLOSC); - else - return -EINVAL; - - pm_writel(PLL1, ctrl); - clk->parent = parent; - - return 0; -} - -/* - * The AT32AP7000 has five primary clock sources: One 32kHz - * oscillator, two crystal oscillators and two PLLs. - */ -static struct clk osc32k = { - .name = "osc32k", - .get_rate = osc_get_rate, - .users = 1, - .index = 0, -}; -static struct clk osc0 = { - .name = "osc0", - .get_rate = osc_get_rate, - .users = 1, - .index = 1, -}; -static struct clk osc1 = { - .name = "osc1", - .get_rate = osc_get_rate, - .index = 2, -}; -static struct clk pll0 = { - .name = "pll0", - .get_rate = pll0_get_rate, - .parent = &osc0, -}; -static struct clk pll1 = { - .name = "pll1", - .mode = pll1_mode, - .get_rate = pll1_get_rate, - .set_rate = pll1_set_rate, - .set_parent = pll1_set_parent, - .parent = &osc0, -}; - -/* - * The main clock can be either osc0 or pll0. The boot loader may - * have chosen one for us, so we don't really know which one until we - * have a look at the SM. - */ -static struct clk *main_clock; - -/* - * Synchronous clocks are generated from the main clock. The clocks - * must satisfy the constraint - * fCPU >= fHSB >= fPB - * i.e. each clock must not be faster than its parent. - */ -static unsigned long bus_clk_get_rate(struct clk *clk, unsigned int shift) -{ - return main_clock->get_rate(main_clock) >> shift; -}; - -static void cpu_clk_mode(struct clk *clk, int enabled) -{ - unsigned long flags; - u32 mask; - - spin_lock_irqsave(&pm_lock, flags); - mask = pm_readl(CPU_MASK); - if (enabled) - mask |= 1 << clk->index; - else - mask &= ~(1 << clk->index); - pm_writel(CPU_MASK, mask); - spin_unlock_irqrestore(&pm_lock, flags); -} - -static unsigned long cpu_clk_get_rate(struct clk *clk) -{ - unsigned long cksel, shift = 0; - - cksel = pm_readl(CKSEL); - if (cksel & PM_BIT(CPUDIV)) - shift = PM_BFEXT(CPUSEL, cksel) + 1; - - return bus_clk_get_rate(clk, shift); -} - -static long cpu_clk_set_rate(struct clk *clk, unsigned long rate, int apply) -{ - u32 control; - unsigned long parent_rate, child_div, actual_rate, div; - - parent_rate = clk->parent->get_rate(clk->parent); - control = pm_readl(CKSEL); - - if (control & PM_BIT(HSBDIV)) - child_div = 1 << (PM_BFEXT(HSBSEL, control) + 1); - else - child_div = 1; - - if (rate > 3 * (parent_rate / 4) || child_div == 1) { - actual_rate = parent_rate; - control &= ~PM_BIT(CPUDIV); - } else { - unsigned int cpusel; - div = (parent_rate + rate / 2) / rate; - if (div > child_div) - div = child_div; - cpusel = (div > 1) ? (fls(div) - 2) : 0; - control = PM_BIT(CPUDIV) | PM_BFINS(CPUSEL, cpusel, control); - actual_rate = parent_rate / (1 << (cpusel + 1)); - } - - pr_debug("clk %s: new rate %lu (actual rate %lu)\n", - clk->name, rate, actual_rate); - - if (apply) - pm_writel(CKSEL, control); - - return actual_rate; -} - -static void hsb_clk_mode(struct clk *clk, int enabled) -{ - unsigned long flags; - u32 mask; - - spin_lock_irqsave(&pm_lock, flags); - mask = pm_readl(HSB_MASK); - if (enabled) - mask |= 1 << clk->index; - else - mask &= ~(1 << clk->index); - pm_writel(HSB_MASK, mask); - spin_unlock_irqrestore(&pm_lock, flags); -} - -static unsigned long hsb_clk_get_rate(struct clk *clk) -{ - unsigned long cksel, shift = 0; - - cksel = pm_readl(CKSEL); - if (cksel & PM_BIT(HSBDIV)) - shift = PM_BFEXT(HSBSEL, cksel) + 1; - - return bus_clk_get_rate(clk, shift); -} - -void pba_clk_mode(struct clk *clk, int enabled) -{ - unsigned long flags; - u32 mask; - - spin_lock_irqsave(&pm_lock, flags); - mask = pm_readl(PBA_MASK); - if (enabled) - mask |= 1 << clk->index; - else - mask &= ~(1 << clk->index); - pm_writel(PBA_MASK, mask); - spin_unlock_irqrestore(&pm_lock, flags); -} - -unsigned long pba_clk_get_rate(struct clk *clk) -{ - unsigned long cksel, shift = 0; - - cksel = pm_readl(CKSEL); - if (cksel & PM_BIT(PBADIV)) - shift = PM_BFEXT(PBASEL, cksel) + 1; - - return bus_clk_get_rate(clk, shift); -} - -static void pbb_clk_mode(struct clk *clk, int enabled) -{ - unsigned long flags; - u32 mask; - - spin_lock_irqsave(&pm_lock, flags); - mask = pm_readl(PBB_MASK); - if (enabled) - mask |= 1 << clk->index; - else - mask &= ~(1 << clk->index); - pm_writel(PBB_MASK, mask); - spin_unlock_irqrestore(&pm_lock, flags); -} - -static unsigned long pbb_clk_get_rate(struct clk *clk) -{ - unsigned long cksel, shift = 0; - - cksel = pm_readl(CKSEL); - if (cksel & PM_BIT(PBBDIV)) - shift = PM_BFEXT(PBBSEL, cksel) + 1; - - return bus_clk_get_rate(clk, shift); -} - -static struct clk cpu_clk = { - .name = "cpu", - .get_rate = cpu_clk_get_rate, - .set_rate = cpu_clk_set_rate, - .users = 1, -}; -static struct clk hsb_clk = { - .name = "hsb", - .parent = &cpu_clk, - .get_rate = hsb_clk_get_rate, -}; -static struct clk pba_clk = { - .name = "pba", - .parent = &hsb_clk, - .mode = hsb_clk_mode, - .get_rate = pba_clk_get_rate, - .index = 1, -}; -static struct clk pbb_clk = { - .name = "pbb", - .parent = &hsb_clk, - .mode = hsb_clk_mode, - .get_rate = pbb_clk_get_rate, - .users = 1, - .index = 2, -}; - -/* -------------------------------------------------------------------- - * Generic Clock operations - * -------------------------------------------------------------------- */ - -static void genclk_mode(struct clk *clk, int enabled) -{ - u32 control; - - control = pm_readl(GCCTRL(clk->index)); - if (enabled) - control |= PM_BIT(CEN); - else - control &= ~PM_BIT(CEN); - pm_writel(GCCTRL(clk->index), control); -} - -static unsigned long genclk_get_rate(struct clk *clk) -{ - u32 control; - unsigned long div = 1; - - control = pm_readl(GCCTRL(clk->index)); - if (control & PM_BIT(DIVEN)) - div = 2 * (PM_BFEXT(DIV, control) + 1); - - return clk->parent->get_rate(clk->parent) / div; -} - -static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply) -{ - u32 control; - unsigned long parent_rate, actual_rate, div; - - parent_rate = clk->parent->get_rate(clk->parent); - control = pm_readl(GCCTRL(clk->index)); - - if (rate > 3 * parent_rate / 4) { - actual_rate = parent_rate; - control &= ~PM_BIT(DIVEN); - } else { - div = (parent_rate + rate) / (2 * rate) - 1; - control = PM_BFINS(DIV, div, control) | PM_BIT(DIVEN); - actual_rate = parent_rate / (2 * (div + 1)); - } - - dev_dbg(clk->dev, "clk %s: new rate %lu (actual rate %lu)\n", - clk->name, rate, actual_rate); - - if (apply) - pm_writel(GCCTRL(clk->index), control); - - return actual_rate; -} - -int genclk_set_parent(struct clk *clk, struct clk *parent) -{ - u32 control; - - dev_dbg(clk->dev, "clk %s: new parent %s (was %s)\n", - clk->name, parent->name, clk->parent->name); - - control = pm_readl(GCCTRL(clk->index)); - - if (parent == &osc1 || parent == &pll1) - control |= PM_BIT(OSCSEL); - else if (parent == &osc0 || parent == &pll0) - control &= ~PM_BIT(OSCSEL); - else - return -EINVAL; - - if (parent == &pll0 || parent == &pll1) - control |= PM_BIT(PLLSEL); - else - control &= ~PM_BIT(PLLSEL); - - pm_writel(GCCTRL(clk->index), control); - clk->parent = parent; - - return 0; -} - -static void __init genclk_init_parent(struct clk *clk) -{ - u32 control; - struct clk *parent; - - BUG_ON(clk->index > 7); - - control = pm_readl(GCCTRL(clk->index)); - if (control & PM_BIT(OSCSEL)) - parent = (control & PM_BIT(PLLSEL)) ? &pll1 : &osc1; - else - parent = (control & PM_BIT(PLLSEL)) ? &pll0 : &osc0; - - clk->parent = parent; -} - -static struct resource dw_dmac0_resource[] = { - PBMEM(0xff200000), - IRQ(2), -}; -DEFINE_DEV(dw_dmac, 0); -DEV_CLK(hclk, dw_dmac0, hsb, 10); - -/* -------------------------------------------------------------------- - * System peripherals - * -------------------------------------------------------------------- */ -static struct resource at32_pm0_resource[] = { - { - .start = 0xfff00000, - .end = 0xfff0007f, - .flags = IORESOURCE_MEM, - }, - IRQ(20), -}; - -static struct resource at32ap700x_rtc0_resource[] = { - { - .start = 0xfff00080, - .end = 0xfff000af, - .flags = IORESOURCE_MEM, - }, - IRQ(21), -}; - -static struct resource at32_wdt0_resource[] = { - { - .start = 0xfff000b0, - .end = 0xfff000cf, - .flags = IORESOURCE_MEM, - }, -}; - -static struct resource at32_eic0_resource[] = { - { - .start = 0xfff00100, - .end = 0xfff0013f, - .flags = IORESOURCE_MEM, - }, - IRQ(19), -}; - -DEFINE_DEV(at32_pm, 0); -DEFINE_DEV(at32ap700x_rtc, 0); -DEFINE_DEV(at32_wdt, 0); -DEFINE_DEV(at32_eic, 0); - -/* - * Peripheral clock for PM, RTC, WDT and EIC. PM will ensure that this - * is always running. - */ -static struct clk at32_pm_pclk = { - .name = "pclk", - .dev = &at32_pm0_device.dev, - .parent = &pbb_clk, - .mode = pbb_clk_mode, - .get_rate = pbb_clk_get_rate, - .users = 1, - .index = 0, -}; - -static struct resource intc0_resource[] = { - PBMEM(0xfff00400), -}; -struct platform_device at32_intc0_device = { - .name = "intc", - .id = 0, - .resource = intc0_resource, - .num_resources = ARRAY_SIZE(intc0_resource), -}; -DEV_CLK(pclk, at32_intc0, pbb, 1); - -static struct clk ebi_clk = { - .name = "ebi", - .parent = &hsb_clk, - .mode = hsb_clk_mode, - .get_rate = hsb_clk_get_rate, - .users = 1, -}; -static struct clk hramc_clk = { - .name = "hramc", - .parent = &hsb_clk, - .mode = hsb_clk_mode, - .get_rate = hsb_clk_get_rate, - .users = 1, - .index = 3, -}; -static struct clk sdramc_clk = { - .name = "sdramc_clk", - .parent = &pbb_clk, - .mode = pbb_clk_mode, - .get_rate = pbb_clk_get_rate, - .users = 1, - .index = 14, -}; - -static struct resource smc0_resource[] = { - PBMEM(0xfff03400), -}; -DEFINE_DEV(smc, 0); -DEV_CLK(pclk, smc0, pbb, 13); -DEV_CLK(mck, smc0, hsb, 0); - -static struct platform_device pdc_device = { - .name = "pdc", - .id = 0, -}; -DEV_CLK(hclk, pdc, hsb, 4); -DEV_CLK(pclk, pdc, pba, 16); - -static struct clk pico_clk = { - .name = "pico", - .parent = &cpu_clk, - .mode = cpu_clk_mode, - .get_rate = cpu_clk_get_rate, - .users = 1, -}; - -/* -------------------------------------------------------------------- - * HMATRIX - * -------------------------------------------------------------------- */ - -struct clk at32_hmatrix_clk = { - .name = "hmatrix_clk", - .parent = &pbb_clk, - .mode = pbb_clk_mode, - .get_rate = pbb_clk_get_rate, - .index = 2, - .users = 1, -}; - -/* - * Set bits in the HMATRIX Special Function Register (SFR) used by the - * External Bus Interface (EBI). This can be used to enable special - * features like CompactFlash support, NAND Flash support, etc. on - * certain chipselects. - */ -static inline void set_ebi_sfr_bits(u32 mask) -{ - hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, mask); -} - -/* -------------------------------------------------------------------- - * Timer/Counter (TC) - * -------------------------------------------------------------------- */ - -static struct resource at32_tcb0_resource[] = { - PBMEM(0xfff00c00), - IRQ(22), -}; -static struct platform_device at32_tcb0_device = { - .name = "atmel_tcb", - .id = 0, - .resource = at32_tcb0_resource, - .num_resources = ARRAY_SIZE(at32_tcb0_resource), -}; -DEV_CLK(t0_clk, at32_tcb0, pbb, 3); - -static struct resource at32_tcb1_resource[] = { - PBMEM(0xfff01000), - IRQ(23), -}; -static struct platform_device at32_tcb1_device = { - .name = "atmel_tcb", - .id = 1, - .resource = at32_tcb1_resource, - .num_resources = ARRAY_SIZE(at32_tcb1_resource), -}; -DEV_CLK(t0_clk, at32_tcb1, pbb, 4); - -/* -------------------------------------------------------------------- - * PIO - * -------------------------------------------------------------------- */ - -static struct resource pio0_resource[] = { - PBMEM(0xffe02800), - IRQ(13), -}; -DEFINE_DEV(pio, 0); -DEV_CLK(mck, pio0, pba, 10); - -static struct resource pio1_resource[] = { - PBMEM(0xffe02c00), - IRQ(14), -}; -DEFINE_DEV(pio, 1); -DEV_CLK(mck, pio1, pba, 11); - -static struct resource pio2_resource[] = { - PBMEM(0xffe03000), - IRQ(15), -}; -DEFINE_DEV(pio, 2); -DEV_CLK(mck, pio2, pba, 12); - -static struct resource pio3_resource[] = { - PBMEM(0xffe03400), - IRQ(16), -}; -DEFINE_DEV(pio, 3); -DEV_CLK(mck, pio3, pba, 13); - -static struct resource pio4_resource[] = { - PBMEM(0xffe03800), - IRQ(17), -}; -DEFINE_DEV(pio, 4); -DEV_CLK(mck, pio4, pba, 14); - -static int __init system_device_init(void) -{ - platform_device_register(&at32_pm0_device); - platform_device_register(&at32_intc0_device); - platform_device_register(&at32ap700x_rtc0_device); - platform_device_register(&at32_wdt0_device); - platform_device_register(&at32_eic0_device); - platform_device_register(&smc0_device); - platform_device_register(&pdc_device); - platform_device_register(&dw_dmac0_device); - - platform_device_register(&at32_tcb0_device); - platform_device_register(&at32_tcb1_device); - - platform_device_register(&pio0_device); - platform_device_register(&pio1_device); - platform_device_register(&pio2_device); - platform_device_register(&pio3_device); - platform_device_register(&pio4_device); - - return 0; -} -core_initcall(system_device_init); - -/* -------------------------------------------------------------------- - * PSIF - * -------------------------------------------------------------------- */ -static struct resource atmel_psif0_resource[] __initdata = { - { - .start = 0xffe03c00, - .end = 0xffe03cff, - .flags = IORESOURCE_MEM, - }, - IRQ(18), -}; -static struct clk atmel_psif0_pclk = { - .name = "pclk", - .parent = &pba_clk, - .mode = pba_clk_mode, - .get_rate = pba_clk_get_rate, - .index = 15, -}; - -static struct resource atmel_psif1_resource[] __initdata = { - { - .start = 0xffe03d00, - .end = 0xffe03dff, - .flags = IORESOURCE_MEM, - }, - IRQ(18), -}; -static struct clk atmel_psif1_pclk = { - .name = "pclk", - .parent = &pba_clk, - .mode = pba_clk_mode, - .get_rate = pba_clk_get_rate, - .index = 15, -}; - -struct platform_device *__init at32_add_device_psif(unsigned int id) -{ - struct platform_device *pdev; - u32 pin_mask; - - if (!(id == 0 || id == 1)) - return NULL; - - pdev = platform_device_alloc("atmel_psif", id); - if (!pdev) - return NULL; - - switch (id) { - case 0: - pin_mask = (1 << 8) | (1 << 9); /* CLOCK & DATA */ - - if (platform_device_add_resources(pdev, atmel_psif0_resource, - ARRAY_SIZE(atmel_psif0_resource))) - goto err_add_resources; - atmel_psif0_pclk.dev = &pdev->dev; - select_peripheral(PIOA, pin_mask, PERIPH_A, 0); - break; - case 1: - pin_mask = (1 << 11) | (1 << 12); /* CLOCK & DATA */ - - if (platform_device_add_resources(pdev, atmel_psif1_resource, - ARRAY_SIZE(atmel_psif1_resource))) - goto err_add_resources; - atmel_psif1_pclk.dev = &pdev->dev; - select_peripheral(PIOB, pin_mask, PERIPH_A, 0); - break; - default: - return NULL; - } - - platform_device_add(pdev); - return pdev; - -err_add_resources: - platform_device_put(pdev); - return NULL; -} - -/* -------------------------------------------------------------------- - * USART - * -------------------------------------------------------------------- */ - -static struct atmel_uart_data atmel_usart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; -static struct resource atmel_usart0_resource[] = { - PBMEM(0xffe00c00), - IRQ(6), -}; -DEFINE_DEV_DATA(atmel_usart, 0); -DEV_CLK(usart, atmel_usart0, pba, 3); - -static struct atmel_uart_data atmel_usart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; -static struct resource atmel_usart1_resource[] = { - PBMEM(0xffe01000), - IRQ(7), -}; -DEFINE_DEV_DATA(atmel_usart, 1); -DEV_CLK(usart, atmel_usart1, pba, 4); - -static struct atmel_uart_data atmel_usart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; -static struct resource atmel_usart2_resource[] = { - PBMEM(0xffe01400), - IRQ(8), -}; -DEFINE_DEV_DATA(atmel_usart, 2); -DEV_CLK(usart, atmel_usart2, pba, 5); - -static struct atmel_uart_data atmel_usart3_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; -static struct resource atmel_usart3_resource[] = { - PBMEM(0xffe01800), - IRQ(9), -}; -DEFINE_DEV_DATA(atmel_usart, 3); -DEV_CLK(usart, atmel_usart3, pba, 6); - -static inline void configure_usart0_pins(int flags) -{ - u32 pin_mask = (1 << 8) | (1 << 9); /* RXD & TXD */ - if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 6); - if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 7); - if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 10); - - select_peripheral(PIOA, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP); -} - -static inline void configure_usart1_pins(int flags) -{ - u32 pin_mask = (1 << 17) | (1 << 18); /* RXD & TXD */ - if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 19); - if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 20); - if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 16); - - select_peripheral(PIOA, pin_mask, PERIPH_A, AT32_GPIOF_PULLUP); -} - -static inline void configure_usart2_pins(int flags) -{ - u32 pin_mask = (1 << 26) | (1 << 27); /* RXD & TXD */ - if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 30); - if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 29); - if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 28); - - select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP); -} - -static inline void configure_usart3_pins(int flags) -{ - u32 pin_mask = (1 << 18) | (1 << 17); /* RXD & TXD */ - if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 16); - if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 15); - if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 19); - - select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP); -} - -static struct platform_device *__initdata at32_usarts[4]; - -void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags) -{ - struct platform_device *pdev; - struct atmel_uart_data *pdata; - - switch (hw_id) { - case 0: - pdev = &atmel_usart0_device; - configure_usart0_pins(flags); - break; - case 1: - pdev = &atmel_usart1_device; - configure_usart1_pins(flags); - break; - case 2: - pdev = &atmel_usart2_device; - configure_usart2_pins(flags); - break; - case 3: - pdev = &atmel_usart3_device; - configure_usart3_pins(flags); - break; - default: - return; - } - - if (PXSEG(pdev->resource[0].start) == P4SEG) { - /* Addresses in the P4 segment are permanently mapped 1:1 */ - struct atmel_uart_data *data = pdev->dev.platform_data; - data->regs = (void __iomem *)pdev->resource[0].start; - } - - pdev->id = line; - pdata = pdev->dev.platform_data; - pdata->num = line; - at32_usarts[line] = pdev; -} - -struct platform_device *__init at32_add_device_usart(unsigned int id) -{ - platform_device_register(at32_usarts[id]); - return at32_usarts[id]; -} - -void __init at32_setup_serial_console(unsigned int usart_id) -{ -#ifdef CONFIG_SERIAL_ATMEL - atmel_default_console_device = at32_usarts[usart_id]; -#endif -} - -/* -------------------------------------------------------------------- - * Ethernet - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_CPU_AT32AP7000 -static struct macb_platform_data macb0_data; -static struct resource macb0_resource[] = { - PBMEM(0xfff01800), - IRQ(25), -}; -DEFINE_DEV_DATA(macb, 0); -DEV_CLK(hclk, macb0, hsb, 8); -DEV_CLK(pclk, macb0, pbb, 6); - -static struct macb_platform_data macb1_data; -static struct resource macb1_resource[] = { - PBMEM(0xfff01c00), - IRQ(26), -}; -DEFINE_DEV_DATA(macb, 1); -DEV_CLK(hclk, macb1, hsb, 9); -DEV_CLK(pclk, macb1, pbb, 7); - -struct platform_device *__init -at32_add_device_eth(unsigned int id, struct macb_platform_data *data) -{ - struct platform_device *pdev; - u32 pin_mask; - - switch (id) { - case 0: - pdev = &macb0_device; - - pin_mask = (1 << 3); /* TXD0 */ - pin_mask |= (1 << 4); /* TXD1 */ - pin_mask |= (1 << 7); /* TXEN */ - pin_mask |= (1 << 8); /* TXCK */ - pin_mask |= (1 << 9); /* RXD0 */ - pin_mask |= (1 << 10); /* RXD1 */ - pin_mask |= (1 << 13); /* RXER */ - pin_mask |= (1 << 15); /* RXDV */ - pin_mask |= (1 << 16); /* MDC */ - pin_mask |= (1 << 17); /* MDIO */ - - if (!data->is_rmii) { - pin_mask |= (1 << 0); /* COL */ - pin_mask |= (1 << 1); /* CRS */ - pin_mask |= (1 << 2); /* TXER */ - pin_mask |= (1 << 5); /* TXD2 */ - pin_mask |= (1 << 6); /* TXD3 */ - pin_mask |= (1 << 11); /* RXD2 */ - pin_mask |= (1 << 12); /* RXD3 */ - pin_mask |= (1 << 14); /* RXCK */ -#ifndef CONFIG_BOARD_MIMC200 - pin_mask |= (1 << 18); /* SPD */ -#endif - } - - select_peripheral(PIOC, pin_mask, PERIPH_A, 0); - - break; - - case 1: - pdev = &macb1_device; - - pin_mask = (1 << 13); /* TXD0 */ - pin_mask |= (1 << 14); /* TXD1 */ - pin_mask |= (1 << 11); /* TXEN */ - pin_mask |= (1 << 12); /* TXCK */ - pin_mask |= (1 << 10); /* RXD0 */ - pin_mask |= (1 << 6); /* RXD1 */ - pin_mask |= (1 << 5); /* RXER */ - pin_mask |= (1 << 4); /* RXDV */ - pin_mask |= (1 << 3); /* MDC */ - pin_mask |= (1 << 2); /* MDIO */ - -#ifndef CONFIG_BOARD_MIMC200 - if (!data->is_rmii) - pin_mask |= (1 << 15); /* SPD */ -#endif - - select_peripheral(PIOD, pin_mask, PERIPH_B, 0); - - if (!data->is_rmii) { - pin_mask = (1 << 19); /* COL */ - pin_mask |= (1 << 23); /* CRS */ - pin_mask |= (1 << 26); /* TXER */ - pin_mask |= (1 << 27); /* TXD2 */ - pin_mask |= (1 << 28); /* TXD3 */ - pin_mask |= (1 << 29); /* RXD2 */ - pin_mask |= (1 << 30); /* RXD3 */ - pin_mask |= (1 << 24); /* RXCK */ - - select_peripheral(PIOC, pin_mask, PERIPH_B, 0); - } - break; - - default: - return NULL; - } - - memcpy(pdev->dev.platform_data, data, sizeof(struct macb_platform_data)); - platform_device_register(pdev); - - return pdev; -} -#endif - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ -static struct resource atmel_spi0_resource[] = { - PBMEM(0xffe00000), - IRQ(3), -}; -DEFINE_DEV(atmel_spi, 0); -DEV_CLK(spi_clk, atmel_spi0, pba, 0); - -static struct resource atmel_spi1_resource[] = { - PBMEM(0xffe00400), - IRQ(4), -}; -DEFINE_DEV(atmel_spi, 1); -DEV_CLK(spi_clk, atmel_spi1, pba, 1); - -void __init -at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, unsigned int n) -{ - /* - * Manage the chipselects as GPIOs, normally using the same pins - * the SPI controller expects; but boards can use other pins. - */ - static u8 __initdata spi_pins[][4] = { - { GPIO_PIN_PA(3), GPIO_PIN_PA(4), - GPIO_PIN_PA(5), GPIO_PIN_PA(20) }, - { GPIO_PIN_PB(2), GPIO_PIN_PB(3), - GPIO_PIN_PB(4), GPIO_PIN_PA(27) }, - }; - unsigned int pin, mode; - - /* There are only 2 SPI controllers */ - if (bus_num > 1) - return; - - for (; n; n--, b++) { - b->bus_num = bus_num; - if (b->chip_select >= 4) - continue; - pin = (unsigned)b->controller_data; - if (!pin) { - pin = spi_pins[bus_num][b->chip_select]; - b->controller_data = (void *)pin; - } - mode = AT32_GPIOF_OUTPUT; - if (!(b->mode & SPI_CS_HIGH)) - mode |= AT32_GPIOF_HIGH; - at32_select_gpio(pin, mode); - } -} - -struct platform_device *__init -at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n) -{ - struct platform_device *pdev; - u32 pin_mask; - - switch (id) { - case 0: - pdev = &atmel_spi0_device; - pin_mask = (1 << 1) | (1 << 2); /* MOSI & SCK */ - - /* pullup MISO so a level is always defined */ - select_peripheral(PIOA, (1 << 0), PERIPH_A, AT32_GPIOF_PULLUP); - select_peripheral(PIOA, pin_mask, PERIPH_A, 0); - - at32_spi_setup_slaves(0, b, n); - break; - - case 1: - pdev = &atmel_spi1_device; - pin_mask = (1 << 1) | (1 << 5); /* MOSI */ - - /* pullup MISO so a level is always defined */ - select_peripheral(PIOB, (1 << 0), PERIPH_B, AT32_GPIOF_PULLUP); - select_peripheral(PIOB, pin_mask, PERIPH_B, 0); - - at32_spi_setup_slaves(1, b, n); - break; - - default: - return NULL; - } - - spi_register_board_info(b, n); - platform_device_register(pdev); - return pdev; -} - -/* -------------------------------------------------------------------- - * TWI - * -------------------------------------------------------------------- */ -static struct resource atmel_twi0_resource[] __initdata = { - PBMEM(0xffe00800), - IRQ(5), -}; -static struct clk atmel_twi0_pclk = { - .name = "twi_pclk", - .parent = &pba_clk, - .mode = pba_clk_mode, - .get_rate = pba_clk_get_rate, - .index = 2, -}; - -struct platform_device *__init at32_add_device_twi(unsigned int id, - struct i2c_board_info *b, - unsigned int n) -{ - struct platform_device *pdev; - u32 pin_mask; - - if (id != 0) - return NULL; - - pdev = platform_device_alloc("atmel_twi", id); - if (!pdev) - return NULL; - - if (platform_device_add_resources(pdev, atmel_twi0_resource, - ARRAY_SIZE(atmel_twi0_resource))) - goto err_add_resources; - - pin_mask = (1 << 6) | (1 << 7); /* SDA & SDL */ - - select_peripheral(PIOA, pin_mask, PERIPH_A, 0); - - atmel_twi0_pclk.dev = &pdev->dev; - - if (b) - i2c_register_board_info(id, b, n); - - platform_device_add(pdev); - return pdev; - -err_add_resources: - platform_device_put(pdev); - return NULL; -} - -/* -------------------------------------------------------------------- - * MMC - * -------------------------------------------------------------------- */ -static struct resource atmel_mci0_resource[] __initdata = { - PBMEM(0xfff02400), - IRQ(28), -}; -static struct clk atmel_mci0_pclk = { - .name = "mci_clk", - .parent = &pbb_clk, - .mode = pbb_clk_mode, - .get_rate = pbb_clk_get_rate, - .index = 9, -}; - -static bool at32_mci_dma_filter(struct dma_chan *chan, void *pdata) -{ - struct dw_dma_slave *sl = pdata; - - if (!sl) - return false; - - if (sl->dma_dev == chan->device->dev) { - chan->private = sl; - return true; - } - - return false; -} - -struct platform_device *__init -at32_add_device_mci(unsigned int id, struct mci_platform_data *data) -{ - struct platform_device *pdev; - struct dw_dma_slave *slave; - u32 pioa_mask; - u32 piob_mask; - - if (id != 0 || !data) - return NULL; - - /* Must have at least one usable slot */ - if (!data->slot[0].bus_width && !data->slot[1].bus_width) - return NULL; - - pdev = platform_device_alloc("atmel_mci", id); - if (!pdev) - goto fail; - - if (platform_device_add_resources(pdev, atmel_mci0_resource, - ARRAY_SIZE(atmel_mci0_resource))) - goto fail; - - slave = kzalloc(sizeof(*slave), GFP_KERNEL); - if (!slave) - goto fail; - - slave->dma_dev = &dw_dmac0_device.dev; - slave->src_id = 0; - slave->dst_id = 1; - slave->m_master = 1; - slave->p_master = 0; - - data->dma_slave = slave; - data->dma_filter = at32_mci_dma_filter; - - if (platform_device_add_data(pdev, data, - sizeof(struct mci_platform_data))) - goto fail_free; - - /* CLK line is common to both slots */ - pioa_mask = 1 << 10; - - switch (data->slot[0].bus_width) { - case 4: - pioa_mask |= 1 << 13; /* DATA1 */ - pioa_mask |= 1 << 14; /* DATA2 */ - pioa_mask |= 1 << 15; /* DATA3 */ - /* fall through */ - case 1: - pioa_mask |= 1 << 11; /* CMD */ - pioa_mask |= 1 << 12; /* DATA0 */ - - if (gpio_is_valid(data->slot[0].detect_pin)) - at32_select_gpio(data->slot[0].detect_pin, 0); - if (gpio_is_valid(data->slot[0].wp_pin)) - at32_select_gpio(data->slot[0].wp_pin, 0); - break; - case 0: - /* Slot is unused */ - break; - default: - goto fail_free; - } - - select_peripheral(PIOA, pioa_mask, PERIPH_A, 0); - piob_mask = 0; - - switch (data->slot[1].bus_width) { - case 4: - piob_mask |= 1 << 8; /* DATA1 */ - piob_mask |= 1 << 9; /* DATA2 */ - piob_mask |= 1 << 10; /* DATA3 */ - /* fall through */ - case 1: - piob_mask |= 1 << 6; /* CMD */ - piob_mask |= 1 << 7; /* DATA0 */ - select_peripheral(PIOB, piob_mask, PERIPH_B, 0); - - if (gpio_is_valid(data->slot[1].detect_pin)) - at32_select_gpio(data->slot[1].detect_pin, 0); - if (gpio_is_valid(data->slot[1].wp_pin)) - at32_select_gpio(data->slot[1].wp_pin, 0); - break; - case 0: - /* Slot is unused */ - break; - default: - if (!data->slot[0].bus_width) - goto fail_free; - - data->slot[1].bus_width = 0; - break; - } - - atmel_mci0_pclk.dev = &pdev->dev; - - platform_device_add(pdev); - return pdev; - -fail_free: - kfree(slave); -fail: - data->dma_slave = NULL; - platform_device_put(pdev); - return NULL; -} - -/* -------------------------------------------------------------------- - * LCDC - * -------------------------------------------------------------------- */ -#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002) -static struct atmel_lcdfb_pdata atmel_lcdfb0_data; -static struct resource atmel_lcdfb0_resource[] = { - { - .start = 0xff000000, - .end = 0xff000fff, - .flags = IORESOURCE_MEM, - }, - IRQ(1), - { - /* Placeholder for pre-allocated fb memory */ - .start = 0x00000000, - .end = 0x00000000, - .flags = 0, - }, -}; -DEFINE_DEV_DATA(atmel_lcdfb, 0); -DEV_CLK(hclk, atmel_lcdfb0, hsb, 7); -static struct clk atmel_lcdfb0_pixclk = { - .name = "lcdc_clk", - .dev = &atmel_lcdfb0_device.dev, - .mode = genclk_mode, - .get_rate = genclk_get_rate, - .set_rate = genclk_set_rate, - .set_parent = genclk_set_parent, - .index = 7, -}; - -struct platform_device *__init -at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_pdata *data, - unsigned long fbmem_start, unsigned long fbmem_len, - u64 pin_mask) -{ - struct platform_device *pdev; - struct atmel_lcdfb_pdata *info; - struct fb_monspecs *monspecs; - struct fb_videomode *modedb; - unsigned int modedb_size; - u32 portc_mask, portd_mask, porte_mask; - - /* - * Do a deep copy of the fb data, monspecs and modedb. Make - * sure all allocations are done before setting up the - * portmux. - */ - monspecs = kmemdup(data->default_monspecs, - sizeof(struct fb_monspecs), GFP_KERNEL); - if (!monspecs) - return NULL; - - modedb_size = sizeof(struct fb_videomode) * monspecs->modedb_len; - modedb = kmemdup(monspecs->modedb, modedb_size, GFP_KERNEL); - if (!modedb) - goto err_dup_modedb; - monspecs->modedb = modedb; - - switch (id) { - case 0: - pdev = &atmel_lcdfb0_device; - - if (pin_mask == 0ULL) - /* Default to "full" lcdc control signals and 24bit */ - pin_mask = ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL; - - /* LCDC on port C */ - portc_mask = pin_mask & 0xfff80000; - select_peripheral(PIOC, portc_mask, PERIPH_A, 0); - - /* LCDC on port D */ - portd_mask = pin_mask & 0x0003ffff; - select_peripheral(PIOD, portd_mask, PERIPH_A, 0); - - /* LCDC on port E */ - porte_mask = (pin_mask >> 32) & 0x0007ffff; - select_peripheral(PIOE, porte_mask, PERIPH_B, 0); - - clk_set_parent(&atmel_lcdfb0_pixclk, &pll0); - clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0)); - break; - - default: - goto err_invalid_id; - } - - if (fbmem_len) { - pdev->resource[2].start = fbmem_start; - pdev->resource[2].end = fbmem_start + fbmem_len - 1; - pdev->resource[2].flags = IORESOURCE_MEM; - } - - info = pdev->dev.platform_data; - memcpy(info, data, sizeof(struct atmel_lcdfb_pdata)); - info->default_monspecs = monspecs; - - pdev->name = "at32ap-lcdfb"; - - platform_device_register(pdev); - return pdev; - -err_invalid_id: - kfree(modedb); -err_dup_modedb: - kfree(monspecs); - return NULL; -} -#endif - -/* -------------------------------------------------------------------- - * PWM - * -------------------------------------------------------------------- */ -static struct resource atmel_pwm0_resource[] __initdata = { - PBMEM(0xfff01400), - IRQ(24), -}; -static struct clk atmel_pwm0_mck = { - .name = "at91sam9rl-pwm", - .parent = &pbb_clk, - .mode = pbb_clk_mode, - .get_rate = pbb_clk_get_rate, - .index = 5, -}; - -struct platform_device *__init at32_add_device_pwm(u32 mask) -{ - struct platform_device *pdev; - u32 pin_mask; - - if (!mask) - return NULL; - - pdev = platform_device_alloc("at91sam9rl-pwm", 0); - if (!pdev) - return NULL; - - if (platform_device_add_resources(pdev, atmel_pwm0_resource, - ARRAY_SIZE(atmel_pwm0_resource))) - goto out_free_pdev; - - pin_mask = 0; - if (mask & (1 << 0)) - pin_mask |= (1 << 28); - if (mask & (1 << 1)) - pin_mask |= (1 << 29); - if (pin_mask > 0) - select_peripheral(PIOA, pin_mask, PERIPH_A, 0); - - pin_mask = 0; - if (mask & (1 << 2)) - pin_mask |= (1 << 21); - if (mask & (1 << 3)) - pin_mask |= (1 << 22); - if (pin_mask > 0) - select_peripheral(PIOA, pin_mask, PERIPH_B, 0); - - atmel_pwm0_mck.dev = &pdev->dev; - - platform_device_add(pdev); - - return pdev; - -out_free_pdev: - platform_device_put(pdev); - return NULL; -} - -/* -------------------------------------------------------------------- - * SSC - * -------------------------------------------------------------------- */ -static struct resource ssc0_resource[] = { - PBMEM(0xffe01c00), - IRQ(10), -}; -DEFINE_DEV(ssc, 0); -DEV_CLK(pclk, ssc0, pba, 7); - -static struct resource ssc1_resource[] = { - PBMEM(0xffe02000), - IRQ(11), -}; -DEFINE_DEV(ssc, 1); -DEV_CLK(pclk, ssc1, pba, 8); - -static struct resource ssc2_resource[] = { - PBMEM(0xffe02400), - IRQ(12), -}; -DEFINE_DEV(ssc, 2); -DEV_CLK(pclk, ssc2, pba, 9); - -struct platform_device *__init -at32_add_device_ssc(unsigned int id, unsigned int flags) -{ - struct platform_device *pdev; - u32 pin_mask = 0; - - switch (id) { - case 0: - pdev = &ssc0_device; - if (flags & ATMEL_SSC_RF) - pin_mask |= (1 << 21); /* RF */ - if (flags & ATMEL_SSC_RK) - pin_mask |= (1 << 22); /* RK */ - if (flags & ATMEL_SSC_TK) - pin_mask |= (1 << 23); /* TK */ - if (flags & ATMEL_SSC_TF) - pin_mask |= (1 << 24); /* TF */ - if (flags & ATMEL_SSC_TD) - pin_mask |= (1 << 25); /* TD */ - if (flags & ATMEL_SSC_RD) - pin_mask |= (1 << 26); /* RD */ - - if (pin_mask > 0) - select_peripheral(PIOA, pin_mask, PERIPH_A, 0); - - break; - case 1: - pdev = &ssc1_device; - if (flags & ATMEL_SSC_RF) - pin_mask |= (1 << 0); /* RF */ - if (flags & ATMEL_SSC_RK) - pin_mask |= (1 << 1); /* RK */ - if (flags & ATMEL_SSC_TK) - pin_mask |= (1 << 2); /* TK */ - if (flags & ATMEL_SSC_TF) - pin_mask |= (1 << 3); /* TF */ - if (flags & ATMEL_SSC_TD) - pin_mask |= (1 << 4); /* TD */ - if (flags & ATMEL_SSC_RD) - pin_mask |= (1 << 5); /* RD */ - - if (pin_mask > 0) - select_peripheral(PIOA, pin_mask, PERIPH_B, 0); - - break; - case 2: - pdev = &ssc2_device; - if (flags & ATMEL_SSC_TD) - pin_mask |= (1 << 13); /* TD */ - if (flags & ATMEL_SSC_RD) - pin_mask |= (1 << 14); /* RD */ - if (flags & ATMEL_SSC_TK) - pin_mask |= (1 << 15); /* TK */ - if (flags & ATMEL_SSC_TF) - pin_mask |= (1 << 16); /* TF */ - if (flags & ATMEL_SSC_RF) - pin_mask |= (1 << 17); /* RF */ - if (flags & ATMEL_SSC_RK) - pin_mask |= (1 << 18); /* RK */ - - if (pin_mask > 0) - select_peripheral(PIOB, pin_mask, PERIPH_A, 0); - - break; - default: - return NULL; - } - - platform_device_register(pdev); - return pdev; -} - -/* -------------------------------------------------------------------- - * USB Device Controller - * -------------------------------------------------------------------- */ -static struct resource usba0_resource[] __initdata = { - { - .start = 0xff300000, - .end = 0xff3fffff, - .flags = IORESOURCE_MEM, - }, { - .start = 0xfff03000, - .end = 0xfff033ff, - .flags = IORESOURCE_MEM, - }, - IRQ(31), -}; -static struct clk usba0_pclk = { - .name = "pclk", - .parent = &pbb_clk, - .mode = pbb_clk_mode, - .get_rate = pbb_clk_get_rate, - .index = 12, -}; -static struct clk usba0_hclk = { - .name = "hclk", - .parent = &hsb_clk, - .mode = hsb_clk_mode, - .get_rate = hsb_clk_get_rate, - .index = 6, -}; - -#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ - [idx] = { \ - .name = nam, \ - .index = idx, \ - .fifo_size = maxpkt, \ - .nr_banks = maxbk, \ - .can_dma = dma, \ - .can_isoc = isoc, \ - } - -static struct usba_ep_data at32_usba_ep[] __initdata = { - EP("ep0", 0, 64, 1, 0, 0), - EP("ep1", 1, 512, 2, 1, 1), - EP("ep2", 2, 512, 2, 1, 1), - EP("ep3-int", 3, 64, 3, 1, 0), - EP("ep4-int", 4, 64, 3, 1, 0), - EP("ep5", 5, 1024, 3, 1, 1), - EP("ep6", 6, 1024, 3, 1, 1), -}; - -#undef EP - -struct platform_device *__init -at32_add_device_usba(unsigned int id, struct usba_platform_data *data) -{ - /* - * pdata doesn't have room for any endpoints, so we need to - * append room for the ones we need right after it. - */ - struct { - struct usba_platform_data pdata; - struct usba_ep_data ep[7]; - } usba_data; - struct platform_device *pdev; - - if (id != 0) - return NULL; - - pdev = platform_device_alloc("atmel_usba_udc", 0); - if (!pdev) - return NULL; - - if (platform_device_add_resources(pdev, usba0_resource, - ARRAY_SIZE(usba0_resource))) - goto out_free_pdev; - - if (data) { - usba_data.pdata.vbus_pin = data->vbus_pin; - usba_data.pdata.vbus_pin_inverted = data->vbus_pin_inverted; - } else { - usba_data.pdata.vbus_pin = -EINVAL; - usba_data.pdata.vbus_pin_inverted = -EINVAL; - } - - data = &usba_data.pdata; - data->num_ep = ARRAY_SIZE(at32_usba_ep); - memcpy(data->ep, at32_usba_ep, sizeof(at32_usba_ep)); - - if (platform_device_add_data(pdev, data, sizeof(usba_data))) - goto out_free_pdev; - - if (gpio_is_valid(data->vbus_pin)) - at32_select_gpio(data->vbus_pin, 0); - - usba0_pclk.dev = &pdev->dev; - usba0_hclk.dev = &pdev->dev; - - platform_device_add(pdev); - - return pdev; - -out_free_pdev: - platform_device_put(pdev); - return NULL; -} - -/* -------------------------------------------------------------------- - * IDE / CompactFlash - * -------------------------------------------------------------------- */ -#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7001) -static struct resource at32_smc_cs4_resource[] __initdata = { - { - .start = 0x04000000, - .end = 0x07ffffff, - .flags = IORESOURCE_MEM, - }, - IRQ(~0UL), /* Magic IRQ will be overridden */ -}; -static struct resource at32_smc_cs5_resource[] __initdata = { - { - .start = 0x20000000, - .end = 0x23ffffff, - .flags = IORESOURCE_MEM, - }, - IRQ(~0UL), /* Magic IRQ will be overridden */ -}; - -static int __init at32_init_ide_or_cf(struct platform_device *pdev, - unsigned int cs, unsigned int extint) -{ - static unsigned int extint_pin_map[4] __initdata = { - (1 << 25), - (1 << 26), - (1 << 27), - (1 << 28), - }; - static bool common_pins_initialized __initdata = false; - unsigned int extint_pin; - int ret; - u32 pin_mask; - - if (extint >= ARRAY_SIZE(extint_pin_map)) - return -EINVAL; - extint_pin = extint_pin_map[extint]; - - switch (cs) { - case 4: - ret = platform_device_add_resources(pdev, - at32_smc_cs4_resource, - ARRAY_SIZE(at32_smc_cs4_resource)); - if (ret) - return ret; - - /* NCS4 -> OE_N */ - select_peripheral(PIOE, (1 << 21), PERIPH_A, 0); - hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF0_ENABLE); - break; - case 5: - ret = platform_device_add_resources(pdev, - at32_smc_cs5_resource, - ARRAY_SIZE(at32_smc_cs5_resource)); - if (ret) - return ret; - - /* NCS5 -> OE_N */ - select_peripheral(PIOE, (1 << 22), PERIPH_A, 0); - hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF1_ENABLE); - break; - default: - return -EINVAL; - } - - if (!common_pins_initialized) { - pin_mask = (1 << 19); /* CFCE1 -> CS0_N */ - pin_mask |= (1 << 20); /* CFCE2 -> CS1_N */ - pin_mask |= (1 << 23); /* CFRNW -> DIR */ - pin_mask |= (1 << 24); /* NWAIT <- IORDY */ - - select_peripheral(PIOE, pin_mask, PERIPH_A, 0); - - common_pins_initialized = true; - } - - select_peripheral(PIOB, extint_pin, PERIPH_A, AT32_GPIOF_DEGLITCH); - - pdev->resource[1].start = EIM_IRQ_BASE + extint; - pdev->resource[1].end = pdev->resource[1].start; - - return 0; -} - -struct platform_device *__init -at32_add_device_ide(unsigned int id, unsigned int extint, - struct ide_platform_data *data) -{ - struct platform_device *pdev; - - pdev = platform_device_alloc("at32_ide", id); - if (!pdev) - goto fail; - - if (platform_device_add_data(pdev, data, - sizeof(struct ide_platform_data))) - goto fail; - - if (at32_init_ide_or_cf(pdev, data->cs, extint)) - goto fail; - - platform_device_add(pdev); - return pdev; - -fail: - platform_device_put(pdev); - return NULL; -} - -struct platform_device *__init -at32_add_device_cf(unsigned int id, unsigned int extint, - struct cf_platform_data *data) -{ - struct platform_device *pdev; - - pdev = platform_device_alloc("at32_cf", id); - if (!pdev) - goto fail; - - if (platform_device_add_data(pdev, data, - sizeof(struct cf_platform_data))) - goto fail; - - if (at32_init_ide_or_cf(pdev, data->cs, extint)) - goto fail; - - if (gpio_is_valid(data->detect_pin)) - at32_select_gpio(data->detect_pin, AT32_GPIOF_DEGLITCH); - if (gpio_is_valid(data->reset_pin)) - at32_select_gpio(data->reset_pin, 0); - if (gpio_is_valid(data->vcc_pin)) - at32_select_gpio(data->vcc_pin, 0); - /* READY is used as extint, so we can't select it as gpio */ - - platform_device_add(pdev); - return pdev; - -fail: - platform_device_put(pdev); - return NULL; -} -#endif - -/* -------------------------------------------------------------------- - * NAND Flash / SmartMedia - * -------------------------------------------------------------------- */ -static struct resource smc_cs3_resource[] __initdata = { - { - .start = 0x0c000000, - .end = 0x0fffffff, - .flags = IORESOURCE_MEM, - }, { - .start = 0xfff03c00, - .end = 0xfff03fff, - .flags = IORESOURCE_MEM, - }, -}; - -struct platform_device *__init -at32_add_device_nand(unsigned int id, struct atmel_nand_data *data) -{ - struct platform_device *pdev; - - if (id != 0 || !data) - return NULL; - - pdev = platform_device_alloc("atmel_nand", id); - if (!pdev) - goto fail; - - if (platform_device_add_resources(pdev, smc_cs3_resource, - ARRAY_SIZE(smc_cs3_resource))) - goto fail; - - /* For at32ap7000, we use the reset workaround for nand driver */ - data->need_reset_workaround = true; - - if (platform_device_add_data(pdev, data, - sizeof(struct atmel_nand_data))) - goto fail; - - hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_NAND_ENABLE); - if (data->enable_pin) - at32_select_gpio(data->enable_pin, - AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - if (data->rdy_pin) - at32_select_gpio(data->rdy_pin, 0); - if (data->det_pin) - at32_select_gpio(data->det_pin, 0); - - platform_device_add(pdev); - return pdev; - -fail: - platform_device_put(pdev); - return NULL; -} - -/* -------------------------------------------------------------------- - * AC97C - * -------------------------------------------------------------------- */ -static struct resource atmel_ac97c0_resource[] __initdata = { - PBMEM(0xfff02800), - IRQ(29), -}; -static struct clk atmel_ac97c0_pclk = { - .name = "pclk", - .parent = &pbb_clk, - .mode = pbb_clk_mode, - .get_rate = pbb_clk_get_rate, - .index = 10, -}; - -struct platform_device *__init -at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, - unsigned int flags) -{ - struct platform_device *pdev; - struct dw_dma_slave *rx_dws; - struct dw_dma_slave *tx_dws; - struct ac97c_platform_data _data; - u32 pin_mask; - - if (id != 0) - return NULL; - - pdev = platform_device_alloc("atmel_ac97c", id); - if (!pdev) - return NULL; - - if (platform_device_add_resources(pdev, atmel_ac97c0_resource, - ARRAY_SIZE(atmel_ac97c0_resource))) - goto out_free_resources; - - if (!data) { - data = &_data; - memset(data, 0, sizeof(struct ac97c_platform_data)); - data->reset_pin = -ENODEV; - } - - rx_dws = &data->rx_dws; - tx_dws = &data->tx_dws; - - /* Check if DMA slave interface for capture should be configured. */ - if (flags & AC97C_CAPTURE) { - rx_dws->dma_dev = &dw_dmac0_device.dev; - rx_dws->src_id = 3; - rx_dws->m_master = 0; - rx_dws->p_master = 1; - } - - /* Check if DMA slave interface for playback should be configured. */ - if (flags & AC97C_PLAYBACK) { - tx_dws->dma_dev = &dw_dmac0_device.dev; - tx_dws->dst_id = 4; - tx_dws->m_master = 0; - tx_dws->p_master = 1; - } - - if (platform_device_add_data(pdev, data, - sizeof(struct ac97c_platform_data))) - goto out_free_resources; - - /* SDO | SYNC | SCLK | SDI */ - pin_mask = (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23); - - select_peripheral(PIOB, pin_mask, PERIPH_B, 0); - - if (gpio_is_valid(data->reset_pin)) - at32_select_gpio(data->reset_pin, AT32_GPIOF_OUTPUT - | AT32_GPIOF_HIGH); - - atmel_ac97c0_pclk.dev = &pdev->dev; - - platform_device_add(pdev); - return pdev; - -out_free_resources: - platform_device_put(pdev); - return NULL; -} - -/* -------------------------------------------------------------------- - * ABDAC - * -------------------------------------------------------------------- */ -static struct resource abdac0_resource[] __initdata = { - PBMEM(0xfff02000), - IRQ(27), -}; -static struct clk abdac0_pclk = { - .name = "pclk", - .parent = &pbb_clk, - .mode = pbb_clk_mode, - .get_rate = pbb_clk_get_rate, - .index = 8, -}; -static struct clk abdac0_sample_clk = { - .name = "sample_clk", - .mode = genclk_mode, - .get_rate = genclk_get_rate, - .set_rate = genclk_set_rate, - .set_parent = genclk_set_parent, - .index = 6, -}; - -struct platform_device *__init -at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data) -{ - struct platform_device *pdev; - struct dw_dma_slave *dws; - u32 pin_mask; - - if (id != 0 || !data) - return NULL; - - pdev = platform_device_alloc("atmel_abdac", id); - if (!pdev) - return NULL; - - if (platform_device_add_resources(pdev, abdac0_resource, - ARRAY_SIZE(abdac0_resource))) - goto out_free_resources; - - dws = &data->dws; - - dws->dma_dev = &dw_dmac0_device.dev; - dws->dst_id = 2; - dws->m_master = 0; - dws->p_master = 1; - - if (platform_device_add_data(pdev, data, - sizeof(struct atmel_abdac_pdata))) - goto out_free_resources; - - pin_mask = (1 << 20) | (1 << 22); /* DATA1 & DATAN1 */ - pin_mask |= (1 << 21) | (1 << 23); /* DATA0 & DATAN0 */ - - select_peripheral(PIOB, pin_mask, PERIPH_A, 0); - - abdac0_pclk.dev = &pdev->dev; - abdac0_sample_clk.dev = &pdev->dev; - - platform_device_add(pdev); - return pdev; - -out_free_resources: - platform_device_put(pdev); - return NULL; -} - -/* -------------------------------------------------------------------- - * GCLK - * -------------------------------------------------------------------- */ -static struct clk gclk0 = { - .name = "gclk0", - .mode = genclk_mode, - .get_rate = genclk_get_rate, - .set_rate = genclk_set_rate, - .set_parent = genclk_set_parent, - .index = 0, -}; -static struct clk gclk1 = { - .name = "gclk1", - .mode = genclk_mode, - .get_rate = genclk_get_rate, - .set_rate = genclk_set_rate, - .set_parent = genclk_set_parent, - .index = 1, -}; -static struct clk gclk2 = { - .name = "gclk2", - .mode = genclk_mode, - .get_rate = genclk_get_rate, - .set_rate = genclk_set_rate, - .set_parent = genclk_set_parent, - .index = 2, -}; -static struct clk gclk3 = { - .name = "gclk3", - .mode = genclk_mode, - .get_rate = genclk_get_rate, - .set_rate = genclk_set_rate, - .set_parent = genclk_set_parent, - .index = 3, -}; -static struct clk gclk4 = { - .name = "gclk4", - .mode = genclk_mode, - .get_rate = genclk_get_rate, - .set_rate = genclk_set_rate, - .set_parent = genclk_set_parent, - .index = 4, -}; - -static __initdata struct clk *init_clocks[] = { - &osc32k, - &osc0, - &osc1, - &pll0, - &pll1, - &cpu_clk, - &hsb_clk, - &pba_clk, - &pbb_clk, - &at32_pm_pclk, - &at32_intc0_pclk, - &at32_hmatrix_clk, - &ebi_clk, - &hramc_clk, - &sdramc_clk, - &smc0_pclk, - &smc0_mck, - &pdc_hclk, - &pdc_pclk, - &dw_dmac0_hclk, - &pico_clk, - &pio0_mck, - &pio1_mck, - &pio2_mck, - &pio3_mck, - &pio4_mck, - &at32_tcb0_t0_clk, - &at32_tcb1_t0_clk, - &atmel_psif0_pclk, - &atmel_psif1_pclk, - &atmel_usart0_usart, - &atmel_usart1_usart, - &atmel_usart2_usart, - &atmel_usart3_usart, - &atmel_pwm0_mck, -#if defined(CONFIG_CPU_AT32AP7000) - &macb0_hclk, - &macb0_pclk, - &macb1_hclk, - &macb1_pclk, -#endif - &atmel_spi0_spi_clk, - &atmel_spi1_spi_clk, - &atmel_twi0_pclk, - &atmel_mci0_pclk, -#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002) - &atmel_lcdfb0_hclk, - &atmel_lcdfb0_pixclk, -#endif - &ssc0_pclk, - &ssc1_pclk, - &ssc2_pclk, - &usba0_hclk, - &usba0_pclk, - &atmel_ac97c0_pclk, - &abdac0_pclk, - &abdac0_sample_clk, - &gclk0, - &gclk1, - &gclk2, - &gclk3, - &gclk4, -}; - -void __init setup_platform(void) -{ - u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0; - int i; - - if (pm_readl(MCCTRL) & PM_BIT(PLLSEL)) { - main_clock = &pll0; - cpu_clk.parent = &pll0; - } else { - main_clock = &osc0; - cpu_clk.parent = &osc0; - } - - if (pm_readl(PLL0) & PM_BIT(PLLOSC)) - pll0.parent = &osc1; - if (pm_readl(PLL1) & PM_BIT(PLLOSC)) - pll1.parent = &osc1; - - genclk_init_parent(&gclk0); - genclk_init_parent(&gclk1); - genclk_init_parent(&gclk2); - genclk_init_parent(&gclk3); - genclk_init_parent(&gclk4); -#if defined(CONFIG_CPU_AT32AP7000) || defined(CONFIG_CPU_AT32AP7002) - genclk_init_parent(&atmel_lcdfb0_pixclk); -#endif - genclk_init_parent(&abdac0_sample_clk); - - /* - * Build initial dynamic clock list by registering all clocks - * from the array. - * At the same time, turn on all clocks that have at least one - * user already, and turn off everything else. We only do this - * for module clocks, and even though it isn't particularly - * pretty to check the address of the mode function, it should - * do the trick... - */ - for (i = 0; i < ARRAY_SIZE(init_clocks); i++) { - struct clk *clk = init_clocks[i]; - - /* first, register clock */ - at32_clk_register(clk); - - if (clk->users == 0) - continue; - - if (clk->mode == &cpu_clk_mode) - cpu_mask |= 1 << clk->index; - else if (clk->mode == &hsb_clk_mode) - hsb_mask |= 1 << clk->index; - else if (clk->mode == &pba_clk_mode) - pba_mask |= 1 << clk->index; - else if (clk->mode == &pbb_clk_mode) - pbb_mask |= 1 << clk->index; - } - - pm_writel(CPU_MASK, cpu_mask); - pm_writel(HSB_MASK, hsb_mask); - pm_writel(PBA_MASK, pba_mask); - pm_writel(PBB_MASK, pbb_mask); - - /* Initialize the port muxes */ - at32_init_pio(&pio0_device); - at32_init_pio(&pio1_device); - at32_init_pio(&pio2_device); - at32_init_pio(&pio3_device); - at32_init_pio(&pio4_device); -} - -struct gen_pool *sram_pool; - -static int __init sram_init(void) -{ - struct gen_pool *pool; - - /* 1KiB granularity */ - pool = gen_pool_create(10, -1); - if (!pool) - goto fail; - - if (gen_pool_add(pool, 0x24000000, 0x8000, -1)) - goto err_pool_add; - - sram_pool = pool; - return 0; - -err_pool_add: - gen_pool_destroy(pool); -fail: - pr_err("Failed to create SRAM pool\n"); - return -ENOMEM; -} -core_initcall(sram_init); diff --git a/arch/avr32/mach-at32ap/clock.c b/arch/avr32/mach-at32ap/clock.c deleted file mode 100644 index fdf1caecb7b9..000000000000 --- a/arch/avr32/mach-at32ap/clock.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Clock management for AT32AP CPUs - * - * Copyright (C) 2006 Atmel Corporation - * - * Based on arch/arm/mach-at91/clock.c - * Copyright (C) 2005 David Brownell - * Copyright (C) 2005 Ivan Kokshaysky - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/export.h> -#include <linux/device.h> -#include <linux/string.h> -#include <linux/list.h> - -#include <mach/chip.h> - -#include "clock.h" - -/* at32 clock list */ -static LIST_HEAD(at32_clock_list); - -static DEFINE_SPINLOCK(clk_lock); -static DEFINE_SPINLOCK(clk_list_lock); - -void at32_clk_register(struct clk *clk) -{ - spin_lock(&clk_list_lock); - /* add the new item to the end of the list */ - list_add_tail(&clk->list, &at32_clock_list); - spin_unlock(&clk_list_lock); -} - -static struct clk *__clk_get(struct device *dev, const char *id) -{ - struct clk *clk; - - list_for_each_entry(clk, &at32_clock_list, list) { - if (clk->dev == dev && strcmp(id, clk->name) == 0) { - return clk; - } - } - - return ERR_PTR(-ENOENT); -} - -struct clk *clk_get(struct device *dev, const char *id) -{ - struct clk *clk; - - spin_lock(&clk_list_lock); - clk = __clk_get(dev, id); - spin_unlock(&clk_list_lock); - - return clk; -} - -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ - /* clocks are static for now, we can't free them */ -} -EXPORT_SYMBOL(clk_put); - -static void __clk_enable(struct clk *clk) -{ - if (clk->parent) - __clk_enable(clk->parent); - if (clk->users++ == 0 && clk->mode) - clk->mode(clk, 1); -} - -int clk_enable(struct clk *clk) -{ - unsigned long flags; - - if (!clk) - return 0; - - spin_lock_irqsave(&clk_lock, flags); - __clk_enable(clk); - spin_unlock_irqrestore(&clk_lock, flags); - - return 0; -} -EXPORT_SYMBOL(clk_enable); - -static void __clk_disable(struct clk *clk) -{ - if (clk->users == 0) { - printk(KERN_ERR "%s: mismatched disable\n", clk->name); - WARN_ON(1); - return; - } - - if (--clk->users == 0 && clk->mode) - clk->mode(clk, 0); - if (clk->parent) - __clk_disable(clk->parent); -} - -void clk_disable(struct clk *clk) -{ - unsigned long flags; - - if (IS_ERR_OR_NULL(clk)) - return; - - spin_lock_irqsave(&clk_lock, flags); - __clk_disable(clk); - spin_unlock_irqrestore(&clk_lock, flags); -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - unsigned long flags; - unsigned long rate; - - if (!clk) - return 0; - - spin_lock_irqsave(&clk_lock, flags); - rate = clk->get_rate(clk); - spin_unlock_irqrestore(&clk_lock, flags); - - return rate; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - unsigned long flags, actual_rate; - - if (!clk) - return 0; - - if (!clk->set_rate) - return -ENOSYS; - - spin_lock_irqsave(&clk_lock, flags); - actual_rate = clk->set_rate(clk, rate, 0); - spin_unlock_irqrestore(&clk_lock, flags); - - return actual_rate; -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned long flags; - long ret; - - if (!clk) - return 0; - - if (!clk->set_rate) - return -ENOSYS; - - spin_lock_irqsave(&clk_lock, flags); - ret = clk->set_rate(clk, rate, 1); - spin_unlock_irqrestore(&clk_lock, flags); - - return (ret < 0) ? ret : 0; -} -EXPORT_SYMBOL(clk_set_rate); - -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - unsigned long flags; - int ret; - - if (!clk) - return 0; - - if (!clk->set_parent) - return -ENOSYS; - - spin_lock_irqsave(&clk_lock, flags); - ret = clk->set_parent(clk, parent); - spin_unlock_irqrestore(&clk_lock, flags); - - return ret; -} -EXPORT_SYMBOL(clk_set_parent); - -struct clk *clk_get_parent(struct clk *clk) -{ - return !clk ? NULL : clk->parent; -} -EXPORT_SYMBOL(clk_get_parent); - - - -#ifdef CONFIG_DEBUG_FS - -/* /sys/kernel/debug/at32ap_clk */ - -#include <linux/io.h> -#include <linux/debugfs.h> -#include <linux/seq_file.h> -#include "pm.h" - - -#define NEST_DELTA 2 -#define NEST_MAX 6 - -struct clkinf { - struct seq_file *s; - unsigned nest; -}; - -static void -dump_clock(struct clk *parent, struct clkinf *r) -{ - unsigned nest = r->nest; - char buf[16 + NEST_MAX]; - struct clk *clk; - unsigned i; - - /* skip clocks coupled to devices that aren't registered */ - if (parent->dev && !dev_name(parent->dev) && !parent->users) - return; - - /* <nest spaces> name <pad to end> */ - memset(buf, ' ', sizeof(buf) - 1); - buf[sizeof(buf) - 1] = 0; - i = strlen(parent->name); - memcpy(buf + nest, parent->name, - min(i, (unsigned)(sizeof(buf) - 1 - nest))); - - seq_printf(r->s, "%s%c users=%2d %-3s %9ld Hz", - buf, parent->set_parent ? '*' : ' ', - parent->users, - parent->users ? "on" : "off", /* NOTE: not-paranoid!! */ - clk_get_rate(parent)); - if (parent->dev) - seq_printf(r->s, ", for %s", dev_name(parent->dev)); - seq_putc(r->s, '\n'); - - /* cost of this scan is small, but not linear... */ - r->nest = nest + NEST_DELTA; - - list_for_each_entry(clk, &at32_clock_list, list) { - if (clk->parent == parent) - dump_clock(clk, r); - } - r->nest = nest; -} - -static int clk_show(struct seq_file *s, void *unused) -{ - struct clkinf r; - int i; - struct clk *clk; - - /* show all the power manager registers */ - seq_printf(s, - "MCCTRL = %8x\n" - "CKSEL = %8x\n" - "CPUMASK = %8x\n" - "HSBMASK = %8x\n" - "PBAMASK = %8x\n" - "PBBMASK = %8x\n" - "PLL0 = %8x\n" - "PLL1 = %8x\n" - "IMR = %8x\n", - pm_readl(MCCTRL), - pm_readl(CKSEL), - pm_readl(CPU_MASK), - pm_readl(HSB_MASK), - pm_readl(PBA_MASK), - pm_readl(PBB_MASK), - pm_readl(PLL0), - pm_readl(PLL1), - pm_readl(IMR)); - for (i = 0; i < 8; i++) { - if (i == 5) - continue; - seq_printf(s, "GCCTRL%d = %8x\n", i, pm_readl(GCCTRL(i))); - } - - seq_putc(s, '\n'); - r.s = s; - r.nest = 0; - /* protected from changes on the list while dumping */ - spin_lock(&clk_list_lock); - - /* show clock tree as derived from the three oscillators */ - clk = __clk_get(NULL, "osc32k"); - dump_clock(clk, &r); - clk_put(clk); - - clk = __clk_get(NULL, "osc0"); - dump_clock(clk, &r); - clk_put(clk); - - clk = __clk_get(NULL, "osc1"); - dump_clock(clk, &r); - clk_put(clk); - - spin_unlock(&clk_list_lock); - - return 0; -} - -static int clk_open(struct inode *inode, struct file *file) -{ - return single_open(file, clk_show, NULL); -} - -static const struct file_operations clk_operations = { - .open = clk_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init clk_debugfs_init(void) -{ - (void) debugfs_create_file("at32ap_clk", S_IFREG | S_IRUGO, - NULL, NULL, &clk_operations); - - return 0; -} -postcore_initcall(clk_debugfs_init); - -#endif diff --git a/arch/avr32/mach-at32ap/clock.h b/arch/avr32/mach-at32ap/clock.h deleted file mode 100644 index 4c7ebbdc6dfa..000000000000 --- a/arch/avr32/mach-at32ap/clock.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Clock management for AT32AP CPUs - * - * Copyright (C) 2006 Atmel Corporation - * - * Based on arch/arm/mach-at91/clock.c - * Copyright (C) 2005 David Brownell - * Copyright (C) 2005 Ivan Kokshaysky - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/list.h> - - -void at32_clk_register(struct clk *clk); - -struct clk { - struct list_head list; /* linking element */ - const char *name; /* Clock name/function */ - struct device *dev; /* Device the clock is used by */ - struct clk *parent; /* Parent clock, if any */ - void (*mode)(struct clk *clk, int enabled); - unsigned long (*get_rate)(struct clk *clk); - long (*set_rate)(struct clk *clk, unsigned long rate, - int apply); - int (*set_parent)(struct clk *clk, struct clk *parent); - u16 users; /* Enabled if non-zero */ - u16 index; /* Sibling index */ -}; - -unsigned long pba_clk_get_rate(struct clk *clk); -void pba_clk_mode(struct clk *clk, int enabled); diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c deleted file mode 100644 index 96cabad68489..000000000000 --- a/arch/avr32/mach-at32ap/extint.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * External interrupt handling for AT32AP CPUs - * - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/platform_device.h> -#include <linux/random.h> -#include <linux/slab.h> - -#include <asm/io.h> - -/* EIC register offsets */ -#define EIC_IER 0x0000 -#define EIC_IDR 0x0004 -#define EIC_IMR 0x0008 -#define EIC_ISR 0x000c -#define EIC_ICR 0x0010 -#define EIC_MODE 0x0014 -#define EIC_EDGE 0x0018 -#define EIC_LEVEL 0x001c -#define EIC_NMIC 0x0024 - -/* Bitfields in NMIC */ -#define EIC_NMIC_ENABLE (1 << 0) - -/* Bit manipulation macros */ -#define EIC_BIT(name) \ - (1 << EIC_##name##_OFFSET) -#define EIC_BF(name,value) \ - (((value) & ((1 << EIC_##name##_SIZE) - 1)) \ - << EIC_##name##_OFFSET) -#define EIC_BFEXT(name,value) \ - (((value) >> EIC_##name##_OFFSET) \ - & ((1 << EIC_##name##_SIZE) - 1)) -#define EIC_BFINS(name,value,old) \ - (((old) & ~(((1 << EIC_##name##_SIZE) - 1) \ - << EIC_##name##_OFFSET)) \ - | EIC_BF(name,value)) - -/* Register access macros */ -#define eic_readl(port,reg) \ - __raw_readl((port)->regs + EIC_##reg) -#define eic_writel(port,reg,value) \ - __raw_writel((value), (port)->regs + EIC_##reg) - -struct eic { - void __iomem *regs; - struct irq_chip *chip; - unsigned int first_irq; -}; - -static struct eic *nmi_eic; -static bool nmi_enabled; - -static void eic_ack_irq(struct irq_data *d) -{ - struct eic *eic = irq_data_get_irq_chip_data(d); - eic_writel(eic, ICR, 1 << (d->irq - eic->first_irq)); -} - -static void eic_mask_irq(struct irq_data *d) -{ - struct eic *eic = irq_data_get_irq_chip_data(d); - eic_writel(eic, IDR, 1 << (d->irq - eic->first_irq)); -} - -static void eic_mask_ack_irq(struct irq_data *d) -{ - struct eic *eic = irq_data_get_irq_chip_data(d); - eic_writel(eic, ICR, 1 << (d->irq - eic->first_irq)); - eic_writel(eic, IDR, 1 << (d->irq - eic->first_irq)); -} - -static void eic_unmask_irq(struct irq_data *d) -{ - struct eic *eic = irq_data_get_irq_chip_data(d); - eic_writel(eic, IER, 1 << (d->irq - eic->first_irq)); -} - -static int eic_set_irq_type(struct irq_data *d, unsigned int flow_type) -{ - struct eic *eic = irq_data_get_irq_chip_data(d); - unsigned int irq = d->irq; - unsigned int i = irq - eic->first_irq; - u32 mode, edge, level; - - flow_type &= IRQ_TYPE_SENSE_MASK; - if (flow_type == IRQ_TYPE_NONE) - flow_type = IRQ_TYPE_LEVEL_LOW; - - mode = eic_readl(eic, MODE); - edge = eic_readl(eic, EDGE); - level = eic_readl(eic, LEVEL); - - switch (flow_type) { - case IRQ_TYPE_LEVEL_LOW: - mode |= 1 << i; - level &= ~(1 << i); - break; - case IRQ_TYPE_LEVEL_HIGH: - mode |= 1 << i; - level |= 1 << i; - break; - case IRQ_TYPE_EDGE_RISING: - mode &= ~(1 << i); - edge |= 1 << i; - break; - case IRQ_TYPE_EDGE_FALLING: - mode &= ~(1 << i); - edge &= ~(1 << i); - break; - default: - return -EINVAL; - } - - eic_writel(eic, MODE, mode); - eic_writel(eic, EDGE, edge); - eic_writel(eic, LEVEL, level); - - irqd_set_trigger_type(d, flow_type); - if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) - irq_set_handler_locked(d, handle_level_irq); - else - irq_set_handler_locked(d, handle_edge_irq); - - return IRQ_SET_MASK_OK_NOCOPY; -} - -static struct irq_chip eic_chip = { - .name = "eic", - .irq_ack = eic_ack_irq, - .irq_mask = eic_mask_irq, - .irq_mask_ack = eic_mask_ack_irq, - .irq_unmask = eic_unmask_irq, - .irq_set_type = eic_set_irq_type, -}; - -static void demux_eic_irq(struct irq_desc *desc) -{ - struct eic *eic = irq_desc_get_handler_data(desc); - unsigned long status, pending; - unsigned int i; - - status = eic_readl(eic, ISR); - pending = status & eic_readl(eic, IMR); - - while (pending) { - i = fls(pending) - 1; - pending &= ~(1 << i); - - generic_handle_irq(i + eic->first_irq); - } -} - -int nmi_enable(void) -{ - nmi_enabled = true; - - if (nmi_eic) - eic_writel(nmi_eic, NMIC, EIC_NMIC_ENABLE); - - return 0; -} - -void nmi_disable(void) -{ - if (nmi_eic) - eic_writel(nmi_eic, NMIC, 0); - - nmi_enabled = false; -} - -static int __init eic_probe(struct platform_device *pdev) -{ - struct eic *eic; - struct resource *regs; - unsigned int i; - unsigned int nr_of_irqs; - unsigned int int_irq; - int ret; - u32 pattern; - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - int_irq = platform_get_irq(pdev, 0); - if (!regs || (int)int_irq <= 0) { - dev_dbg(&pdev->dev, "missing regs and/or irq resource\n"); - return -ENXIO; - } - - ret = -ENOMEM; - eic = kzalloc(sizeof(struct eic), GFP_KERNEL); - if (!eic) { - dev_dbg(&pdev->dev, "no memory for eic structure\n"); - goto err_kzalloc; - } - - eic->first_irq = EIM_IRQ_BASE + 32 * pdev->id; - eic->regs = ioremap(regs->start, resource_size(regs)); - if (!eic->regs) { - dev_dbg(&pdev->dev, "failed to map regs\n"); - goto err_ioremap; - } - - /* - * Find out how many interrupt lines that are actually - * implemented in hardware. - */ - eic_writel(eic, IDR, ~0UL); - eic_writel(eic, MODE, ~0UL); - pattern = eic_readl(eic, MODE); - nr_of_irqs = fls(pattern); - - /* Trigger on low level unless overridden by driver */ - eic_writel(eic, EDGE, 0UL); - eic_writel(eic, LEVEL, 0UL); - - eic->chip = &eic_chip; - - for (i = 0; i < nr_of_irqs; i++) { - irq_set_chip_and_handler(eic->first_irq + i, &eic_chip, - handle_level_irq); - irq_set_chip_data(eic->first_irq + i, eic); - } - - irq_set_chained_handler_and_data(int_irq, demux_eic_irq, eic); - - if (pdev->id == 0) { - nmi_eic = eic; - if (nmi_enabled) - /* - * Someone tried to enable NMI before we were - * ready. Do it now. - */ - nmi_enable(); - } - - dev_info(&pdev->dev, - "External Interrupt Controller at 0x%p, IRQ %u\n", - eic->regs, int_irq); - dev_info(&pdev->dev, - "Handling %u external IRQs, starting with IRQ %u\n", - nr_of_irqs, eic->first_irq); - - return 0; - -err_ioremap: - kfree(eic); -err_kzalloc: - return ret; -} - -static struct platform_driver eic_driver = { - .driver = { - .name = "at32_eic", - }, -}; - -static int __init eic_init(void) -{ - return platform_driver_probe(&eic_driver, eic_probe); -} -arch_initcall(eic_init); diff --git a/arch/avr32/mach-at32ap/hmatrix.c b/arch/avr32/mach-at32ap/hmatrix.c deleted file mode 100644 index 48f5ede77468..000000000000 --- a/arch/avr32/mach-at32ap/hmatrix.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * High-Speed Bus Matrix helper functions - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/io.h> - -#include <mach/chip.h> -#include <mach/hmatrix.h> - -static inline void __hmatrix_write_reg(unsigned long offset, u32 value) -{ - __raw_writel(value, (void __iomem __force *)(HMATRIX_BASE + offset)); -} - -static inline u32 __hmatrix_read_reg(unsigned long offset) -{ - return __raw_readl((void __iomem __force *)(HMATRIX_BASE + offset)); -} - -/** - * hmatrix_write_reg - write HMATRIX configuration register - * @offset: register offset - * @value: value to be written to the register at @offset - */ -void hmatrix_write_reg(unsigned long offset, u32 value) -{ - clk_enable(&at32_hmatrix_clk); - __hmatrix_write_reg(offset, value); - __hmatrix_read_reg(offset); - clk_disable(&at32_hmatrix_clk); -} - -/** - * hmatrix_read_reg - read HMATRIX configuration register - * @offset: register offset - * - * Returns the value of the register at @offset. - */ -u32 hmatrix_read_reg(unsigned long offset) -{ - u32 value; - - clk_enable(&at32_hmatrix_clk); - value = __hmatrix_read_reg(offset); - clk_disable(&at32_hmatrix_clk); - - return value; -} - -/** - * hmatrix_sfr_set_bits - set bits in a slave's Special Function Register - * @slave_id: operate on the SFR belonging to this slave - * @mask: mask of bits to be set in the SFR - */ -void hmatrix_sfr_set_bits(unsigned int slave_id, u32 mask) -{ - u32 value; - - clk_enable(&at32_hmatrix_clk); - value = __hmatrix_read_reg(HMATRIX_SFR(slave_id)); - value |= mask; - __hmatrix_write_reg(HMATRIX_SFR(slave_id), value); - __hmatrix_read_reg(HMATRIX_SFR(slave_id)); - clk_disable(&at32_hmatrix_clk); -} - -/** - * hmatrix_sfr_set_bits - clear bits in a slave's Special Function Register - * @slave_id: operate on the SFR belonging to this slave - * @mask: mask of bits to be cleared in the SFR - */ -void hmatrix_sfr_clear_bits(unsigned int slave_id, u32 mask) -{ - u32 value; - - clk_enable(&at32_hmatrix_clk); - value = __hmatrix_read_reg(HMATRIX_SFR(slave_id)); - value &= ~mask; - __hmatrix_write_reg(HMATRIX_SFR(slave_id), value); - __hmatrix_read_reg(HMATRIX_SFR(slave_id)); - clk_disable(&at32_hmatrix_clk); -} diff --git a/arch/avr32/mach-at32ap/hsmc.c b/arch/avr32/mach-at32ap/hsmc.c deleted file mode 100644 index f66245e6e63e..000000000000 --- a/arch/avr32/mach-at32ap/hsmc.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Static Memory Controller for AT32 chips - * - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/slab.h> - -#include <asm/io.h> -#include <mach/smc.h> - -#include "hsmc.h" - -#define NR_CHIP_SELECTS 6 - -struct hsmc { - void __iomem *regs; - struct clk *pclk; - struct clk *mck; -}; - -static struct hsmc *hsmc; - -void smc_set_timing(struct smc_config *config, - const struct smc_timing *timing) -{ - int recover; - int cycle; - - unsigned long mul; - - /* Reset all SMC timings */ - config->ncs_read_setup = 0; - config->nrd_setup = 0; - config->ncs_write_setup = 0; - config->nwe_setup = 0; - config->ncs_read_pulse = 0; - config->nrd_pulse = 0; - config->ncs_write_pulse = 0; - config->nwe_pulse = 0; - config->read_cycle = 0; - config->write_cycle = 0; - - /* - * cycles = x / T = x * f - * = ((x * 1000000000) * ((f * 65536) / 1000000000)) / 65536 - * = ((x * 1000000000) * (((f / 10000) * 65536) / 100000)) / 65536 - */ - mul = (clk_get_rate(hsmc->mck) / 10000) << 16; - mul /= 100000; - -#define ns2cyc(x) ((((x) * mul) + 65535) >> 16) - - if (timing->ncs_read_setup > 0) - config->ncs_read_setup = ns2cyc(timing->ncs_read_setup); - - if (timing->nrd_setup > 0) - config->nrd_setup = ns2cyc(timing->nrd_setup); - - if (timing->ncs_write_setup > 0) - config->ncs_write_setup = ns2cyc(timing->ncs_write_setup); - - if (timing->nwe_setup > 0) - config->nwe_setup = ns2cyc(timing->nwe_setup); - - if (timing->ncs_read_pulse > 0) - config->ncs_read_pulse = ns2cyc(timing->ncs_read_pulse); - - if (timing->nrd_pulse > 0) - config->nrd_pulse = ns2cyc(timing->nrd_pulse); - - if (timing->ncs_write_pulse > 0) - config->ncs_write_pulse = ns2cyc(timing->ncs_write_pulse); - - if (timing->nwe_pulse > 0) - config->nwe_pulse = ns2cyc(timing->nwe_pulse); - - if (timing->read_cycle > 0) - config->read_cycle = ns2cyc(timing->read_cycle); - - if (timing->write_cycle > 0) - config->write_cycle = ns2cyc(timing->write_cycle); - - /* Extend read cycle in needed */ - if (timing->ncs_read_recover > 0) - recover = ns2cyc(timing->ncs_read_recover); - else - recover = 1; - - cycle = config->ncs_read_setup + config->ncs_read_pulse + recover; - - if (config->read_cycle < cycle) - config->read_cycle = cycle; - - /* Extend read cycle in needed */ - if (timing->nrd_recover > 0) - recover = ns2cyc(timing->nrd_recover); - else - recover = 1; - - cycle = config->nrd_setup + config->nrd_pulse + recover; - - if (config->read_cycle < cycle) - config->read_cycle = cycle; - - /* Extend write cycle in needed */ - if (timing->ncs_write_recover > 0) - recover = ns2cyc(timing->ncs_write_recover); - else - recover = 1; - - cycle = config->ncs_write_setup + config->ncs_write_pulse + recover; - - if (config->write_cycle < cycle) - config->write_cycle = cycle; - - /* Extend write cycle in needed */ - if (timing->nwe_recover > 0) - recover = ns2cyc(timing->nwe_recover); - else - recover = 1; - - cycle = config->nwe_setup + config->nwe_pulse + recover; - - if (config->write_cycle < cycle) - config->write_cycle = cycle; -} -EXPORT_SYMBOL(smc_set_timing); - -int smc_set_configuration(int cs, const struct smc_config *config) -{ - unsigned long offset; - u32 setup, pulse, cycle, mode; - - if (!hsmc) - return -ENODEV; - if (cs >= NR_CHIP_SELECTS) - return -EINVAL; - - setup = (HSMC_BF(NWE_SETUP, config->nwe_setup) - | HSMC_BF(NCS_WR_SETUP, config->ncs_write_setup) - | HSMC_BF(NRD_SETUP, config->nrd_setup) - | HSMC_BF(NCS_RD_SETUP, config->ncs_read_setup)); - pulse = (HSMC_BF(NWE_PULSE, config->nwe_pulse) - | HSMC_BF(NCS_WR_PULSE, config->ncs_write_pulse) - | HSMC_BF(NRD_PULSE, config->nrd_pulse) - | HSMC_BF(NCS_RD_PULSE, config->ncs_read_pulse)); - cycle = (HSMC_BF(NWE_CYCLE, config->write_cycle) - | HSMC_BF(NRD_CYCLE, config->read_cycle)); - - switch (config->bus_width) { - case 1: - mode = HSMC_BF(DBW, HSMC_DBW_8_BITS); - break; - case 2: - mode = HSMC_BF(DBW, HSMC_DBW_16_BITS); - break; - case 4: - mode = HSMC_BF(DBW, HSMC_DBW_32_BITS); - break; - default: - return -EINVAL; - } - - switch (config->nwait_mode) { - case 0: - mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_DISABLED); - break; - case 1: - mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_RESERVED); - break; - case 2: - mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_FROZEN); - break; - case 3: - mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_READY); - break; - default: - return -EINVAL; - } - - if (config->tdf_cycles) { - mode |= HSMC_BF(TDF_CYCLES, config->tdf_cycles); - } - - if (config->nrd_controlled) - mode |= HSMC_BIT(READ_MODE); - if (config->nwe_controlled) - mode |= HSMC_BIT(WRITE_MODE); - if (config->byte_write) - mode |= HSMC_BIT(BAT); - if (config->tdf_mode) - mode |= HSMC_BIT(TDF_MODE); - - pr_debug("smc cs%d: setup/%08x pulse/%08x cycle/%08x mode/%08x\n", - cs, setup, pulse, cycle, mode); - - offset = cs * 0x10; - hsmc_writel(hsmc, SETUP0 + offset, setup); - hsmc_writel(hsmc, PULSE0 + offset, pulse); - hsmc_writel(hsmc, CYCLE0 + offset, cycle); - hsmc_writel(hsmc, MODE0 + offset, mode); - hsmc_readl(hsmc, MODE0); /* I/O barrier */ - - return 0; -} -EXPORT_SYMBOL(smc_set_configuration); - -static int hsmc_probe(struct platform_device *pdev) -{ - struct resource *regs; - struct clk *pclk, *mck; - int ret; - - if (hsmc) - return -EBUSY; - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) - return -ENXIO; - pclk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(pclk)) - return PTR_ERR(pclk); - mck = clk_get(&pdev->dev, "mck"); - if (IS_ERR(mck)) { - ret = PTR_ERR(mck); - goto out_put_pclk; - } - - ret = -ENOMEM; - hsmc = kzalloc(sizeof(struct hsmc), GFP_KERNEL); - if (!hsmc) - goto out_put_clocks; - - clk_enable(pclk); - clk_enable(mck); - - hsmc->pclk = pclk; - hsmc->mck = mck; - hsmc->regs = ioremap(regs->start, resource_size(regs)); - if (!hsmc->regs) - goto out_disable_clocks; - - dev_info(&pdev->dev, "Atmel Static Memory Controller at 0x%08lx\n", - (unsigned long)regs->start); - - platform_set_drvdata(pdev, hsmc); - - return 0; - -out_disable_clocks: - clk_disable(mck); - clk_disable(pclk); - kfree(hsmc); -out_put_clocks: - clk_put(mck); -out_put_pclk: - clk_put(pclk); - hsmc = NULL; - return ret; -} - -static struct platform_driver hsmc_driver = { - .probe = hsmc_probe, - .driver = { - .name = "smc", - }, -}; - -static int __init hsmc_init(void) -{ - return platform_driver_register(&hsmc_driver); -} -core_initcall(hsmc_init); diff --git a/arch/avr32/mach-at32ap/hsmc.h b/arch/avr32/mach-at32ap/hsmc.h deleted file mode 100644 index d1d48e26e393..000000000000 --- a/arch/avr32/mach-at32ap/hsmc.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Register definitions for Atmel Static Memory Controller (SMC) - * - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_HSMC_H__ -#define __ASM_AVR32_HSMC_H__ - -/* HSMC register offsets */ -#define HSMC_SETUP0 0x0000 -#define HSMC_PULSE0 0x0004 -#define HSMC_CYCLE0 0x0008 -#define HSMC_MODE0 0x000c -#define HSMC_SETUP1 0x0010 -#define HSMC_PULSE1 0x0014 -#define HSMC_CYCLE1 0x0018 -#define HSMC_MODE1 0x001c -#define HSMC_SETUP2 0x0020 -#define HSMC_PULSE2 0x0024 -#define HSMC_CYCLE2 0x0028 -#define HSMC_MODE2 0x002c -#define HSMC_SETUP3 0x0030 -#define HSMC_PULSE3 0x0034 -#define HSMC_CYCLE3 0x0038 -#define HSMC_MODE3 0x003c -#define HSMC_SETUP4 0x0040 -#define HSMC_PULSE4 0x0044 -#define HSMC_CYCLE4 0x0048 -#define HSMC_MODE4 0x004c -#define HSMC_SETUP5 0x0050 -#define HSMC_PULSE5 0x0054 -#define HSMC_CYCLE5 0x0058 -#define HSMC_MODE5 0x005c - -/* Bitfields in SETUP0 */ -#define HSMC_NWE_SETUP_OFFSET 0 -#define HSMC_NWE_SETUP_SIZE 6 -#define HSMC_NCS_WR_SETUP_OFFSET 8 -#define HSMC_NCS_WR_SETUP_SIZE 6 -#define HSMC_NRD_SETUP_OFFSET 16 -#define HSMC_NRD_SETUP_SIZE 6 -#define HSMC_NCS_RD_SETUP_OFFSET 24 -#define HSMC_NCS_RD_SETUP_SIZE 6 - -/* Bitfields in PULSE0 */ -#define HSMC_NWE_PULSE_OFFSET 0 -#define HSMC_NWE_PULSE_SIZE 7 -#define HSMC_NCS_WR_PULSE_OFFSET 8 -#define HSMC_NCS_WR_PULSE_SIZE 7 -#define HSMC_NRD_PULSE_OFFSET 16 -#define HSMC_NRD_PULSE_SIZE 7 -#define HSMC_NCS_RD_PULSE_OFFSET 24 -#define HSMC_NCS_RD_PULSE_SIZE 7 - -/* Bitfields in CYCLE0 */ -#define HSMC_NWE_CYCLE_OFFSET 0 -#define HSMC_NWE_CYCLE_SIZE 9 -#define HSMC_NRD_CYCLE_OFFSET 16 -#define HSMC_NRD_CYCLE_SIZE 9 - -/* Bitfields in MODE0 */ -#define HSMC_READ_MODE_OFFSET 0 -#define HSMC_READ_MODE_SIZE 1 -#define HSMC_WRITE_MODE_OFFSET 1 -#define HSMC_WRITE_MODE_SIZE 1 -#define HSMC_EXNW_MODE_OFFSET 4 -#define HSMC_EXNW_MODE_SIZE 2 -#define HSMC_BAT_OFFSET 8 -#define HSMC_BAT_SIZE 1 -#define HSMC_DBW_OFFSET 12 -#define HSMC_DBW_SIZE 2 -#define HSMC_TDF_CYCLES_OFFSET 16 -#define HSMC_TDF_CYCLES_SIZE 4 -#define HSMC_TDF_MODE_OFFSET 20 -#define HSMC_TDF_MODE_SIZE 1 -#define HSMC_PMEN_OFFSET 24 -#define HSMC_PMEN_SIZE 1 -#define HSMC_PS_OFFSET 28 -#define HSMC_PS_SIZE 2 - -/* Constants for READ_MODE */ -#define HSMC_READ_MODE_NCS_CONTROLLED 0 -#define HSMC_READ_MODE_NRD_CONTROLLED 1 - -/* Constants for WRITE_MODE */ -#define HSMC_WRITE_MODE_NCS_CONTROLLED 0 -#define HSMC_WRITE_MODE_NWE_CONTROLLED 1 - -/* Constants for EXNW_MODE */ -#define HSMC_EXNW_MODE_DISABLED 0 -#define HSMC_EXNW_MODE_RESERVED 1 -#define HSMC_EXNW_MODE_FROZEN 2 -#define HSMC_EXNW_MODE_READY 3 - -/* Constants for BAT */ -#define HSMC_BAT_BYTE_SELECT 0 -#define HSMC_BAT_BYTE_WRITE 1 - -/* Constants for DBW */ -#define HSMC_DBW_8_BITS 0 -#define HSMC_DBW_16_BITS 1 -#define HSMC_DBW_32_BITS 2 - -/* Bit manipulation macros */ -#define HSMC_BIT(name) \ - (1 << HSMC_##name##_OFFSET) -#define HSMC_BF(name,value) \ - (((value) & ((1 << HSMC_##name##_SIZE) - 1)) \ - << HSMC_##name##_OFFSET) -#define HSMC_BFEXT(name,value) \ - (((value) >> HSMC_##name##_OFFSET) \ - & ((1 << HSMC_##name##_SIZE) - 1)) -#define HSMC_BFINS(name,value,old) \ - (((old) & ~(((1 << HSMC_##name##_SIZE) - 1) \ - << HSMC_##name##_OFFSET)) | HSMC_BF(name,value)) - -/* Register access macros */ -#define hsmc_readl(port,reg) \ - __raw_readl((port)->regs + HSMC_##reg) -#define hsmc_writel(port,reg,value) \ - __raw_writel((value), (port)->regs + HSMC_##reg) - -#endif /* __ASM_AVR32_HSMC_H__ */ diff --git a/arch/avr32/mach-at32ap/include/mach/at32ap700x.h b/arch/avr32/mach-at32ap/include/mach/at32ap700x.h deleted file mode 100644 index b9222bf895bc..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/at32ap700x.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Pin definitions for AT32AP7000. - * - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_ARCH_AT32AP700X_H__ -#define __ASM_ARCH_AT32AP700X_H__ - -#define GPIO_PERIPH_A 0 -#define GPIO_PERIPH_B 1 - -/* - * Pin numbers identifying specific GPIO pins on the chip. They can - * also be converted to IRQ numbers by passing them through - * gpio_to_irq(). - */ -#define GPIO_PIOA_BASE (0) -#define GPIO_PIOB_BASE (GPIO_PIOA_BASE + 32) -#define GPIO_PIOC_BASE (GPIO_PIOB_BASE + 32) -#define GPIO_PIOD_BASE (GPIO_PIOC_BASE + 32) -#define GPIO_PIOE_BASE (GPIO_PIOD_BASE + 32) - -#define GPIO_PIN_PA(N) (GPIO_PIOA_BASE + (N)) -#define GPIO_PIN_PB(N) (GPIO_PIOB_BASE + (N)) -#define GPIO_PIN_PC(N) (GPIO_PIOC_BASE + (N)) -#define GPIO_PIN_PD(N) (GPIO_PIOD_BASE + (N)) -#define GPIO_PIN_PE(N) (GPIO_PIOE_BASE + (N)) - - -/* - * DMAC peripheral hardware handshaking interfaces, used with dw_dmac - */ -#define DMAC_MCI_RX 0 -#define DMAC_MCI_TX 1 -#define DMAC_DAC_TX 2 -#define DMAC_AC97_A_RX 3 -#define DMAC_AC97_A_TX 4 -#define DMAC_AC97_B_RX 5 -#define DMAC_AC97_B_TX 6 -#define DMAC_DMAREQ_0 7 -#define DMAC_DMAREQ_1 8 -#define DMAC_DMAREQ_2 9 -#define DMAC_DMAREQ_3 10 - -/* HSB master IDs */ -#define HMATRIX_MASTER_CPU_DCACHE 0 -#define HMATRIX_MASTER_CPU_ICACHE 1 -#define HMATRIX_MASTER_PDC 2 -#define HMATRIX_MASTER_ISI 3 -#define HMATRIX_MASTER_USBA 4 -#define HMATRIX_MASTER_LCDC 5 -#define HMATRIX_MASTER_MACB0 6 -#define HMATRIX_MASTER_MACB1 7 -#define HMATRIX_MASTER_DMACA_M0 8 -#define HMATRIX_MASTER_DMACA_M1 9 - -/* HSB slave IDs */ -#define HMATRIX_SLAVE_SRAM0 0 -#define HMATRIX_SLAVE_SRAM1 1 -#define HMATRIX_SLAVE_PBA 2 -#define HMATRIX_SLAVE_PBB 3 -#define HMATRIX_SLAVE_EBI 4 -#define HMATRIX_SLAVE_USBA 5 -#define HMATRIX_SLAVE_LCDC 6 -#define HMATRIX_SLAVE_DMACA 7 - -/* Bits in HMATRIX SFR4 (EBI) */ -#define HMATRIX_EBI_SDRAM_ENABLE (1 << 1) -#define HMATRIX_EBI_NAND_ENABLE (1 << 3) -#define HMATRIX_EBI_CF0_ENABLE (1 << 4) -#define HMATRIX_EBI_CF1_ENABLE (1 << 5) -#define HMATRIX_EBI_PULLUP_DISABLE (1 << 8) - -/* - * Base addresses of controllers that may be accessed early by - * platform code. - */ -#define PM_BASE 0xfff00000 -#define HMATRIX_BASE 0xfff00800 -#define SDRAMC_BASE 0xfff03800 - -/* LCDC on port C */ -#define ATMEL_LCDC_PC_CC (1ULL << 19) -#define ATMEL_LCDC_PC_HSYNC (1ULL << 20) -#define ATMEL_LCDC_PC_PCLK (1ULL << 21) -#define ATMEL_LCDC_PC_VSYNC (1ULL << 22) -#define ATMEL_LCDC_PC_DVAL (1ULL << 23) -#define ATMEL_LCDC_PC_MODE (1ULL << 24) -#define ATMEL_LCDC_PC_PWR (1ULL << 25) -#define ATMEL_LCDC_PC_DATA0 (1ULL << 26) -#define ATMEL_LCDC_PC_DATA1 (1ULL << 27) -#define ATMEL_LCDC_PC_DATA2 (1ULL << 28) -#define ATMEL_LCDC_PC_DATA3 (1ULL << 29) -#define ATMEL_LCDC_PC_DATA4 (1ULL << 30) -#define ATMEL_LCDC_PC_DATA5 (1ULL << 31) - -/* LCDC on port D */ -#define ATMEL_LCDC_PD_DATA6 (1ULL << 0) -#define ATMEL_LCDC_PD_DATA7 (1ULL << 1) -#define ATMEL_LCDC_PD_DATA8 (1ULL << 2) -#define ATMEL_LCDC_PD_DATA9 (1ULL << 3) -#define ATMEL_LCDC_PD_DATA10 (1ULL << 4) -#define ATMEL_LCDC_PD_DATA11 (1ULL << 5) -#define ATMEL_LCDC_PD_DATA12 (1ULL << 6) -#define ATMEL_LCDC_PD_DATA13 (1ULL << 7) -#define ATMEL_LCDC_PD_DATA14 (1ULL << 8) -#define ATMEL_LCDC_PD_DATA15 (1ULL << 9) -#define ATMEL_LCDC_PD_DATA16 (1ULL << 10) -#define ATMEL_LCDC_PD_DATA17 (1ULL << 11) -#define ATMEL_LCDC_PD_DATA18 (1ULL << 12) -#define ATMEL_LCDC_PD_DATA19 (1ULL << 13) -#define ATMEL_LCDC_PD_DATA20 (1ULL << 14) -#define ATMEL_LCDC_PD_DATA21 (1ULL << 15) -#define ATMEL_LCDC_PD_DATA22 (1ULL << 16) -#define ATMEL_LCDC_PD_DATA23 (1ULL << 17) - -/* LCDC on port E */ -#define ATMEL_LCDC_PE_CC (1ULL << (32 + 0)) -#define ATMEL_LCDC_PE_DVAL (1ULL << (32 + 1)) -#define ATMEL_LCDC_PE_MODE (1ULL << (32 + 2)) -#define ATMEL_LCDC_PE_DATA0 (1ULL << (32 + 3)) -#define ATMEL_LCDC_PE_DATA1 (1ULL << (32 + 4)) -#define ATMEL_LCDC_PE_DATA2 (1ULL << (32 + 5)) -#define ATMEL_LCDC_PE_DATA3 (1ULL << (32 + 6)) -#define ATMEL_LCDC_PE_DATA4 (1ULL << (32 + 7)) -#define ATMEL_LCDC_PE_DATA8 (1ULL << (32 + 8)) -#define ATMEL_LCDC_PE_DATA9 (1ULL << (32 + 9)) -#define ATMEL_LCDC_PE_DATA10 (1ULL << (32 + 10)) -#define ATMEL_LCDC_PE_DATA11 (1ULL << (32 + 11)) -#define ATMEL_LCDC_PE_DATA12 (1ULL << (32 + 12)) -#define ATMEL_LCDC_PE_DATA16 (1ULL << (32 + 13)) -#define ATMEL_LCDC_PE_DATA17 (1ULL << (32 + 14)) -#define ATMEL_LCDC_PE_DATA18 (1ULL << (32 + 15)) -#define ATMEL_LCDC_PE_DATA19 (1ULL << (32 + 16)) -#define ATMEL_LCDC_PE_DATA20 (1ULL << (32 + 17)) -#define ATMEL_LCDC_PE_DATA21 (1ULL << (32 + 18)) - - -#define ATMEL_LCDC(PORT, PIN) (ATMEL_LCDC_##PORT##_##PIN) - - -#define ATMEL_LCDC_PRI_24B_DATA ( \ - ATMEL_LCDC(PC, DATA0) | ATMEL_LCDC(PC, DATA1) | \ - ATMEL_LCDC(PC, DATA2) | ATMEL_LCDC(PC, DATA3) | \ - ATMEL_LCDC(PC, DATA4) | ATMEL_LCDC(PC, DATA5) | \ - ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \ - ATMEL_LCDC(PD, DATA8) | ATMEL_LCDC(PD, DATA9) | \ - ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) | \ - ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA13) | \ - ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \ - ATMEL_LCDC(PD, DATA16) | ATMEL_LCDC(PD, DATA17) | \ - ATMEL_LCDC(PD, DATA18) | ATMEL_LCDC(PD, DATA19) | \ - ATMEL_LCDC(PD, DATA20) | ATMEL_LCDC(PD, DATA21) | \ - ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23)) - -#define ATMEL_LCDC_ALT_24B_DATA ( \ - ATMEL_LCDC(PE, DATA0) | ATMEL_LCDC(PE, DATA1) | \ - ATMEL_LCDC(PE, DATA2) | ATMEL_LCDC(PE, DATA3) | \ - ATMEL_LCDC(PE, DATA4) | ATMEL_LCDC(PC, DATA5) | \ - ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \ - ATMEL_LCDC(PE, DATA8) | ATMEL_LCDC(PE, DATA9) | \ - ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) | \ - ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PD, DATA13) | \ - ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \ - ATMEL_LCDC(PE, DATA16) | ATMEL_LCDC(PE, DATA17) | \ - ATMEL_LCDC(PE, DATA18) | ATMEL_LCDC(PE, DATA19) | \ - ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) | \ - ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23)) - -#define ATMEL_LCDC_PRI_18B_DATA ( \ - ATMEL_LCDC(PC, DATA2) | ATMEL_LCDC(PC, DATA3) | \ - ATMEL_LCDC(PC, DATA4) | ATMEL_LCDC(PC, DATA5) | \ - ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \ - ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) | \ - ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA13) | \ - ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \ - ATMEL_LCDC(PD, DATA18) | ATMEL_LCDC(PD, DATA19) | \ - ATMEL_LCDC(PD, DATA20) | ATMEL_LCDC(PD, DATA21) | \ - ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23)) - -#define ATMEL_LCDC_ALT_18B_DATA ( \ - ATMEL_LCDC(PE, DATA2) | ATMEL_LCDC(PE, DATA3) | \ - ATMEL_LCDC(PE, DATA4) | ATMEL_LCDC(PC, DATA5) | \ - ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \ - ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) | \ - ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PD, DATA13) | \ - ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \ - ATMEL_LCDC(PE, DATA18) | ATMEL_LCDC(PE, DATA19) | \ - ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) | \ - ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23)) - -#define ATMEL_LCDC_PRI_15B_DATA ( \ - ATMEL_LCDC(PC, DATA3) | ATMEL_LCDC(PC, DATA4) | \ - ATMEL_LCDC(PC, DATA5) | ATMEL_LCDC(PD, DATA6) | \ - ATMEL_LCDC(PD, DATA7) | \ - ATMEL_LCDC(PD, DATA11) | ATMEL_LCDC(PD, DATA12) | \ - ATMEL_LCDC(PD, DATA13) | ATMEL_LCDC(PD, DATA14) | \ - ATMEL_LCDC(PD, DATA15) | \ - ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20) | \ - ATMEL_LCDC(PD, DATA21) | ATMEL_LCDC(PD, DATA22) | \ - ATMEL_LCDC(PD, DATA23)) - -#define ATMEL_LCDC_ALT_15B_DATA ( \ - ATMEL_LCDC(PE, DATA3) | ATMEL_LCDC(PE, DATA4) | \ - ATMEL_LCDC(PC, DATA5) | ATMEL_LCDC(PD, DATA6) | \ - ATMEL_LCDC(PD, DATA7) | \ - ATMEL_LCDC(PE, DATA11) | ATMEL_LCDC(PE, DATA12) | \ - ATMEL_LCDC(PD, DATA13) | ATMEL_LCDC(PD, DATA14) | \ - ATMEL_LCDC(PD, DATA15) | \ - ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20) | \ - ATMEL_LCDC(PE, DATA21) | ATMEL_LCDC(PD, DATA22) | \ - ATMEL_LCDC(PD, DATA23)) - -#define ATMEL_LCDC_PRI_CONTROL ( \ - ATMEL_LCDC(PC, CC) | ATMEL_LCDC(PC, DVAL) | \ - ATMEL_LCDC(PC, MODE) | ATMEL_LCDC(PC, PWR)) - -#define ATMEL_LCDC_ALT_CONTROL ( \ - ATMEL_LCDC(PE, CC) | ATMEL_LCDC(PE, DVAL) | \ - ATMEL_LCDC(PE, MODE) | ATMEL_LCDC(PC, PWR)) - -#define ATMEL_LCDC_CONTROL ( \ - ATMEL_LCDC(PC, HSYNC) | ATMEL_LCDC(PC, VSYNC) | \ - ATMEL_LCDC(PC, PCLK)) - -#define ATMEL_LCDC_PRI_24BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_24B_DATA) - -#define ATMEL_LCDC_ALT_24BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_24B_DATA) - -#define ATMEL_LCDC_PRI_18BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_18B_DATA) - -#define ATMEL_LCDC_ALT_18BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_18B_DATA) - -#define ATMEL_LCDC_PRI_15BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_15B_DATA) - -#define ATMEL_LCDC_ALT_15BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_15B_DATA) - -/* Bitmask for all EBI data (D16..D31) pins on port E */ -#define ATMEL_EBI_PE_DATA_ALL (0x0000FFFF) - -#endif /* __ASM_ARCH_AT32AP700X_H__ */ diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h deleted file mode 100644 index f1a316d52c73..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/board.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Platform data definitions. - */ -#ifndef __ASM_ARCH_BOARD_H -#define __ASM_ARCH_BOARD_H - -#include <linux/types.h> -#include <linux/serial.h> -#include <linux/platform_data/macb.h> -#include <linux/platform_data/atmel.h> - -#define GPIO_PIN_NONE (-1) - -/* - * Clock rates for various on-board oscillators. The number of entries - * in this array is chip-dependent. - */ -extern unsigned long at32_board_osc_rates[]; - -/* - * This used to add essential system devices, but this is now done - * automatically. Please don't use it in new board code. - */ -static inline void __deprecated at32_add_system_devices(void) -{ - -} - -extern struct platform_device *atmel_default_console_device; - -/* Flags for selecting USART extra pins */ -#define ATMEL_USART_RTS 0x01 -#define ATMEL_USART_CTS 0x02 -#define ATMEL_USART_CLK 0x04 - -void at32_map_usart(unsigned int hw_id, unsigned int line, int flags); -struct platform_device *at32_add_device_usart(unsigned int id); - -struct platform_device * -at32_add_device_eth(unsigned int id, struct macb_platform_data *data); - -struct spi_board_info; -struct platform_device * -at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n); -void at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b, unsigned int n); - -struct atmel_lcdfb_pdata; -struct platform_device * -at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_pdata *data, - unsigned long fbmem_start, unsigned long fbmem_len, - u64 pin_mask); - -struct usba_platform_data; -struct platform_device * -at32_add_device_usba(unsigned int id, struct usba_platform_data *data); - -struct ide_platform_data { - u8 cs; -}; -struct platform_device * -at32_add_device_ide(unsigned int id, unsigned int extint, - struct ide_platform_data *data); - -/* mask says which PWM channels to mux */ -struct platform_device *at32_add_device_pwm(u32 mask); - -/* depending on what's hooked up, not all SSC pins will be used */ -#define ATMEL_SSC_TK 0x01 -#define ATMEL_SSC_TF 0x02 -#define ATMEL_SSC_TD 0x04 -#define ATMEL_SSC_TX (ATMEL_SSC_TK | ATMEL_SSC_TF | ATMEL_SSC_TD) - -#define ATMEL_SSC_RK 0x10 -#define ATMEL_SSC_RF 0x20 -#define ATMEL_SSC_RD 0x40 -#define ATMEL_SSC_RX (ATMEL_SSC_RK | ATMEL_SSC_RF | ATMEL_SSC_RD) - -struct platform_device * -at32_add_device_ssc(unsigned int id, unsigned int flags); - -struct i2c_board_info; -struct platform_device *at32_add_device_twi(unsigned int id, - struct i2c_board_info *b, - unsigned int n); - -struct mci_platform_data; -struct platform_device * -at32_add_device_mci(unsigned int id, struct mci_platform_data *data); - -struct ac97c_platform_data; -struct platform_device * -at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data, - unsigned int flags); - -struct atmel_abdac_pdata; -struct platform_device * -at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data); - -struct platform_device *at32_add_device_psif(unsigned int id); - -struct cf_platform_data { - int detect_pin; - int reset_pin; - int vcc_pin; - int ready_pin; - u8 cs; -}; -struct platform_device * -at32_add_device_cf(unsigned int id, unsigned int extint, - struct cf_platform_data *data); - -struct platform_device * -at32_add_device_nand(unsigned int id, struct atmel_nand_data *data); - -#endif /* __ASM_ARCH_BOARD_H */ diff --git a/arch/avr32/mach-at32ap/include/mach/chip.h b/arch/avr32/mach-at32ap/include/mach/chip.h deleted file mode 100644 index 5efca6da6acb..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/chip.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * AVR32 chip-specific definitions - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_ARCH_CHIP_H__ -#define __ASM_AVR32_ARCH_CHIP_H__ - -#if defined(CONFIG_CPU_AT32AP700X) -# include <mach/at32ap700x.h> -#else -# error Unknown chip type selected -#endif - -#endif /* __ASM_AVR32_ARCH_CHIP_H__ */ diff --git a/arch/avr32/mach-at32ap/include/mach/cpu.h b/arch/avr32/mach-at32ap/include/mach/cpu.h deleted file mode 100644 index 4181086f4ddc..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/cpu.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * AVR32 CPU identification - * - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_ARCH_CPU_H -#define __ASM_ARCH_CPU_H - -/* - * Only AT32AP7000 is defined for now. We can identify the specific - * chip at runtime, but I'm not sure if it's really worth it. - */ -#ifdef CONFIG_CPU_AT32AP700X -# define cpu_is_at32ap7000() (1) -#else -# define cpu_is_at32ap7000() (0) -#endif - -#endif /* __ASM_ARCH_CPU_H */ diff --git a/arch/avr32/mach-at32ap/include/mach/gpio.h b/arch/avr32/mach-at32ap/include/mach/gpio.h deleted file mode 100644 index 0180f584ef03..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/gpio.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __ASM_AVR32_ARCH_GPIO_H -#define __ASM_AVR32_ARCH_GPIO_H - -#include <linux/compiler.h> -#include <asm/irq.h> - - -/* Some GPIO chips can manage IRQs; some can't. The exact numbers can - * be changed if needed, but for the moment they're not configurable. - */ -#define ARCH_NR_GPIOS (NR_GPIO_IRQS + 2 * 32) - - -/* Arch-neutral GPIO API, supporting both "native" and external GPIOs. */ -#include <asm-generic/gpio.h> - -static inline int gpio_get_value(unsigned int gpio) -{ - return __gpio_get_value(gpio); -} - -static inline void gpio_set_value(unsigned int gpio, int value) -{ - __gpio_set_value(gpio, value); -} - -static inline int gpio_cansleep(unsigned int gpio) -{ - return __gpio_cansleep(gpio); -} - - -static inline int gpio_to_irq(unsigned int gpio) -{ - if (gpio < NR_GPIO_IRQS) - return gpio + GPIO_IRQ_BASE; - return -EINVAL; -} - -static inline int irq_to_gpio(unsigned int irq) -{ - return irq - GPIO_IRQ_BASE; -} - -#endif /* __ASM_AVR32_ARCH_GPIO_H */ diff --git a/arch/avr32/mach-at32ap/include/mach/hmatrix.h b/arch/avr32/mach-at32ap/include/mach/hmatrix.h deleted file mode 100644 index 7a368f227ebc..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/hmatrix.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * High-Speed Bus Matrix configuration registers - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __HMATRIX_H -#define __HMATRIX_H - -extern struct clk at32_hmatrix_clk; - -void hmatrix_write_reg(unsigned long offset, u32 value); -u32 hmatrix_read_reg(unsigned long offset); - -void hmatrix_sfr_set_bits(unsigned int slave_id, u32 mask); -void hmatrix_sfr_clear_bits(unsigned int slave_id, u32 mask); - -/* Master Configuration register */ -#define HMATRIX_MCFG(m) (0x0000 + 4 * (m)) -/* Undefined length burst limit */ -# define HMATRIX_MCFG_ULBT_INFINITE 0 /* Infinite length */ -# define HMATRIX_MCFG_ULBT_SINGLE 1 /* Single Access */ -# define HMATRIX_MCFG_ULBT_FOUR_BEAT 2 /* Four beat */ -# define HMATRIX_MCFG_ULBT_EIGHT_BEAT 3 /* Eight beat */ -# define HMATRIX_MCFG_ULBT_SIXTEEN_BEAT 4 /* Sixteen beat */ - -/* Slave Configuration register */ -#define HMATRIX_SCFG(s) (0x0040 + 4 * (s)) -# define HMATRIX_SCFG_SLOT_CYCLE(x) ((x) << 0) /* Max burst cycles */ -# define HMATRIX_SCFG_DEFMSTR_NONE ( 0 << 16) /* No default master */ -# define HMATRIX_SCFG_DEFMSTR_LAST ( 1 << 16) /* Last def master */ -# define HMATRIX_SCFG_DEFMSTR_FIXED ( 2 << 16) /* Fixed def master */ -# define HMATRIX_SCFG_FIXED_DEFMSTR(m) ((m) << 18) /* Fixed master ID */ -# define HMATRIX_SCFG_ARBT_ROUND_ROBIN ( 0 << 24) /* RR arbitration */ -# define HMATRIX_SCFG_ARBT_FIXED_PRIO ( 1 << 24) /* Fixed priority */ - -/* Slave Priority register A (master 0..7) */ -#define HMATRIX_PRAS(s) (0x0080 + 8 * (s)) -# define HMATRIX_PRAS_PRIO(m, p) ((p) << ((m) * 4)) - -/* Slave Priority register A (master 8..15) */ -#define HMATRIX_PRBS(s) (0x0084 + 8 * (s)) -# define HMATRIX_PRBS_PRIO(m, p) ((p) << (((m) - 8) * 4)) - -/* Master Remap Control Register */ -#define HMATRIX_MRCR 0x0100 -# define HMATRIX_MRCR_REMAP(m) ( 1 << (m)) /* Remap master m */ - -/* Special Function Register. Bit definitions are chip-specific */ -#define HMATRIX_SFR(s) (0x0110 + 4 * (s)) - -#endif /* __HMATRIX_H */ diff --git a/arch/avr32/mach-at32ap/include/mach/init.h b/arch/avr32/mach-at32ap/include/mach/init.h deleted file mode 100644 index bc40e3d46150..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/init.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * AT32AP platform initialization calls. - * - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_AT32AP_INIT_H__ -#define __ASM_AVR32_AT32AP_INIT_H__ - -void setup_platform(void); -void setup_board(void); - -void at32_setup_serial_console(unsigned int usart_id); - -#endif /* __ASM_AVR32_AT32AP_INIT_H__ */ diff --git a/arch/avr32/mach-at32ap/include/mach/io.h b/arch/avr32/mach-at32ap/include/mach/io.h deleted file mode 100644 index 22ea79b74052..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/io.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __ASM_AVR32_ARCH_AT32AP_IO_H -#define __ASM_AVR32_ARCH_AT32AP_IO_H - -#include <linux/swab.h> - -#if defined(CONFIG_AP700X_32_BIT_SMC) -# define __swizzle_addr_b(addr) (addr ^ 3UL) -# define __swizzle_addr_w(addr) (addr ^ 2UL) -# define __swizzle_addr_l(addr) (addr) -# define ioswabb(a, x) (x) -# define ioswabw(a, x) (x) -# define ioswabl(a, x) (x) -# define __mem_ioswabb(a, x) (x) -# define __mem_ioswabw(a, x) swab16(x) -# define __mem_ioswabl(a, x) swab32(x) -#elif defined(CONFIG_AP700X_16_BIT_SMC) -# define __swizzle_addr_b(addr) (addr ^ 1UL) -# define __swizzle_addr_w(addr) (addr) -# define __swizzle_addr_l(addr) (addr) -# define ioswabb(a, x) (x) -# define ioswabw(a, x) (x) -# define ioswabl(a, x) swahw32(x) -# define __mem_ioswabb(a, x) (x) -# define __mem_ioswabw(a, x) swab16(x) -# define __mem_ioswabl(a, x) swahb32(x) -#else -# define __swizzle_addr_b(addr) (addr) -# define __swizzle_addr_w(addr) (addr) -# define __swizzle_addr_l(addr) (addr) -# define ioswabb(a, x) (x) -# define ioswabw(a, x) swab16(x) -# define ioswabl(a, x) swab32(x) -# define __mem_ioswabb(a, x) (x) -# define __mem_ioswabw(a, x) (x) -# define __mem_ioswabl(a, x) (x) -#endif - -#endif /* __ASM_AVR32_ARCH_AT32AP_IO_H */ diff --git a/arch/avr32/mach-at32ap/include/mach/irq.h b/arch/avr32/mach-at32ap/include/mach/irq.h deleted file mode 100644 index 608e350368c7..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/irq.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __ASM_AVR32_ARCH_IRQ_H -#define __ASM_AVR32_ARCH_IRQ_H - -#define EIM_IRQ_BASE NR_INTERNAL_IRQS -#define NR_EIM_IRQS 32 -#define AT32_EXTINT(n) (EIM_IRQ_BASE + (n)) - -#define GPIO_IRQ_BASE (EIM_IRQ_BASE + NR_EIM_IRQS) -#define NR_GPIO_CTLR (5 /*internal*/ + 1 /*external*/) -#define NR_GPIO_IRQS (NR_GPIO_CTLR * 32) - -#define NR_IRQS (GPIO_IRQ_BASE + NR_GPIO_IRQS) - -#endif /* __ASM_AVR32_ARCH_IRQ_H */ diff --git a/arch/avr32/mach-at32ap/include/mach/pm.h b/arch/avr32/mach-at32ap/include/mach/pm.h deleted file mode 100644 index f29ff2cd23d3..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/pm.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * AVR32 AP Power Management. - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_ARCH_PM_H -#define __ASM_AVR32_ARCH_PM_H - -/* Possible arguments to the "sleep" instruction */ -#define CPU_SLEEP_IDLE 0 -#define CPU_SLEEP_FROZEN 1 -#define CPU_SLEEP_STANDBY 2 -#define CPU_SLEEP_STOP 3 -#define CPU_SLEEP_STATIC 5 - -#ifndef __ASSEMBLY__ -extern void cpu_enter_idle(void); -extern void cpu_enter_standby(unsigned long sdramc_base); - -void intc_set_suspend_handler(unsigned long offset); -#endif - -#endif /* __ASM_AVR32_ARCH_PM_H */ diff --git a/arch/avr32/mach-at32ap/include/mach/portmux.h b/arch/avr32/mach-at32ap/include/mach/portmux.h deleted file mode 100644 index 4873024e3b96..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/portmux.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * AT32 portmux interface. - * - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_ARCH_PORTMUX_H__ -#define __ASM_ARCH_PORTMUX_H__ - -/* - * Set up pin multiplexing, called from board init only. - * - * The following flags determine the initial state of the pin. - */ -#define AT32_GPIOF_PULLUP 0x00000001 /* (not-OUT) Enable pull-up */ -#define AT32_GPIOF_OUTPUT 0x00000002 /* (OUT) Enable output driver */ -#define AT32_GPIOF_HIGH 0x00000004 /* (OUT) Set output high */ -#define AT32_GPIOF_DEGLITCH 0x00000008 /* (IN) Filter glitches */ -#define AT32_GPIOF_MULTIDRV 0x00000010 /* Enable multidriver option */ - -void at32_select_periph(unsigned int port, unsigned int pin, - unsigned int periph, unsigned long flags); -void at32_select_gpio(unsigned int pin, unsigned long flags); -void at32_deselect_pin(unsigned int pin); -void at32_reserve_pin(unsigned int port, u32 pin_mask); - -#endif /* __ASM_ARCH_PORTMUX_H__ */ diff --git a/arch/avr32/mach-at32ap/include/mach/smc.h b/arch/avr32/mach-at32ap/include/mach/smc.h deleted file mode 100644 index c98eea44a70a..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/smc.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Static Memory Controller for AT32 chips - * - * Copyright (C) 2006 Atmel Corporation - * - * Inspired by the OMAP2 General-Purpose Memory Controller interface - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ARCH_AT32AP_SMC_H -#define __ARCH_AT32AP_SMC_H - -/* - * All timing parameters are in nanoseconds. - */ -struct smc_timing { - /* Delay from address valid to assertion of given strobe */ - int ncs_read_setup; - int nrd_setup; - int ncs_write_setup; - int nwe_setup; - - /* Pulse length of given strobe */ - int ncs_read_pulse; - int nrd_pulse; - int ncs_write_pulse; - int nwe_pulse; - - /* Total cycle length of given operation */ - int read_cycle; - int write_cycle; - - /* Minimal recovery times, will extend cycle if needed */ - int ncs_read_recover; - int nrd_recover; - int ncs_write_recover; - int nwe_recover; -}; - -/* - * All timing parameters are in clock cycles. - */ -struct smc_config { - - /* Delay from address valid to assertion of given strobe */ - u8 ncs_read_setup; - u8 nrd_setup; - u8 ncs_write_setup; - u8 nwe_setup; - - /* Pulse length of given strobe */ - u8 ncs_read_pulse; - u8 nrd_pulse; - u8 ncs_write_pulse; - u8 nwe_pulse; - - /* Total cycle length of given operation */ - u8 read_cycle; - u8 write_cycle; - - /* Bus width in bytes */ - u8 bus_width; - - /* - * 0: Data is sampled on rising edge of NCS - * 1: Data is sampled on rising edge of NRD - */ - unsigned int nrd_controlled:1; - - /* - * 0: Data is driven on falling edge of NCS - * 1: Data is driven on falling edge of NWR - */ - unsigned int nwe_controlled:1; - - /* - * 0: NWAIT is disabled - * 1: Reserved - * 2: NWAIT is frozen mode - * 3: NWAIT in ready mode - */ - unsigned int nwait_mode:2; - - /* - * 0: Byte select access type - * 1: Byte write access type - */ - unsigned int byte_write:1; - - /* - * Number of clock cycles before data is released after - * the rising edge of the read controlling signal - * - * Total cycles from SMC is tdf_cycles + 1 - */ - unsigned int tdf_cycles:4; - - /* - * 0: TDF optimization disabled - * 1: TDF optimization enabled - */ - unsigned int tdf_mode:1; -}; - -extern void smc_set_timing(struct smc_config *config, - const struct smc_timing *timing); - -extern int smc_set_configuration(int cs, const struct smc_config *config); -extern struct smc_config *smc_get_configuration(int cs); - -#endif /* __ARCH_AT32AP_SMC_H */ diff --git a/arch/avr32/mach-at32ap/include/mach/sram.h b/arch/avr32/mach-at32ap/include/mach/sram.h deleted file mode 100644 index 4838dae7601a..000000000000 --- a/arch/avr32/mach-at32ap/include/mach/sram.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Simple SRAM allocator - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ASM_AVR32_ARCH_SRAM_H -#define __ASM_AVR32_ARCH_SRAM_H - -#include <linux/genalloc.h> - -extern struct gen_pool *sram_pool; - -static inline unsigned long sram_alloc(size_t len) -{ - if (!sram_pool) - return 0UL; - - return gen_pool_alloc(sram_pool, len); -} - -static inline void sram_free(unsigned long addr, size_t len) -{ - return gen_pool_free(sram_pool, addr, len); -} - -#endif /* __ASM_AVR32_ARCH_SRAM_H */ diff --git a/arch/avr32/mach-at32ap/intc.c b/arch/avr32/mach-at32ap/intc.c deleted file mode 100644 index aaff83cc50f0..000000000000 --- a/arch/avr32/mach-at32ap/intc.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2006, 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/platform_device.h> -#include <linux/syscore_ops.h> -#include <linux/export.h> - -#include <asm/io.h> - -#include "intc.h" - -struct intc { - void __iomem *regs; - struct irq_chip chip; -#ifdef CONFIG_PM - unsigned long suspend_ipr; - unsigned long saved_ipr[64]; -#endif -}; - -extern struct platform_device at32_intc0_device; - -/* - * TODO: We may be able to implement mask/unmask by setting IxM flags - * in the status register. - */ -static void intc_mask_irq(struct irq_data *d) -{ - -} - -static void intc_unmask_irq(struct irq_data *d) -{ - -} - -static struct intc intc0 = { - .chip = { - .name = "intc", - .irq_mask = intc_mask_irq, - .irq_unmask = intc_unmask_irq, - }, -}; - -/* - * All interrupts go via intc at some point. - */ -asmlinkage void do_IRQ(int level, struct pt_regs *regs) -{ - struct pt_regs *old_regs; - unsigned int irq; - unsigned long status_reg; - - local_irq_disable(); - - old_regs = set_irq_regs(regs); - - irq_enter(); - - irq = intc_readl(&intc0, INTCAUSE0 - 4 * level); - generic_handle_irq(irq); - - /* - * Clear all interrupt level masks so that we may handle - * interrupts during softirq processing. If this is a nested - * interrupt, interrupts must stay globally disabled until we - * return. - */ - status_reg = sysreg_read(SR); - status_reg &= ~(SYSREG_BIT(I0M) | SYSREG_BIT(I1M) - | SYSREG_BIT(I2M) | SYSREG_BIT(I3M)); - sysreg_write(SR, status_reg); - - irq_exit(); - - set_irq_regs(old_regs); -} - -void __init init_IRQ(void) -{ - extern void _evba(void); - extern void irq_level0(void); - struct resource *regs; - struct clk *pclk; - unsigned int i; - u32 offset, readback; - - regs = platform_get_resource(&at32_intc0_device, IORESOURCE_MEM, 0); - if (!regs) { - printk(KERN_EMERG "intc: no mmio resource defined\n"); - goto fail; - } - pclk = clk_get(&at32_intc0_device.dev, "pclk"); - if (IS_ERR(pclk)) { - printk(KERN_EMERG "intc: no clock defined\n"); - goto fail; - } - - clk_enable(pclk); - - intc0.regs = ioremap(regs->start, resource_size(regs)); - if (!intc0.regs) { - printk(KERN_EMERG "intc: failed to map registers (0x%08lx)\n", - (unsigned long)regs->start); - goto fail; - } - - /* - * Initialize all interrupts to level 0 (lowest priority). The - * priority level may be changed by calling - * irq_set_priority(). - * - */ - offset = (unsigned long)&irq_level0 - (unsigned long)&_evba; - for (i = 0; i < NR_INTERNAL_IRQS; i++) { - intc_writel(&intc0, INTPR0 + 4 * i, offset); - readback = intc_readl(&intc0, INTPR0 + 4 * i); - if (readback == offset) - irq_set_chip_and_handler(i, &intc0.chip, - handle_simple_irq); - } - - /* Unmask all interrupt levels */ - sysreg_write(SR, (sysreg_read(SR) - & ~(SR_I3M | SR_I2M | SR_I1M | SR_I0M))); - - return; - -fail: - panic("Interrupt controller initialization failed!\n"); -} - -#ifdef CONFIG_PM -void intc_set_suspend_handler(unsigned long offset) -{ - intc0.suspend_ipr = offset; -} - -static int intc_suspend(void) -{ - int i; - - if (unlikely(!irqs_disabled())) { - pr_err("intc_suspend: called with interrupts enabled\n"); - return -EINVAL; - } - - if (unlikely(!intc0.suspend_ipr)) { - pr_err("intc_suspend: suspend_ipr not initialized\n"); - return -EINVAL; - } - - for (i = 0; i < 64; i++) { - intc0.saved_ipr[i] = intc_readl(&intc0, INTPR0 + 4 * i); - intc_writel(&intc0, INTPR0 + 4 * i, intc0.suspend_ipr); - } - - return 0; -} - -static void intc_resume(void) -{ - int i; - - for (i = 0; i < 64; i++) - intc_writel(&intc0, INTPR0 + 4 * i, intc0.saved_ipr[i]); -} -#else -#define intc_suspend NULL -#define intc_resume NULL -#endif - -static struct syscore_ops intc_syscore_ops = { - .suspend = intc_suspend, - .resume = intc_resume, -}; - -static int __init intc_init_syscore(void) -{ - register_syscore_ops(&intc_syscore_ops); - - return 0; -} -device_initcall(intc_init_syscore); - -unsigned long intc_get_pending(unsigned int group) -{ - return intc_readl(&intc0, INTREQ0 + 4 * group); -} -EXPORT_SYMBOL_GPL(intc_get_pending); diff --git a/arch/avr32/mach-at32ap/intc.h b/arch/avr32/mach-at32ap/intc.h deleted file mode 100644 index 4d3664e43a8e..000000000000 --- a/arch/avr32/mach-at32ap/intc.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Automatically generated by gen-header.xsl - */ -#ifndef __ASM_AVR32_PERIHP_INTC_H__ -#define __ASM_AVR32_PERIHP_INTC_H__ - -#define INTC_NUM_INT_GRPS 33 - -#define INTC_INTPR0 0x0 -# define INTC_INTPR0_INTLEV_OFFSET 30 -# define INTC_INTPR0_INTLEV_SIZE 2 -# define INTC_INTPR0_OFFSET_OFFSET 0 -# define INTC_INTPR0_OFFSET_SIZE 24 -#define INTC_INTREQ0 0x100 -# define INTC_INTREQ0_IREQUEST0_OFFSET 0 -# define INTC_INTREQ0_IREQUEST0_SIZE 1 -# define INTC_INTREQ0_IREQUEST1_OFFSET 1 -# define INTC_INTREQ0_IREQUEST1_SIZE 1 -#define INTC_INTPR1 0x4 -# define INTC_INTPR1_INTLEV_OFFSET 30 -# define INTC_INTPR1_INTLEV_SIZE 2 -# define INTC_INTPR1_OFFSET_OFFSET 0 -# define INTC_INTPR1_OFFSET_SIZE 24 -#define INTC_INTREQ1 0x104 -# define INTC_INTREQ1_IREQUEST32_OFFSET 0 -# define INTC_INTREQ1_IREQUEST32_SIZE 1 -# define INTC_INTREQ1_IREQUEST33_OFFSET 1 -# define INTC_INTREQ1_IREQUEST33_SIZE 1 -# define INTC_INTREQ1_IREQUEST34_OFFSET 2 -# define INTC_INTREQ1_IREQUEST34_SIZE 1 -# define INTC_INTREQ1_IREQUEST35_OFFSET 3 -# define INTC_INTREQ1_IREQUEST35_SIZE 1 -# define INTC_INTREQ1_IREQUEST36_OFFSET 4 -# define INTC_INTREQ1_IREQUEST36_SIZE 1 -# define INTC_INTREQ1_IREQUEST37_OFFSET 5 -# define INTC_INTREQ1_IREQUEST37_SIZE 1 -#define INTC_INTPR2 0x8 -# define INTC_INTPR2_INTLEV_OFFSET 30 -# define INTC_INTPR2_INTLEV_SIZE 2 -# define INTC_INTPR2_OFFSET_OFFSET 0 -# define INTC_INTPR2_OFFSET_SIZE 24 -#define INTC_INTREQ2 0x108 -# define INTC_INTREQ2_IREQUEST64_OFFSET 0 -# define INTC_INTREQ2_IREQUEST64_SIZE 1 -# define INTC_INTREQ2_IREQUEST65_OFFSET 1 -# define INTC_INTREQ2_IREQUEST65_SIZE 1 -# define INTC_INTREQ2_IREQUEST66_OFFSET 2 -# define INTC_INTREQ2_IREQUEST66_SIZE 1 -# define INTC_INTREQ2_IREQUEST67_OFFSET 3 -# define INTC_INTREQ2_IREQUEST67_SIZE 1 -# define INTC_INTREQ2_IREQUEST68_OFFSET 4 -# define INTC_INTREQ2_IREQUEST68_SIZE 1 -#define INTC_INTPR3 0xc -# define INTC_INTPR3_INTLEV_OFFSET 30 -# define INTC_INTPR3_INTLEV_SIZE 2 -# define INTC_INTPR3_OFFSET_OFFSET 0 -# define INTC_INTPR3_OFFSET_SIZE 24 -#define INTC_INTREQ3 0x10c -# define INTC_INTREQ3_IREQUEST96_OFFSET 0 -# define INTC_INTREQ3_IREQUEST96_SIZE 1 -#define INTC_INTPR4 0x10 -# define INTC_INTPR4_INTLEV_OFFSET 30 -# define INTC_INTPR4_INTLEV_SIZE 2 -# define INTC_INTPR4_OFFSET_OFFSET 0 -# define INTC_INTPR4_OFFSET_SIZE 24 -#define INTC_INTREQ4 0x110 -# define INTC_INTREQ4_IREQUEST128_OFFSET 0 -# define INTC_INTREQ4_IREQUEST128_SIZE 1 -#define INTC_INTPR5 0x14 -# define INTC_INTPR5_INTLEV_OFFSET 30 -# define INTC_INTPR5_INTLEV_SIZE 2 -# define INTC_INTPR5_OFFSET_OFFSET 0 -# define INTC_INTPR5_OFFSET_SIZE 24 -#define INTC_INTREQ5 0x114 -# define INTC_INTREQ5_IREQUEST160_OFFSET 0 -# define INTC_INTREQ5_IREQUEST160_SIZE 1 -#define INTC_INTPR6 0x18 -# define INTC_INTPR6_INTLEV_OFFSET 30 -# define INTC_INTPR6_INTLEV_SIZE 2 -# define INTC_INTPR6_OFFSET_OFFSET 0 -# define INTC_INTPR6_OFFSET_SIZE 24 -#define INTC_INTREQ6 0x118 -# define INTC_INTREQ6_IREQUEST192_OFFSET 0 -# define INTC_INTREQ6_IREQUEST192_SIZE 1 -#define INTC_INTPR7 0x1c -# define INTC_INTPR7_INTLEV_OFFSET 30 -# define INTC_INTPR7_INTLEV_SIZE 2 -# define INTC_INTPR7_OFFSET_OFFSET 0 -# define INTC_INTPR7_OFFSET_SIZE 24 -#define INTC_INTREQ7 0x11c -# define INTC_INTREQ7_IREQUEST224_OFFSET 0 -# define INTC_INTREQ7_IREQUEST224_SIZE 1 -#define INTC_INTPR8 0x20 -# define INTC_INTPR8_INTLEV_OFFSET 30 -# define INTC_INTPR8_INTLEV_SIZE 2 -# define INTC_INTPR8_OFFSET_OFFSET 0 -# define INTC_INTPR8_OFFSET_SIZE 24 -#define INTC_INTREQ8 0x120 -# define INTC_INTREQ8_IREQUEST256_OFFSET 0 -# define INTC_INTREQ8_IREQUEST256_SIZE 1 -#define INTC_INTPR9 0x24 -# define INTC_INTPR9_INTLEV_OFFSET 30 -# define INTC_INTPR9_INTLEV_SIZE 2 -# define INTC_INTPR9_OFFSET_OFFSET 0 -# define INTC_INTPR9_OFFSET_SIZE 24 -#define INTC_INTREQ9 0x124 -# define INTC_INTREQ9_IREQUEST288_OFFSET 0 -# define INTC_INTREQ9_IREQUEST288_SIZE 1 -#define INTC_INTPR10 0x28 -# define INTC_INTPR10_INTLEV_OFFSET 30 -# define INTC_INTPR10_INTLEV_SIZE 2 -# define INTC_INTPR10_OFFSET_OFFSET 0 -# define INTC_INTPR10_OFFSET_SIZE 24 -#define INTC_INTREQ10 0x128 -# define INTC_INTREQ10_IREQUEST320_OFFSET 0 -# define INTC_INTREQ10_IREQUEST320_SIZE 1 -#define INTC_INTPR11 0x2c -# define INTC_INTPR11_INTLEV_OFFSET 30 -# define INTC_INTPR11_INTLEV_SIZE 2 -# define INTC_INTPR11_OFFSET_OFFSET 0 -# define INTC_INTPR11_OFFSET_SIZE 24 -#define INTC_INTREQ11 0x12c -# define INTC_INTREQ11_IREQUEST352_OFFSET 0 -# define INTC_INTREQ11_IREQUEST352_SIZE 1 -#define INTC_INTPR12 0x30 -# define INTC_INTPR12_INTLEV_OFFSET 30 -# define INTC_INTPR12_INTLEV_SIZE 2 -# define INTC_INTPR12_OFFSET_OFFSET 0 -# define INTC_INTPR12_OFFSET_SIZE 24 -#define INTC_INTREQ12 0x130 -# define INTC_INTREQ12_IREQUEST384_OFFSET 0 -# define INTC_INTREQ12_IREQUEST384_SIZE 1 -#define INTC_INTPR13 0x34 -# define INTC_INTPR13_INTLEV_OFFSET 30 -# define INTC_INTPR13_INTLEV_SIZE 2 -# define INTC_INTPR13_OFFSET_OFFSET 0 -# define INTC_INTPR13_OFFSET_SIZE 24 -#define INTC_INTREQ13 0x134 -# define INTC_INTREQ13_IREQUEST416_OFFSET 0 -# define INTC_INTREQ13_IREQUEST416_SIZE 1 -#define INTC_INTPR14 0x38 -# define INTC_INTPR14_INTLEV_OFFSET 30 -# define INTC_INTPR14_INTLEV_SIZE 2 -# define INTC_INTPR14_OFFSET_OFFSET 0 -# define INTC_INTPR14_OFFSET_SIZE 24 -#define INTC_INTREQ14 0x138 -# define INTC_INTREQ14_IREQUEST448_OFFSET 0 -# define INTC_INTREQ14_IREQUEST448_SIZE 1 -#define INTC_INTPR15 0x3c -# define INTC_INTPR15_INTLEV_OFFSET 30 -# define INTC_INTPR15_INTLEV_SIZE 2 -# define INTC_INTPR15_OFFSET_OFFSET 0 -# define INTC_INTPR15_OFFSET_SIZE 24 -#define INTC_INTREQ15 0x13c -# define INTC_INTREQ15_IREQUEST480_OFFSET 0 -# define INTC_INTREQ15_IREQUEST480_SIZE 1 -#define INTC_INTPR16 0x40 -# define INTC_INTPR16_INTLEV_OFFSET 30 -# define INTC_INTPR16_INTLEV_SIZE 2 -# define INTC_INTPR16_OFFSET_OFFSET 0 -# define INTC_INTPR16_OFFSET_SIZE 24 -#define INTC_INTREQ16 0x140 -# define INTC_INTREQ16_IREQUEST512_OFFSET 0 -# define INTC_INTREQ16_IREQUEST512_SIZE 1 -#define INTC_INTPR17 0x44 -# define INTC_INTPR17_INTLEV_OFFSET 30 -# define INTC_INTPR17_INTLEV_SIZE 2 -# define INTC_INTPR17_OFFSET_OFFSET 0 -# define INTC_INTPR17_OFFSET_SIZE 24 -#define INTC_INTREQ17 0x144 -# define INTC_INTREQ17_IREQUEST544_OFFSET 0 -# define INTC_INTREQ17_IREQUEST544_SIZE 1 -#define INTC_INTPR18 0x48 -# define INTC_INTPR18_INTLEV_OFFSET 30 -# define INTC_INTPR18_INTLEV_SIZE 2 -# define INTC_INTPR18_OFFSET_OFFSET 0 -# define INTC_INTPR18_OFFSET_SIZE 24 -#define INTC_INTREQ18 0x148 -# define INTC_INTREQ18_IREQUEST576_OFFSET 0 -# define INTC_INTREQ18_IREQUEST576_SIZE 1 -#define INTC_INTPR19 0x4c -# define INTC_INTPR19_INTLEV_OFFSET 30 -# define INTC_INTPR19_INTLEV_SIZE 2 -# define INTC_INTPR19_OFFSET_OFFSET 0 -# define INTC_INTPR19_OFFSET_SIZE 24 -#define INTC_INTREQ19 0x14c -# define INTC_INTREQ19_IREQUEST608_OFFSET 0 -# define INTC_INTREQ19_IREQUEST608_SIZE 1 -# define INTC_INTREQ19_IREQUEST609_OFFSET 1 -# define INTC_INTREQ19_IREQUEST609_SIZE 1 -# define INTC_INTREQ19_IREQUEST610_OFFSET 2 -# define INTC_INTREQ19_IREQUEST610_SIZE 1 -# define INTC_INTREQ19_IREQUEST611_OFFSET 3 -# define INTC_INTREQ19_IREQUEST611_SIZE 1 -#define INTC_INTPR20 0x50 -# define INTC_INTPR20_INTLEV_OFFSET 30 -# define INTC_INTPR20_INTLEV_SIZE 2 -# define INTC_INTPR20_OFFSET_OFFSET 0 -# define INTC_INTPR20_OFFSET_SIZE 24 -#define INTC_INTREQ20 0x150 -# define INTC_INTREQ20_IREQUEST640_OFFSET 0 -# define INTC_INTREQ20_IREQUEST640_SIZE 1 -#define INTC_INTPR21 0x54 -# define INTC_INTPR21_INTLEV_OFFSET 30 -# define INTC_INTPR21_INTLEV_SIZE 2 -# define INTC_INTPR21_OFFSET_OFFSET 0 -# define INTC_INTPR21_OFFSET_SIZE 24 -#define INTC_INTREQ21 0x154 -# define INTC_INTREQ21_IREQUEST672_OFFSET 0 -# define INTC_INTREQ21_IREQUEST672_SIZE 1 -#define INTC_INTPR22 0x58 -# define INTC_INTPR22_INTLEV_OFFSET 30 -# define INTC_INTPR22_INTLEV_SIZE 2 -# define INTC_INTPR22_OFFSET_OFFSET 0 -# define INTC_INTPR22_OFFSET_SIZE 24 -#define INTC_INTREQ22 0x158 -# define INTC_INTREQ22_IREQUEST704_OFFSET 0 -# define INTC_INTREQ22_IREQUEST704_SIZE 1 -# define INTC_INTREQ22_IREQUEST705_OFFSET 1 -# define INTC_INTREQ22_IREQUEST705_SIZE 1 -# define INTC_INTREQ22_IREQUEST706_OFFSET 2 -# define INTC_INTREQ22_IREQUEST706_SIZE 1 -#define INTC_INTPR23 0x5c -# define INTC_INTPR23_INTLEV_OFFSET 30 -# define INTC_INTPR23_INTLEV_SIZE 2 -# define INTC_INTPR23_OFFSET_OFFSET 0 -# define INTC_INTPR23_OFFSET_SIZE 24 -#define INTC_INTREQ23 0x15c -# define INTC_INTREQ23_IREQUEST736_OFFSET 0 -# define INTC_INTREQ23_IREQUEST736_SIZE 1 -# define INTC_INTREQ23_IREQUEST737_OFFSET 1 -# define INTC_INTREQ23_IREQUEST737_SIZE 1 -# define INTC_INTREQ23_IREQUEST738_OFFSET 2 -# define INTC_INTREQ23_IREQUEST738_SIZE 1 -#define INTC_INTPR24 0x60 -# define INTC_INTPR24_INTLEV_OFFSET 30 -# define INTC_INTPR24_INTLEV_SIZE 2 -# define INTC_INTPR24_OFFSET_OFFSET 0 -# define INTC_INTPR24_OFFSET_SIZE 24 -#define INTC_INTREQ24 0x160 -# define INTC_INTREQ24_IREQUEST768_OFFSET 0 -# define INTC_INTREQ24_IREQUEST768_SIZE 1 -#define INTC_INTPR25 0x64 -# define INTC_INTPR25_INTLEV_OFFSET 30 -# define INTC_INTPR25_INTLEV_SIZE 2 -# define INTC_INTPR25_OFFSET_OFFSET 0 -# define INTC_INTPR25_OFFSET_SIZE 24 -#define INTC_INTREQ25 0x164 -# define INTC_INTREQ25_IREQUEST800_OFFSET 0 -# define INTC_INTREQ25_IREQUEST800_SIZE 1 -#define INTC_INTPR26 0x68 -# define INTC_INTPR26_INTLEV_OFFSET 30 -# define INTC_INTPR26_INTLEV_SIZE 2 -# define INTC_INTPR26_OFFSET_OFFSET 0 -# define INTC_INTPR26_OFFSET_SIZE 24 -#define INTC_INTREQ26 0x168 -# define INTC_INTREQ26_IREQUEST832_OFFSET 0 -# define INTC_INTREQ26_IREQUEST832_SIZE 1 -#define INTC_INTPR27 0x6c -# define INTC_INTPR27_INTLEV_OFFSET 30 -# define INTC_INTPR27_INTLEV_SIZE 2 -# define INTC_INTPR27_OFFSET_OFFSET 0 -# define INTC_INTPR27_OFFSET_SIZE 24 -#define INTC_INTREQ27 0x16c -# define INTC_INTREQ27_IREQUEST864_OFFSET 0 -# define INTC_INTREQ27_IREQUEST864_SIZE 1 -#define INTC_INTPR28 0x70 -# define INTC_INTPR28_INTLEV_OFFSET 30 -# define INTC_INTPR28_INTLEV_SIZE 2 -# define INTC_INTPR28_OFFSET_OFFSET 0 -# define INTC_INTPR28_OFFSET_SIZE 24 -#define INTC_INTREQ28 0x170 -# define INTC_INTREQ28_IREQUEST896_OFFSET 0 -# define INTC_INTREQ28_IREQUEST896_SIZE 1 -#define INTC_INTPR29 0x74 -# define INTC_INTPR29_INTLEV_OFFSET 30 -# define INTC_INTPR29_INTLEV_SIZE 2 -# define INTC_INTPR29_OFFSET_OFFSET 0 -# define INTC_INTPR29_OFFSET_SIZE 24 -#define INTC_INTREQ29 0x174 -# define INTC_INTREQ29_IREQUEST928_OFFSET 0 -# define INTC_INTREQ29_IREQUEST928_SIZE 1 -#define INTC_INTPR30 0x78 -# define INTC_INTPR30_INTLEV_OFFSET 30 -# define INTC_INTPR30_INTLEV_SIZE 2 -# define INTC_INTPR30_OFFSET_OFFSET 0 -# define INTC_INTPR30_OFFSET_SIZE 24 -#define INTC_INTREQ30 0x178 -# define INTC_INTREQ30_IREQUEST960_OFFSET 0 -# define INTC_INTREQ30_IREQUEST960_SIZE 1 -#define INTC_INTPR31 0x7c -# define INTC_INTPR31_INTLEV_OFFSET 30 -# define INTC_INTPR31_INTLEV_SIZE 2 -# define INTC_INTPR31_OFFSET_OFFSET 0 -# define INTC_INTPR31_OFFSET_SIZE 24 -#define INTC_INTREQ31 0x17c -# define INTC_INTREQ31_IREQUEST992_OFFSET 0 -# define INTC_INTREQ31_IREQUEST992_SIZE 1 -#define INTC_INTPR32 0x80 -# define INTC_INTPR32_INTLEV_OFFSET 30 -# define INTC_INTPR32_INTLEV_SIZE 2 -# define INTC_INTPR32_OFFSET_OFFSET 0 -# define INTC_INTPR32_OFFSET_SIZE 24 -#define INTC_INTREQ32 0x180 -# define INTC_INTREQ32_IREQUEST1024_OFFSET 0 -# define INTC_INTREQ32_IREQUEST1024_SIZE 1 -#define INTC_INTCAUSE0 0x20c -# define INTC_INTCAUSE0_CAUSEGRP_OFFSET 0 -# define INTC_INTCAUSE0_CAUSEGRP_SIZE 6 -#define INTC_INTCAUSE1 0x208 -# define INTC_INTCAUSE1_CAUSEGRP_OFFSET 0 -# define INTC_INTCAUSE1_CAUSEGRP_SIZE 6 -#define INTC_INTCAUSE2 0x204 -# define INTC_INTCAUSE2_CAUSEGRP_OFFSET 0 -# define INTC_INTCAUSE2_CAUSEGRP_SIZE 6 -#define INTC_INTCAUSE3 0x200 -# define INTC_INTCAUSE3_CAUSEGRP_OFFSET 0 -# define INTC_INTCAUSE3_CAUSEGRP_SIZE 6 - -#define INTC_BIT(name) (1 << INTC_##name##_OFFSET) -#define INTC_MKBF(name, value) (((value) & ((1 << INTC_##name##_SIZE) - 1)) << INTC_##name##_OFFSET) -#define INTC_GETBF(name, value) (((value) >> INTC_##name##_OFFSET) & ((1 << INTC_##name##_SIZE) - 1)) - -#define intc_readl(port,reg) \ - __raw_readl((port)->regs + INTC_##reg) -#define intc_writel(port,reg,value) \ - __raw_writel((value), (port)->regs + INTC_##reg) - -#endif /* __ASM_AVR32_PERIHP_INTC_H__ */ diff --git a/arch/avr32/mach-at32ap/pdc.c b/arch/avr32/mach-at32ap/pdc.c deleted file mode 100644 index 61ab15aae970..000000000000 --- a/arch/avr32/mach-at32ap/pdc.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/init.h> -#include <linux/platform_device.h> - -static int __init pdc_probe(struct platform_device *pdev) -{ - struct clk *pclk, *hclk; - - pclk = clk_get(&pdev->dev, "pclk"); - if (IS_ERR(pclk)) { - dev_err(&pdev->dev, "no pclk defined\n"); - return PTR_ERR(pclk); - } - hclk = clk_get(&pdev->dev, "hclk"); - if (IS_ERR(hclk)) { - dev_err(&pdev->dev, "no hclk defined\n"); - clk_put(pclk); - return PTR_ERR(hclk); - } - - clk_enable(pclk); - clk_enable(hclk); - - dev_info(&pdev->dev, "Atmel Peripheral DMA Controller enabled\n"); - return 0; -} - -static struct platform_driver pdc_driver = { - .driver = { - .name = "pdc", - }, -}; - -static int __init pdc_init(void) -{ - return platform_driver_probe(&pdc_driver, pdc_probe); -} -arch_initcall(pdc_init); diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c deleted file mode 100644 index 7fae6ec7e8ec..000000000000 --- a/arch/avr32/mach-at32ap/pio.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * Atmel PIO2 Port Multiplexer support - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/clk.h> -#include <linux/debugfs.h> -#include <linux/export.h> -#include <linux/fs.h> -#include <linux/platform_device.h> -#include <linux/irq.h> -#include <linux/gpio.h> - -#include <asm/io.h> - -#include <mach/portmux.h> - -#include "pio.h" - -#define MAX_NR_PIO_DEVICES 8 - -struct pio_device { - struct gpio_chip chip; - void __iomem *regs; - const struct platform_device *pdev; - struct clk *clk; - u32 pinmux_mask; - char name[8]; -}; - -static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; - -static struct pio_device *gpio_to_pio(unsigned int gpio) -{ - struct pio_device *pio; - unsigned int index; - - index = gpio >> 5; - if (index >= MAX_NR_PIO_DEVICES) - return NULL; - pio = &pio_dev[index]; - if (!pio->regs) - return NULL; - - return pio; -} - -/* Pin multiplexing API */ -static DEFINE_SPINLOCK(pio_lock); - -void __init at32_select_periph(unsigned int port, u32 pin_mask, - unsigned int periph, unsigned long flags) -{ - struct pio_device *pio; - - /* assign and verify pio */ - pio = gpio_to_pio(port); - if (unlikely(!pio)) { - printk(KERN_WARNING "pio: invalid port %u\n", port); - goto fail; - } - - /* Test if any of the requested pins is already muxed */ - spin_lock(&pio_lock); - if (unlikely(pio->pinmux_mask & pin_mask)) { - printk(KERN_WARNING "%s: pin(s) busy (requested 0x%x, busy 0x%x)\n", - pio->name, pin_mask, pio->pinmux_mask & pin_mask); - spin_unlock(&pio_lock); - goto fail; - } - - pio->pinmux_mask |= pin_mask; - - /* enable pull ups */ - pio_writel(pio, PUER, pin_mask); - - /* select either peripheral A or B */ - if (periph) - pio_writel(pio, BSR, pin_mask); - else - pio_writel(pio, ASR, pin_mask); - - /* enable peripheral control */ - pio_writel(pio, PDR, pin_mask); - - /* Disable pull ups if not requested. */ - if (!(flags & AT32_GPIOF_PULLUP)) - pio_writel(pio, PUDR, pin_mask); - - spin_unlock(&pio_lock); - - return; - -fail: - dump_stack(); -} - -void __init at32_select_gpio(unsigned int pin, unsigned long flags) -{ - struct pio_device *pio; - unsigned int pin_index = pin & 0x1f; - u32 mask = 1 << pin_index; - - pio = gpio_to_pio(pin); - if (unlikely(!pio)) { - printk("pio: invalid pin %u\n", pin); - goto fail; - } - - if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { - printk("%s: pin %u is busy\n", pio->name, pin_index); - goto fail; - } - - if (flags & AT32_GPIOF_OUTPUT) { - if (flags & AT32_GPIOF_HIGH) - pio_writel(pio, SODR, mask); - else - pio_writel(pio, CODR, mask); - if (flags & AT32_GPIOF_MULTIDRV) - pio_writel(pio, MDER, mask); - else - pio_writel(pio, MDDR, mask); - pio_writel(pio, PUDR, mask); - pio_writel(pio, OER, mask); - } else { - if (flags & AT32_GPIOF_PULLUP) - pio_writel(pio, PUER, mask); - else - pio_writel(pio, PUDR, mask); - if (flags & AT32_GPIOF_DEGLITCH) - pio_writel(pio, IFER, mask); - else - pio_writel(pio, IFDR, mask); - pio_writel(pio, ODR, mask); - } - - pio_writel(pio, PER, mask); - - return; - -fail: - dump_stack(); -} - -/* - * Undo a previous pin reservation. Will not affect the hardware - * configuration. - */ -void at32_deselect_pin(unsigned int pin) -{ - struct pio_device *pio; - unsigned int pin_index = pin & 0x1f; - - pio = gpio_to_pio(pin); - if (unlikely(!pio)) { - printk("pio: invalid pin %u\n", pin); - dump_stack(); - return; - } - - clear_bit(pin_index, &pio->pinmux_mask); -} - -/* Reserve a pin, preventing anyone else from changing its configuration. */ -void __init at32_reserve_pin(unsigned int port, u32 pin_mask) -{ - struct pio_device *pio; - - /* assign and verify pio */ - pio = gpio_to_pio(port); - if (unlikely(!pio)) { - printk(KERN_WARNING "pio: invalid port %u\n", port); - goto fail; - } - - /* Test if any of the requested pins is already muxed */ - spin_lock(&pio_lock); - if (unlikely(pio->pinmux_mask & pin_mask)) { - printk(KERN_WARNING "%s: pin(s) busy (req. 0x%x, busy 0x%x)\n", - pio->name, pin_mask, pio->pinmux_mask & pin_mask); - spin_unlock(&pio_lock); - goto fail; - } - - /* Reserve pins */ - pio->pinmux_mask |= pin_mask; - spin_unlock(&pio_lock); - return; - -fail: - dump_stack(); -} - -/*--------------------------------------------------------------------------*/ - -/* GPIO API */ - -static int direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct pio_device *pio = gpiochip_get_data(chip); - u32 mask = 1 << offset; - - if (!(pio_readl(pio, PSR) & mask)) - return -EINVAL; - - pio_writel(pio, ODR, mask); - return 0; -} - -static int gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct pio_device *pio = gpiochip_get_data(chip); - - return (pio_readl(pio, PDSR) >> offset) & 1; -} - -static void gpio_set(struct gpio_chip *chip, unsigned offset, int value); - -static int direction_output(struct gpio_chip *chip, unsigned offset, int value) -{ - struct pio_device *pio = gpiochip_get_data(chip); - u32 mask = 1 << offset; - - if (!(pio_readl(pio, PSR) & mask)) - return -EINVAL; - - gpio_set(chip, offset, value); - pio_writel(pio, OER, mask); - return 0; -} - -static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct pio_device *pio = gpiochip_get_data(chip); - u32 mask = 1 << offset; - - if (value) - pio_writel(pio, SODR, mask); - else - pio_writel(pio, CODR, mask); -} - -/*--------------------------------------------------------------------------*/ - -/* GPIO IRQ support */ - -static void gpio_irq_mask(struct irq_data *d) -{ - unsigned gpio = irq_to_gpio(d->irq); - struct pio_device *pio = &pio_dev[gpio >> 5]; - - pio_writel(pio, IDR, 1 << (gpio & 0x1f)); -} - -static void gpio_irq_unmask(struct irq_data *d) -{ - unsigned gpio = irq_to_gpio(d->irq); - struct pio_device *pio = &pio_dev[gpio >> 5]; - - pio_writel(pio, IER, 1 << (gpio & 0x1f)); -} - -static int gpio_irq_type(struct irq_data *d, unsigned type) -{ - if (type != IRQ_TYPE_EDGE_BOTH && type != IRQ_TYPE_NONE) - return -EINVAL; - - return 0; -} - -static struct irq_chip gpio_irqchip = { - .name = "gpio", - .irq_mask = gpio_irq_mask, - .irq_unmask = gpio_irq_unmask, - .irq_set_type = gpio_irq_type, -}; - -static void gpio_irq_handler(struct irq_desc *desc) -{ - struct pio_device *pio = irq_desc_get_chip_data(desc); - unsigned gpio_irq; - - gpio_irq = (unsigned) irq_desc_get_handler_data(desc); - for (;;) { - u32 isr; - - /* ack pending GPIO interrupts */ - isr = pio_readl(pio, ISR) & pio_readl(pio, IMR); - if (!isr) - break; - do { - int i; - - i = ffs(isr) - 1; - isr &= ~(1 << i); - - i += gpio_irq; - generic_handle_irq(i); - } while (isr); - } -} - -static void __init -gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq) -{ - unsigned i; - - irq_set_chip_data(irq, pio); - - for (i = 0; i < 32; i++, gpio_irq++) { - irq_set_chip_data(gpio_irq, pio); - irq_set_chip_and_handler(gpio_irq, &gpio_irqchip, - handle_simple_irq); - } - - irq_set_chained_handler_and_data(irq, gpio_irq_handler, - (void *)gpio_irq); -} - -/*--------------------------------------------------------------------------*/ - -#ifdef CONFIG_DEBUG_FS - -#include <linux/seq_file.h> - -/* - * This shows more info than the generic gpio dump code: - * pullups, deglitching, open drain drive. - */ -static void pio_bank_show(struct seq_file *s, struct gpio_chip *chip) -{ - struct pio_device *pio = gpiochip_get_data(chip); - u32 psr, osr, imr, pdsr, pusr, ifsr, mdsr; - unsigned i; - u32 mask; - char bank; - - psr = pio_readl(pio, PSR); - osr = pio_readl(pio, OSR); - imr = pio_readl(pio, IMR); - pdsr = pio_readl(pio, PDSR); - pusr = pio_readl(pio, PUSR); - ifsr = pio_readl(pio, IFSR); - mdsr = pio_readl(pio, MDSR); - - bank = 'A' + pio->pdev->id; - - for (i = 0, mask = 1; i < 32; i++, mask <<= 1) { - const char *label; - - label = gpiochip_is_requested(chip, i); - if (!label && (imr & mask)) - label = "[irq]"; - if (!label) - continue; - - seq_printf(s, " gpio-%-3d P%c%-2d (%-12s) %s %s %s", - chip->base + i, bank, i, - label, - (osr & mask) ? "out" : "in ", - (mask & pdsr) ? "hi" : "lo", - (mask & pusr) ? " " : "up"); - if (ifsr & mask) - seq_puts(s, " deglitch"); - if ((osr & mdsr) & mask) - seq_puts(s, " open-drain"); - if (imr & mask) - seq_printf(s, " irq-%d edge-both", - gpio_to_irq(chip->base + i)); - seq_putc(s, '\n'); - } -} - -#else -#define pio_bank_show NULL -#endif - - -/*--------------------------------------------------------------------------*/ - -static int __init pio_probe(struct platform_device *pdev) -{ - struct pio_device *pio = NULL; - int irq = platform_get_irq(pdev, 0); - int gpio_irq_base = GPIO_IRQ_BASE + pdev->id * 32; - - BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES); - pio = &pio_dev[pdev->id]; - BUG_ON(!pio->regs); - - pio->chip.label = pio->name; - pio->chip.base = pdev->id * 32; - pio->chip.ngpio = 32; - pio->chip.parent = &pdev->dev; - pio->chip.owner = THIS_MODULE; - - pio->chip.direction_input = direction_input; - pio->chip.get = gpio_get; - pio->chip.direction_output = direction_output; - pio->chip.set = gpio_set; - pio->chip.dbg_show = pio_bank_show; - - gpiochip_add_data(&pio->chip, pio); - - gpio_irq_setup(pio, irq, gpio_irq_base); - - platform_set_drvdata(pdev, pio); - - printk(KERN_DEBUG "%s: base 0x%p, irq %d chains %d..%d\n", - pio->name, pio->regs, irq, gpio_irq_base, gpio_irq_base + 31); - - return 0; -} - -static struct platform_driver pio_driver = { - .driver = { - .name = "pio", - }, -}; - -static int __init pio_init(void) -{ - return platform_driver_probe(&pio_driver, pio_probe); -} -postcore_initcall(pio_init); - -void __init at32_init_pio(struct platform_device *pdev) -{ - struct resource *regs; - struct pio_device *pio; - - if (pdev->id >= MAX_NR_PIO_DEVICES) { - dev_err(&pdev->dev, "only %d PIO devices supported\n", - MAX_NR_PIO_DEVICES); - return; - } - - pio = &pio_dev[pdev->id]; - snprintf(pio->name, sizeof(pio->name), "pio%d", pdev->id); - - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_err(&pdev->dev, "no mmio resource defined\n"); - return; - } - - pio->clk = clk_get(&pdev->dev, "mck"); - if (IS_ERR(pio->clk)) - /* - * This is a fatal error, but if we continue we might - * be so lucky that we manage to initialize the - * console and display this message... - */ - dev_err(&pdev->dev, "no mck clock defined\n"); - else - clk_enable(pio->clk); - - pio->pdev = pdev; - pio->regs = ioremap(regs->start, resource_size(regs)); - - /* start with irqs disabled and acked */ - pio_writel(pio, IDR, ~0UL); - (void) pio_readl(pio, ISR); -} diff --git a/arch/avr32/mach-at32ap/pio.h b/arch/avr32/mach-at32ap/pio.h deleted file mode 100644 index 9484dfcc08f2..000000000000 --- a/arch/avr32/mach-at32ap/pio.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Atmel PIO2 Port Multiplexer support - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef __ARCH_AVR32_AT32AP_PIO_H__ -#define __ARCH_AVR32_AT32AP_PIO_H__ - -/* PIO register offsets */ -#define PIO_PER 0x0000 -#define PIO_PDR 0x0004 -#define PIO_PSR 0x0008 -#define PIO_OER 0x0010 -#define PIO_ODR 0x0014 -#define PIO_OSR 0x0018 -#define PIO_IFER 0x0020 -#define PIO_IFDR 0x0024 -#define PIO_IFSR 0x0028 -#define PIO_SODR 0x0030 -#define PIO_CODR 0x0034 -#define PIO_ODSR 0x0038 -#define PIO_PDSR 0x003c -#define PIO_IER 0x0040 -#define PIO_IDR 0x0044 -#define PIO_IMR 0x0048 -#define PIO_ISR 0x004c -#define PIO_MDER 0x0050 -#define PIO_MDDR 0x0054 -#define PIO_MDSR 0x0058 -#define PIO_PUDR 0x0060 -#define PIO_PUER 0x0064 -#define PIO_PUSR 0x0068 -#define PIO_ASR 0x0070 -#define PIO_BSR 0x0074 -#define PIO_ABSR 0x0078 -#define PIO_OWER 0x00a0 -#define PIO_OWDR 0x00a4 -#define PIO_OWSR 0x00a8 - -/* Bitfields in PER */ - -/* Bitfields in PDR */ - -/* Bitfields in PSR */ - -/* Bitfields in OER */ - -/* Bitfields in ODR */ - -/* Bitfields in OSR */ - -/* Bitfields in IFER */ - -/* Bitfields in IFDR */ - -/* Bitfields in IFSR */ - -/* Bitfields in SODR */ - -/* Bitfields in CODR */ - -/* Bitfields in ODSR */ - -/* Bitfields in PDSR */ - -/* Bitfields in IER */ - -/* Bitfields in IDR */ - -/* Bitfields in IMR */ - -/* Bitfields in ISR */ - -/* Bitfields in MDER */ - -/* Bitfields in MDDR */ - -/* Bitfields in MDSR */ - -/* Bitfields in PUDR */ - -/* Bitfields in PUER */ - -/* Bitfields in PUSR */ - -/* Bitfields in ASR */ - -/* Bitfields in BSR */ - -/* Bitfields in ABSR */ -#define PIO_P0_OFFSET 0 -#define PIO_P0_SIZE 1 -#define PIO_P1_OFFSET 1 -#define PIO_P1_SIZE 1 -#define PIO_P2_OFFSET 2 -#define PIO_P2_SIZE 1 -#define PIO_P3_OFFSET 3 -#define PIO_P3_SIZE 1 -#define PIO_P4_OFFSET 4 -#define PIO_P4_SIZE 1 -#define PIO_P5_OFFSET 5 -#define PIO_P5_SIZE 1 -#define PIO_P6_OFFSET 6 -#define PIO_P6_SIZE 1 -#define PIO_P7_OFFSET 7 -#define PIO_P7_SIZE 1 -#define PIO_P8_OFFSET 8 -#define PIO_P8_SIZE 1 -#define PIO_P9_OFFSET 9 -#define PIO_P9_SIZE 1 -#define PIO_P10_OFFSET 10 -#define PIO_P10_SIZE 1 -#define PIO_P11_OFFSET 11 -#define PIO_P11_SIZE 1 -#define PIO_P12_OFFSET 12 -#define PIO_P12_SIZE 1 -#define PIO_P13_OFFSET 13 -#define PIO_P13_SIZE 1 -#define PIO_P14_OFFSET 14 -#define PIO_P14_SIZE 1 -#define PIO_P15_OFFSET 15 -#define PIO_P15_SIZE 1 -#define PIO_P16_OFFSET 16 -#define PIO_P16_SIZE 1 -#define PIO_P17_OFFSET 17 -#define PIO_P17_SIZE 1 -#define PIO_P18_OFFSET 18 -#define PIO_P18_SIZE 1 -#define PIO_P19_OFFSET 19 -#define PIO_P19_SIZE 1 -#define PIO_P20_OFFSET 20 -#define PIO_P20_SIZE 1 -#define PIO_P21_OFFSET 21 -#define PIO_P21_SIZE 1 -#define PIO_P22_OFFSET 22 -#define PIO_P22_SIZE 1 -#define PIO_P23_OFFSET 23 -#define PIO_P23_SIZE 1 -#define PIO_P24_OFFSET 24 -#define PIO_P24_SIZE 1 -#define PIO_P25_OFFSET 25 -#define PIO_P25_SIZE 1 -#define PIO_P26_OFFSET 26 -#define PIO_P26_SIZE 1 -#define PIO_P27_OFFSET 27 -#define PIO_P27_SIZE 1 -#define PIO_P28_OFFSET 28 -#define PIO_P28_SIZE 1 -#define PIO_P29_OFFSET 29 -#define PIO_P29_SIZE 1 -#define PIO_P30_OFFSET 30 -#define PIO_P30_SIZE 1 -#define PIO_P31_OFFSET 31 -#define PIO_P31_SIZE 1 - -/* Bitfields in OWER */ - -/* Bitfields in OWDR */ - -/* Bitfields in OWSR */ - -/* Bit manipulation macros */ -#define PIO_BIT(name) (1 << PIO_##name##_OFFSET) -#define PIO_BF(name,value) (((value) & ((1 << PIO_##name##_SIZE) - 1)) << PIO_##name##_OFFSET) -#define PIO_BFEXT(name,value) (((value) >> PIO_##name##_OFFSET) & ((1 << PIO_##name##_SIZE) - 1)) -#define PIO_BFINS(name,value,old) (((old) & ~(((1 << PIO_##name##_SIZE) - 1) << PIO_##name##_OFFSET)) | PIO_BF(name,value)) - -/* Register access macros */ -#define pio_readl(port,reg) \ - __raw_readl((port)->regs + PIO_##reg) -#define pio_writel(port,reg,value) \ - __raw_writel((value), (port)->regs + PIO_##reg) - -void at32_init_pio(struct platform_device *pdev); - -#endif /* __ARCH_AVR32_AT32AP_PIO_H__ */ diff --git a/arch/avr32/mach-at32ap/pm-at32ap700x.S b/arch/avr32/mach-at32ap/pm-at32ap700x.S deleted file mode 100644 index 1c8e4e6bff03..000000000000 --- a/arch/avr32/mach-at32ap/pm-at32ap700x.S +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Low-level Power Management code. - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <asm/asm.h> -#include <asm/asm-offsets.h> -#include <asm/thread_info.h> -#include <mach/pm.h> - -#include "pm.h" -#include "sdramc.h" - -/* Same as 0xfff00000 but fits in a 21 bit signed immediate */ -#define PM_BASE -0x100000 - - /* Keep this close to the irq handlers */ - .section .irq.text, "ax", @progbits - - /* - * void cpu_enter_idle(void) - * - * Put the CPU into "idle" mode, in which it will consume - * significantly less power. - * - * If an interrupt comes along in the window between - * unmask_interrupts and the sleep instruction below, the - * interrupt code will adjust the return address so that we - * never execute the sleep instruction. This is required - * because the AP7000 doesn't unmask interrupts when entering - * sleep modes; later CPUs may not need this workaround. - */ - .global cpu_enter_idle - .type cpu_enter_idle, @function -cpu_enter_idle: - mask_interrupts - get_thread_info r8 - ld.w r9, r8[TI_flags] - bld r9, TIF_NEED_RESCHED - brcs .Lret_from_sleep - sbr r9, TIF_CPU_GOING_TO_SLEEP - st.w r8[TI_flags], r9 - unmask_interrupts - sleep CPU_SLEEP_IDLE - .size cpu_enter_idle, . - cpu_enter_idle - - /* - * Common return path for PM functions that don't run from - * SRAM. - */ - .global cpu_idle_skip_sleep - .type cpu_idle_skip_sleep, @function -cpu_idle_skip_sleep: - mask_interrupts - ld.w r9, r8[TI_flags] - cbr r9, TIF_CPU_GOING_TO_SLEEP - st.w r8[TI_flags], r9 -.Lret_from_sleep: - unmask_interrupts - retal r12 - .size cpu_idle_skip_sleep, . - cpu_idle_skip_sleep - -#ifdef CONFIG_PM - .section .init.text, "ax", @progbits - - .global pm_exception - .type pm_exception, @function -pm_exception: - /* - * Exceptions are masked when we switch to this handler, so - * we'll only get "unrecoverable" exceptions (offset 0.) - */ - sub r12, pc, . - .Lpanic_msg - lddpc pc, .Lpanic_addr - - .align 2 -.Lpanic_addr: - .long panic -.Lpanic_msg: - .asciz "Unrecoverable exception during suspend\n" - .size pm_exception, . - pm_exception - - .global pm_irq0 - .type pm_irq0, @function -pm_irq0: - /* Disable interrupts and return after the sleep instruction */ - mfsr r9, SYSREG_RSR_INT0 - mtsr SYSREG_RAR_INT0, r8 - sbr r9, SYSREG_GM_OFFSET - mtsr SYSREG_RSR_INT0, r9 - rete - - /* - * void cpu_enter_standby(unsigned long sdramc_base) - * - * Enter PM_SUSPEND_STANDBY mode. At this point, all drivers - * are suspended and interrupts are disabled. Interrupts - * marked as 'wakeup' event sources may still come along and - * get us out of here. - * - * The SDRAM will be put into self-refresh mode (which does - * not require a clock from the CPU), and the CPU will be put - * into "frozen" mode (HSB bus stopped). The SDRAM controller - * will automatically bring the SDRAM into normal mode on the - * first access, and the power manager will automatically - * start the HSB and CPU clocks upon a wakeup event. - * - * This code uses the same "skip sleep" technique as above. - * It is very important that we jump directly to - * cpu_after_sleep after the sleep instruction since that's - * where we'll end up if the interrupt handler decides that we - * need to skip the sleep instruction. - */ - .global pm_standby - .type pm_standby, @function -pm_standby: - /* - * interrupts are already masked at this point, and EVBA - * points to pm_exception above. - */ - ld.w r10, r12[SDRAMC_LPR] - sub r8, pc, . - 1f /* return address for irq handler */ - mov r11, SDRAMC_LPR_LPCB_SELF_RFR - bfins r10, r11, 0, 2 /* LPCB <- self Refresh */ - sync 0 /* flush write buffer */ - st.w r12[SDRAMC_LPR], r10 /* put SDRAM in self-refresh mode */ - ld.w r11, r12[SDRAMC_LPR] - unmask_interrupts - sleep CPU_SLEEP_FROZEN -1: mask_interrupts - retal r12 - .size pm_standby, . - pm_standby - - .global pm_suspend_to_ram - .type pm_suspend_to_ram, @function -pm_suspend_to_ram: - /* - * interrupts are already masked at this point, and EVBA - * points to pm_exception above. - */ - mov r11, 0 - cache r11[2], 8 /* clean all dcache lines */ - sync 0 /* flush write buffer */ - ld.w r10, r12[SDRAMC_LPR] - sub r8, pc, . - 1f /* return address for irq handler */ - mov r11, SDRAMC_LPR_LPCB_SELF_RFR - bfins r10, r11, 0, 2 /* LPCB <- self refresh */ - st.w r12[SDRAMC_LPR], r10 /* put SDRAM in self-refresh mode */ - ld.w r11, r12[SDRAMC_LPR] - - unmask_interrupts - sleep CPU_SLEEP_STOP -1: mask_interrupts - - retal r12 - .size pm_suspend_to_ram, . - pm_suspend_to_ram - - .global pm_sram_end - .type pm_sram_end, @function -pm_sram_end: - .size pm_sram_end, 0 - -#endif /* CONFIG_PM */ diff --git a/arch/avr32/mach-at32ap/pm.c b/arch/avr32/mach-at32ap/pm.c deleted file mode 100644 index db190842b80c..000000000000 --- a/arch/avr32/mach-at32ap/pm.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * AVR32 AP Power Management - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - */ -#include <linux/io.h> -#include <linux/suspend.h> -#include <linux/vmalloc.h> - -#include <asm/cacheflush.h> -#include <asm/sysreg.h> - -#include <mach/chip.h> -#include <mach/pm.h> -#include <mach/sram.h> - -#include "sdramc.h" - -#define SRAM_PAGE_FLAGS (SYSREG_BIT(TLBELO_D) | SYSREG_BF(SZ, 1) \ - | SYSREG_BF(AP, 3) | SYSREG_BIT(G)) - - -static unsigned long pm_sram_start; -static size_t pm_sram_size; -static struct vm_struct *pm_sram_area; - -static void (*avr32_pm_enter_standby)(unsigned long sdramc_base); -static void (*avr32_pm_enter_str)(unsigned long sdramc_base); - -/* - * Must be called with interrupts disabled. Exceptions will be masked - * on return (i.e. all exceptions will be "unrecoverable".) - */ -static void *avr32_pm_map_sram(void) -{ - unsigned long vaddr; - unsigned long page_addr; - u32 tlbehi; - u32 mmucr; - - vaddr = (unsigned long)pm_sram_area->addr; - page_addr = pm_sram_start & PAGE_MASK; - - /* - * Mask exceptions and grab the first TLB entry. We won't be - * needing it while sleeping. - */ - asm volatile("ssrf %0" : : "i"(SYSREG_EM_OFFSET) : "memory"); - - mmucr = sysreg_read(MMUCR); - tlbehi = sysreg_read(TLBEHI); - sysreg_write(MMUCR, SYSREG_BFINS(DRP, 0, mmucr)); - - tlbehi = SYSREG_BF(ASID, SYSREG_BFEXT(ASID, tlbehi)); - tlbehi |= vaddr & PAGE_MASK; - tlbehi |= SYSREG_BIT(TLBEHI_V); - - sysreg_write(TLBELO, page_addr | SRAM_PAGE_FLAGS); - sysreg_write(TLBEHI, tlbehi); - __builtin_tlbw(); - - return (void *)(vaddr + pm_sram_start - page_addr); -} - -/* - * Must be called with interrupts disabled. Exceptions will be - * unmasked on return. - */ -static void avr32_pm_unmap_sram(void) -{ - u32 mmucr; - u32 tlbehi; - u32 tlbarlo; - - /* Going to update TLB entry at index 0 */ - mmucr = sysreg_read(MMUCR); - tlbehi = sysreg_read(TLBEHI); - sysreg_write(MMUCR, SYSREG_BFINS(DRP, 0, mmucr)); - - /* Clear the "valid" bit */ - tlbehi = SYSREG_BF(ASID, SYSREG_BFEXT(ASID, tlbehi)); - sysreg_write(TLBEHI, tlbehi); - - /* Mark it as "not accessed" */ - tlbarlo = sysreg_read(TLBARLO); - sysreg_write(TLBARLO, tlbarlo | 0x80000000U); - - /* Update the TLB */ - __builtin_tlbw(); - - /* Unmask exceptions */ - asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET) : "memory"); -} - -static int avr32_pm_valid_state(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_ON: - case PM_SUSPEND_STANDBY: - case PM_SUSPEND_MEM: - return 1; - - default: - return 0; - } -} - -static int avr32_pm_enter(suspend_state_t state) -{ - u32 lpr_saved; - u32 evba_saved; - void *sram; - - switch (state) { - case PM_SUSPEND_STANDBY: - sram = avr32_pm_map_sram(); - - /* Switch to in-sram exception handlers */ - evba_saved = sysreg_read(EVBA); - sysreg_write(EVBA, (unsigned long)sram); - - /* - * Save the LPR register so that we can re-enable - * SDRAM Low Power mode on resume. - */ - lpr_saved = sdramc_readl(LPR); - pr_debug("%s: Entering standby...\n", __func__); - avr32_pm_enter_standby(SDRAMC_BASE); - sdramc_writel(LPR, lpr_saved); - - /* Switch back to regular exception handlers */ - sysreg_write(EVBA, evba_saved); - - avr32_pm_unmap_sram(); - break; - - case PM_SUSPEND_MEM: - sram = avr32_pm_map_sram(); - - /* Switch to in-sram exception handlers */ - evba_saved = sysreg_read(EVBA); - sysreg_write(EVBA, (unsigned long)sram); - - /* - * Save the LPR register so that we can re-enable - * SDRAM Low Power mode on resume. - */ - lpr_saved = sdramc_readl(LPR); - pr_debug("%s: Entering suspend-to-ram...\n", __func__); - avr32_pm_enter_str(SDRAMC_BASE); - sdramc_writel(LPR, lpr_saved); - - /* Switch back to regular exception handlers */ - sysreg_write(EVBA, evba_saved); - - avr32_pm_unmap_sram(); - break; - - case PM_SUSPEND_ON: - pr_debug("%s: Entering idle...\n", __func__); - cpu_enter_idle(); - break; - - default: - pr_debug("%s: Invalid suspend state %d\n", __func__, state); - goto out; - } - - pr_debug("%s: wakeup\n", __func__); - -out: - return 0; -} - -static const struct platform_suspend_ops avr32_pm_ops = { - .valid = avr32_pm_valid_state, - .enter = avr32_pm_enter, -}; - -static unsigned long __init avr32_pm_offset(void *symbol) -{ - extern u8 pm_exception[]; - - return (unsigned long)symbol - (unsigned long)pm_exception; -} - -static int __init avr32_pm_init(void) -{ - extern u8 pm_exception[]; - extern u8 pm_irq0[]; - extern u8 pm_standby[]; - extern u8 pm_suspend_to_ram[]; - extern u8 pm_sram_end[]; - void *dst; - - /* - * To keep things simple, we depend on not needing more than a - * single page. - */ - pm_sram_size = avr32_pm_offset(pm_sram_end); - if (pm_sram_size > PAGE_SIZE) - goto err; - - pm_sram_start = sram_alloc(pm_sram_size); - if (!pm_sram_start) - goto err_alloc_sram; - - /* Grab a virtual area we can use later on. */ - pm_sram_area = get_vm_area(pm_sram_size, VM_IOREMAP); - if (!pm_sram_area) - goto err_vm_area; - pm_sram_area->phys_addr = pm_sram_start; - - local_irq_disable(); - dst = avr32_pm_map_sram(); - memcpy(dst, pm_exception, pm_sram_size); - flush_dcache_region(dst, pm_sram_size); - invalidate_icache_region(dst, pm_sram_size); - avr32_pm_unmap_sram(); - local_irq_enable(); - - avr32_pm_enter_standby = dst + avr32_pm_offset(pm_standby); - avr32_pm_enter_str = dst + avr32_pm_offset(pm_suspend_to_ram); - intc_set_suspend_handler(avr32_pm_offset(pm_irq0)); - - suspend_set_ops(&avr32_pm_ops); - - printk("AVR32 AP Power Management enabled\n"); - - return 0; - -err_vm_area: - sram_free(pm_sram_start, pm_sram_size); -err_alloc_sram: -err: - pr_err("AVR32 Power Management initialization failed\n"); - return -ENOMEM; -} -arch_initcall(avr32_pm_init); diff --git a/arch/avr32/mach-at32ap/pm.h b/arch/avr32/mach-at32ap/pm.h deleted file mode 100644 index 532a3732c214..000000000000 --- a/arch/avr32/mach-at32ap/pm.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Register definitions for the Power Manager (PM) - */ -#ifndef __ARCH_AVR32_MACH_AT32AP_PM_H__ -#define __ARCH_AVR32_MACH_AT32AP_PM_H__ - -/* PM register offsets */ -#define PM_MCCTRL 0x0000 -#define PM_CKSEL 0x0004 -#define PM_CPU_MASK 0x0008 -#define PM_HSB_MASK 0x000c -#define PM_PBA_MASK 0x0010 -#define PM_PBB_MASK 0x0014 -#define PM_PLL0 0x0020 -#define PM_PLL1 0x0024 -#define PM_IER 0x0040 -#define PM_IDR 0x0044 -#define PM_IMR 0x0048 -#define PM_ISR 0x004c -#define PM_ICR 0x0050 -#define PM_GCCTRL(x) (0x0060 + 4 * (x)) -#define PM_RCAUSE 0x00c0 - -/* Bitfields in CKSEL */ -#define PM_CPUSEL_OFFSET 0 -#define PM_CPUSEL_SIZE 3 -#define PM_CPUDIV_OFFSET 7 -#define PM_CPUDIV_SIZE 1 -#define PM_HSBSEL_OFFSET 8 -#define PM_HSBSEL_SIZE 3 -#define PM_HSBDIV_OFFSET 15 -#define PM_HSBDIV_SIZE 1 -#define PM_PBASEL_OFFSET 16 -#define PM_PBASEL_SIZE 3 -#define PM_PBADIV_OFFSET 23 -#define PM_PBADIV_SIZE 1 -#define PM_PBBSEL_OFFSET 24 -#define PM_PBBSEL_SIZE 3 -#define PM_PBBDIV_OFFSET 31 -#define PM_PBBDIV_SIZE 1 - -/* Bitfields in PLL0 */ -#define PM_PLLEN_OFFSET 0 -#define PM_PLLEN_SIZE 1 -#define PM_PLLOSC_OFFSET 1 -#define PM_PLLOSC_SIZE 1 -#define PM_PLLOPT_OFFSET 2 -#define PM_PLLOPT_SIZE 3 -#define PM_PLLDIV_OFFSET 8 -#define PM_PLLDIV_SIZE 8 -#define PM_PLLMUL_OFFSET 16 -#define PM_PLLMUL_SIZE 8 -#define PM_PLLCOUNT_OFFSET 24 -#define PM_PLLCOUNT_SIZE 6 -#define PM_PLLTEST_OFFSET 31 -#define PM_PLLTEST_SIZE 1 - -/* Bitfields in ICR */ -#define PM_LOCK0_OFFSET 0 -#define PM_LOCK0_SIZE 1 -#define PM_LOCK1_OFFSET 1 -#define PM_LOCK1_SIZE 1 -#define PM_WAKE_OFFSET 2 -#define PM_WAKE_SIZE 1 -#define PM_CKRDY_OFFSET 5 -#define PM_CKRDY_SIZE 1 -#define PM_MSKRDY_OFFSET 6 -#define PM_MSKRDY_SIZE 1 - -/* Bitfields in GCCTRL0 */ -#define PM_OSCSEL_OFFSET 0 -#define PM_OSCSEL_SIZE 1 -#define PM_PLLSEL_OFFSET 1 -#define PM_PLLSEL_SIZE 1 -#define PM_CEN_OFFSET 2 -#define PM_CEN_SIZE 1 -#define PM_DIVEN_OFFSET 4 -#define PM_DIVEN_SIZE 1 -#define PM_DIV_OFFSET 8 -#define PM_DIV_SIZE 8 - -/* Bitfields in RCAUSE */ -#define PM_POR_OFFSET 0 -#define PM_POR_SIZE 1 -#define PM_EXT_OFFSET 2 -#define PM_EXT_SIZE 1 -#define PM_WDT_OFFSET 3 -#define PM_WDT_SIZE 1 -#define PM_NTAE_OFFSET 4 -#define PM_NTAE_SIZE 1 - -/* Bit manipulation macros */ -#define PM_BIT(name) \ - (1 << PM_##name##_OFFSET) -#define PM_BF(name,value) \ - (((value) & ((1 << PM_##name##_SIZE) - 1)) \ - << PM_##name##_OFFSET) -#define PM_BFEXT(name,value) \ - (((value) >> PM_##name##_OFFSET) \ - & ((1 << PM_##name##_SIZE) - 1)) -#define PM_BFINS(name,value,old)\ - (((old) & ~(((1 << PM_##name##_SIZE) - 1) \ - << PM_##name##_OFFSET)) \ - | PM_BF(name,value)) - -/* Register access macros */ -#define pm_readl(reg) \ - __raw_readl((void __iomem __force *)PM_BASE + PM_##reg) -#define pm_writel(reg,value) \ - __raw_writel((value), (void __iomem __force *)PM_BASE + PM_##reg) - -#endif /* __ARCH_AVR32_MACH_AT32AP_PM_H__ */ diff --git a/arch/avr32/mach-at32ap/sdramc.h b/arch/avr32/mach-at32ap/sdramc.h deleted file mode 100644 index 66eeaed49073..000000000000 --- a/arch/avr32/mach-at32ap/sdramc.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Register definitions for the AT32AP SDRAM Controller - * - * Copyright (C) 2008 Atmel Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - */ - -/* Register offsets */ -#define SDRAMC_MR 0x0000 -#define SDRAMC_TR 0x0004 -#define SDRAMC_CR 0x0008 -#define SDRAMC_HSR 0x000c -#define SDRAMC_LPR 0x0010 -#define SDRAMC_IER 0x0014 -#define SDRAMC_IDR 0x0018 -#define SDRAMC_IMR 0x001c -#define SDRAMC_ISR 0x0020 -#define SDRAMC_MDR 0x0024 - -/* MR - Mode Register */ -#define SDRAMC_MR_MODE_NORMAL ( 0 << 0) -#define SDRAMC_MR_MODE_NOP ( 1 << 0) -#define SDRAMC_MR_MODE_BANKS_PRECHARGE ( 2 << 0) -#define SDRAMC_MR_MODE_LOAD_MODE ( 3 << 0) -#define SDRAMC_MR_MODE_AUTO_REFRESH ( 4 << 0) -#define SDRAMC_MR_MODE_EXT_LOAD_MODE ( 5 << 0) -#define SDRAMC_MR_MODE_POWER_DOWN ( 6 << 0) - -/* CR - Configuration Register */ -#define SDRAMC_CR_NC_8_BITS ( 0 << 0) -#define SDRAMC_CR_NC_9_BITS ( 1 << 0) -#define SDRAMC_CR_NC_10_BITS ( 2 << 0) -#define SDRAMC_CR_NC_11_BITS ( 3 << 0) -#define SDRAMC_CR_NR_11_BITS ( 0 << 2) -#define SDRAMC_CR_NR_12_BITS ( 1 << 2) -#define SDRAMC_CR_NR_13_BITS ( 2 << 2) -#define SDRAMC_CR_NB_2_BANKS ( 0 << 4) -#define SDRAMC_CR_NB_4_BANKS ( 1 << 4) -#define SDRAMC_CR_CAS(x) ((x) << 5) -#define SDRAMC_CR_DBW_32_BITS ( 0 << 7) -#define SDRAMC_CR_DBW_16_BITS ( 1 << 7) -#define SDRAMC_CR_TWR(x) ((x) << 8) -#define SDRAMC_CR_TRC(x) ((x) << 12) -#define SDRAMC_CR_TRP(x) ((x) << 16) -#define SDRAMC_CR_TRCD(x) ((x) << 20) -#define SDRAMC_CR_TRAS(x) ((x) << 24) -#define SDRAMC_CR_TXSR(x) ((x) << 28) - -/* HSR - High Speed Register */ -#define SDRAMC_HSR_DA ( 1 << 0) - -/* LPR - Low Power Register */ -#define SDRAMC_LPR_LPCB_INHIBIT ( 0 << 0) -#define SDRAMC_LPR_LPCB_SELF_RFR ( 1 << 0) -#define SDRAMC_LPR_LPCB_PDOWN ( 2 << 0) -#define SDRAMC_LPR_LPCB_DEEP_PDOWN ( 3 << 0) -#define SDRAMC_LPR_PASR(x) ((x) << 4) -#define SDRAMC_LPR_TCSR(x) ((x) << 8) -#define SDRAMC_LPR_DS(x) ((x) << 10) -#define SDRAMC_LPR_TIMEOUT(x) ((x) << 12) - -/* IER/IDR/IMR/ISR - Interrupt Enable/Disable/Mask/Status Register */ -#define SDRAMC_ISR_RES ( 1 << 0) - -/* MDR - Memory Device Register */ -#define SDRAMC_MDR_MD_SDRAM ( 0 << 0) -#define SDRAMC_MDR_MD_LOW_PWR_SDRAM ( 1 << 0) - -/* Register access macros */ -#define sdramc_readl(reg) \ - __raw_readl((void __iomem __force *)SDRAMC_BASE + SDRAMC_##reg) -#define sdramc_writel(reg, value) \ - __raw_writel(value, (void __iomem __force *)SDRAMC_BASE + SDRAMC_##reg) diff --git a/arch/avr32/mm/Makefile b/arch/avr32/mm/Makefile deleted file mode 100644 index 0066491f90d4..000000000000 --- a/arch/avr32/mm/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for the Linux/AVR32 kernel. -# - -obj-y += init.o clear_page.o copy_page.o dma-coherent.o -obj-y += ioremap.o cache.o fault.o tlb.o diff --git a/arch/avr32/mm/cache.c b/arch/avr32/mm/cache.c deleted file mode 100644 index d9476825fc43..000000000000 --- a/arch/avr32/mm/cache.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/highmem.h> -#include <linux/unistd.h> - -#include <asm/cacheflush.h> -#include <asm/cachectl.h> -#include <asm/processor.h> -#include <linux/uaccess.h> -#include <asm/syscalls.h> - -/* - * If you attempt to flush anything more than this, you need superuser - * privileges. The value is completely arbitrary. - */ -#define CACHEFLUSH_MAX_LEN 1024 - -void invalidate_dcache_region(void *start, size_t size) -{ - unsigned long v, begin, end, linesz, mask; - - linesz = boot_cpu_data.dcache.linesz; - mask = linesz - 1; - - /* when first and/or last cachelines are shared, flush them - * instead of invalidating ... never discard valid data! - */ - begin = (unsigned long)start; - end = begin + size; - - if (begin & mask) { - flush_dcache_line(start); - begin += linesz; - } - if (end & mask) { - flush_dcache_line((void *)end); - end &= ~mask; - } - - /* remaining cachelines only need invalidation */ - for (v = begin; v < end; v += linesz) - invalidate_dcache_line((void *)v); - flush_write_buffer(); -} - -void clean_dcache_region(void *start, size_t size) -{ - unsigned long v, begin, end, linesz; - - linesz = boot_cpu_data.dcache.linesz; - begin = (unsigned long)start & ~(linesz - 1); - end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1); - - for (v = begin; v < end; v += linesz) - clean_dcache_line((void *)v); - flush_write_buffer(); -} - -void flush_dcache_region(void *start, size_t size) -{ - unsigned long v, begin, end, linesz; - - linesz = boot_cpu_data.dcache.linesz; - begin = (unsigned long)start & ~(linesz - 1); - end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1); - - for (v = begin; v < end; v += linesz) - flush_dcache_line((void *)v); - flush_write_buffer(); -} - -void invalidate_icache_region(void *start, size_t size) -{ - unsigned long v, begin, end, linesz; - - linesz = boot_cpu_data.icache.linesz; - begin = (unsigned long)start & ~(linesz - 1); - end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1); - - for (v = begin; v < end; v += linesz) - invalidate_icache_line((void *)v); -} - -static inline void __flush_icache_range(unsigned long start, unsigned long end) -{ - unsigned long v, linesz; - - linesz = boot_cpu_data.dcache.linesz; - for (v = start; v < end; v += linesz) { - clean_dcache_line((void *)v); - invalidate_icache_line((void *)v); - } - - flush_write_buffer(); -} - -/* - * This one is called after a module has been loaded. - */ -void flush_icache_range(unsigned long start, unsigned long end) -{ - unsigned long linesz; - - linesz = boot_cpu_data.dcache.linesz; - __flush_icache_range(start & ~(linesz - 1), - (end + linesz - 1) & ~(linesz - 1)); -} -EXPORT_SYMBOL(flush_icache_range); - -/* - * This one is called from __do_fault() and do_swap_page(). - */ -void flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - if (vma->vm_flags & VM_EXEC) { - void *v = page_address(page); - __flush_icache_range((unsigned long)v, (unsigned long)v + PAGE_SIZE); - } -} - -asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len) -{ - int ret; - - if (len > CACHEFLUSH_MAX_LEN) { - ret = -EPERM; - if (!capable(CAP_SYS_ADMIN)) - goto out; - } - - ret = -EFAULT; - if (!access_ok(VERIFY_WRITE, addr, len)) - goto out; - - switch (operation) { - case CACHE_IFLUSH: - flush_icache_range((unsigned long)addr, - (unsigned long)addr + len); - ret = 0; - break; - default: - ret = -EINVAL; - } - -out: - return ret; -} - -void copy_to_user_page(struct vm_area_struct *vma, struct page *page, - unsigned long vaddr, void *dst, const void *src, - unsigned long len) -{ - memcpy(dst, src, len); - if (vma->vm_flags & VM_EXEC) - flush_icache_range((unsigned long)dst, - (unsigned long)dst + len); -} diff --git a/arch/avr32/mm/clear_page.S b/arch/avr32/mm/clear_page.S deleted file mode 100644 index 5d70dca00699..000000000000 --- a/arch/avr32/mm/clear_page.S +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/linkage.h> -#include <asm/page.h> - -/* - * clear_page - * r12: P1 address (to) - */ - .text - .global clear_page -clear_page: - sub r9, r12, -PAGE_SIZE - mov r10, 0 - mov r11, 0 -0: st.d r12++, r10 - cp r12, r9 - brne 0b - mov pc, lr diff --git a/arch/avr32/mm/copy_page.S b/arch/avr32/mm/copy_page.S deleted file mode 100644 index c2b3752946b8..000000000000 --- a/arch/avr32/mm/copy_page.S +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/linkage.h> -#include <asm/page.h> - -/* - * copy_page - * - * r12 to (P1 address) - * r11 from (P1 address) - * r8-r10 scratch - */ - .text - .global copy_page -copy_page: - sub r10, r11, -(1 << PAGE_SHIFT) - /* pref r11[0] */ -1: /* pref r11[8] */ - ld.d r8, r11++ - st.d r12++, r8 - cp r11, r10 - brlo 1b - mov pc, lr diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c deleted file mode 100644 index 555222d4f414..000000000000 --- a/arch/avr32/mm/dma-coherent.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/dma-mapping.h> -#include <linux/gfp.h> -#include <linux/export.h> -#include <linux/mm.h> -#include <linux/device.h> -#include <linux/scatterlist.h> - -#include <asm/processor.h> -#include <asm/cacheflush.h> -#include <asm/io.h> -#include <asm/addrspace.h> - -void dma_cache_sync(struct device *dev, void *vaddr, size_t size, int direction) -{ - /* - * No need to sync an uncached area - */ - if (PXSEG(vaddr) == P2SEG) - return; - - switch (direction) { - case DMA_FROM_DEVICE: /* invalidate only */ - invalidate_dcache_region(vaddr, size); - break; - case DMA_TO_DEVICE: /* writeback only */ - clean_dcache_region(vaddr, size); - break; - case DMA_BIDIRECTIONAL: /* writeback and invalidate */ - flush_dcache_region(vaddr, size); - break; - default: - BUG(); - } -} -EXPORT_SYMBOL(dma_cache_sync); - -static struct page *__dma_alloc(struct device *dev, size_t size, - dma_addr_t *handle, gfp_t gfp) -{ - struct page *page, *free, *end; - int order; - - /* Following is a work-around (a.k.a. hack) to prevent pages - * with __GFP_COMP being passed to split_page() which cannot - * handle them. The real problem is that this flag probably - * should be 0 on AVR32 as it is not supported on this - * platform--see CONFIG_HUGETLB_PAGE. */ - gfp &= ~(__GFP_COMP); - - size = PAGE_ALIGN(size); - order = get_order(size); - - page = alloc_pages(gfp, order); - if (!page) - return NULL; - split_page(page, order); - - /* - * When accessing physical memory with valid cache data, we - * get a cache hit even if the virtual memory region is marked - * as uncached. - * - * Since the memory is newly allocated, there is no point in - * doing a writeback. If the previous owner cares, he should - * have flushed the cache before releasing the memory. - */ - invalidate_dcache_region(phys_to_virt(page_to_phys(page)), size); - - *handle = page_to_bus(page); - free = page + (size >> PAGE_SHIFT); - end = page + (1 << order); - - /* - * Free any unused pages - */ - while (free < end) { - __free_page(free); - free++; - } - - return page; -} - -static void __dma_free(struct device *dev, size_t size, - struct page *page, dma_addr_t handle) -{ - struct page *end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT); - - while (page < end) - __free_page(page++); -} - -static void *avr32_dma_alloc(struct device *dev, size_t size, - dma_addr_t *handle, gfp_t gfp, unsigned long attrs) -{ - struct page *page; - dma_addr_t phys; - - page = __dma_alloc(dev, size, handle, gfp); - if (!page) - return NULL; - phys = page_to_phys(page); - - if (attrs & DMA_ATTR_WRITE_COMBINE) { - /* Now, map the page into P3 with write-combining turned on */ - *handle = phys; - return __ioremap(phys, size, _PAGE_BUFFER); - } else { - return phys_to_uncached(phys); - } -} - -static void avr32_dma_free(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t handle, unsigned long attrs) -{ - struct page *page; - - if (attrs & DMA_ATTR_WRITE_COMBINE) { - iounmap(cpu_addr); - - page = phys_to_page(handle); - } else { - void *addr = phys_to_cached(uncached_to_phys(cpu_addr)); - - pr_debug("avr32_dma_free addr %p (phys %08lx) size %u\n", - cpu_addr, (unsigned long)handle, (unsigned)size); - - BUG_ON(!virt_addr_valid(addr)); - page = virt_to_page(addr); - } - - __dma_free(dev, size, page, handle); -} - -static dma_addr_t avr32_dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction, unsigned long attrs) -{ - void *cpu_addr = page_address(page) + offset; - - if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - dma_cache_sync(dev, cpu_addr, size, direction); - return virt_to_bus(cpu_addr); -} - -static int avr32_dma_map_sg(struct device *dev, struct scatterlist *sglist, - int nents, enum dma_data_direction direction, - unsigned long attrs) -{ - int i; - struct scatterlist *sg; - - for_each_sg(sglist, sg, nents, i) { - char *virt; - - sg->dma_address = page_to_bus(sg_page(sg)) + sg->offset; - virt = sg_virt(sg); - - if (attrs & DMA_ATTR_SKIP_CPU_SYNC) - continue; - - dma_cache_sync(dev, virt, sg->length, direction); - } - - return nents; -} - -static void avr32_dma_sync_single_for_device(struct device *dev, - dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction) -{ - dma_cache_sync(dev, bus_to_virt(dma_handle), size, direction); -} - -static void avr32_dma_sync_sg_for_device(struct device *dev, - struct scatterlist *sglist, int nents, - enum dma_data_direction direction) -{ - int i; - struct scatterlist *sg; - - for_each_sg(sglist, sg, nents, i) - dma_cache_sync(dev, sg_virt(sg), sg->length, direction); -} - -const struct dma_map_ops avr32_dma_ops = { - .alloc = avr32_dma_alloc, - .free = avr32_dma_free, - .map_page = avr32_dma_map_page, - .map_sg = avr32_dma_map_sg, - .sync_single_for_device = avr32_dma_sync_single_for_device, - .sync_sg_for_device = avr32_dma_sync_sg_for_device, -}; -EXPORT_SYMBOL(avr32_dma_ops); diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c deleted file mode 100644 index b3977e9208a3..000000000000 --- a/arch/avr32/mm/fault.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * Based on linux/arch/sh/mm/fault.c: - * Copyright (C) 1999 Niibe Yutaka - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/mm.h> -#include <linux/extable.h> -#include <linux/pagemap.h> -#include <linux/kdebug.h> -#include <linux/kprobes.h> -#include <linux/uaccess.h> - -#include <asm/mmu_context.h> -#include <asm/sysreg.h> -#include <asm/tlb.h> - -#ifdef CONFIG_KPROBES -static inline int notify_page_fault(struct pt_regs *regs, int trap) -{ - int ret = 0; - - if (!user_mode(regs)) { - if (kprobe_running() && kprobe_fault_handler(regs, trap)) - ret = 1; - } - - return ret; -} -#else -static inline int notify_page_fault(struct pt_regs *regs, int trap) -{ - return 0; -} -#endif - -int exception_trace = 1; - -/* - * This routine handles page faults. It determines the address and the - * problem, and then passes it off to one of the appropriate routines. - * - * ecr is the Exception Cause Register. Possible values are: - * 6: Protection fault (instruction access) - * 15: Protection fault (read access) - * 16: Protection fault (write access) - * 20: Page not found (instruction access) - * 24: Page not found (read access) - * 28: Page not found (write access) - */ -asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) -{ - struct task_struct *tsk; - struct mm_struct *mm; - struct vm_area_struct *vma; - const struct exception_table_entry *fixup; - unsigned long address; - unsigned long page; - long signr; - int code; - int fault; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; - - if (notify_page_fault(regs, ecr)) - return; - - address = sysreg_read(TLBEAR); - - tsk = current; - mm = tsk->mm; - - signr = SIGSEGV; - code = SEGV_MAPERR; - - /* - * If we're in an interrupt or have no user context, we must - * not take the fault... - */ - if (faulthandler_disabled() || !mm || regs->sr & SYSREG_BIT(GM)) - goto no_context; - - local_irq_enable(); - - if (user_mode(regs)) - flags |= FAULT_FLAG_USER; -retry: - down_read(&mm->mmap_sem); - - vma = find_vma(mm, address); - if (!vma) - goto bad_area; - if (vma->vm_start <= address) - goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; - if (expand_stack(vma, address)) - goto bad_area; - - /* - * Ok, we have a good vm_area for this memory access, so we - * can handle it... - */ -good_area: - code = SEGV_ACCERR; - - switch (ecr) { - case ECR_PROTECTION_X: - case ECR_TLB_MISS_X: - if (!(vma->vm_flags & VM_EXEC)) - goto bad_area; - break; - case ECR_PROTECTION_R: - case ECR_TLB_MISS_R: - if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) - goto bad_area; - break; - case ECR_PROTECTION_W: - case ECR_TLB_MISS_W: - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - flags |= FAULT_FLAG_WRITE; - break; - default: - panic("Unhandled case %lu in do_page_fault!", ecr); - } - - /* - * If for any reason at all we couldn't handle the fault, make - * sure we exit gracefully rather than endlessly redo the - * fault. - */ - fault = handle_mm_fault(vma, address, flags); - - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return; - - if (unlikely(fault & VM_FAULT_ERROR)) { - if (fault & VM_FAULT_OOM) - goto out_of_memory; - else if (fault & VM_FAULT_SIGSEGV) - goto bad_area; - else if (fault & VM_FAULT_SIGBUS) - goto do_sigbus; - BUG(); - } - - if (flags & FAULT_FLAG_ALLOW_RETRY) { - if (fault & VM_FAULT_MAJOR) - tsk->maj_flt++; - else - tsk->min_flt++; - if (fault & VM_FAULT_RETRY) { - flags &= ~FAULT_FLAG_ALLOW_RETRY; - flags |= FAULT_FLAG_TRIED; - - /* - * No need to up_read(&mm->mmap_sem) as we would have - * already released it in __lock_page_or_retry() in - * mm/filemap.c. - */ - goto retry; - } - } - - up_read(&mm->mmap_sem); - return; - - /* - * Something tried to access memory that isn't in our memory - * map. Fix it, but check if it's kernel or user first... - */ -bad_area: - up_read(&mm->mmap_sem); - - if (user_mode(regs)) { - if (exception_trace && printk_ratelimit()) - printk("%s%s[%d]: segfault at %08lx pc %08lx " - "sp %08lx ecr %lu\n", - is_global_init(tsk) ? KERN_EMERG : KERN_INFO, - tsk->comm, tsk->pid, address, regs->pc, - regs->sp, ecr); - _exception(SIGSEGV, regs, code, address); - return; - } - -no_context: - /* Are we prepared to handle this kernel fault? */ - fixup = search_exception_tables(regs->pc); - if (fixup) { - regs->pc = fixup->fixup; - return; - } - - /* - * Oops. The kernel tried to access some bad page. We'll have - * to terminate things with extreme prejudice. - */ - if (address < PAGE_SIZE) - printk(KERN_ALERT - "Unable to handle kernel NULL pointer dereference"); - else - printk(KERN_ALERT - "Unable to handle kernel paging request"); - printk(" at virtual address %08lx\n", address); - - page = sysreg_read(PTBR); - printk(KERN_ALERT "ptbr = %08lx", page); - if (address >= TASK_SIZE) - page = (unsigned long)swapper_pg_dir; - if (page) { - page = ((unsigned long *)page)[address >> 22]; - printk(" pgd = %08lx", page); - if (page & _PAGE_PRESENT) { - page &= PAGE_MASK; - address &= 0x003ff000; - page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT]; - printk(" pte = %08lx", page); - } - } - printk("\n"); - die("Kernel access of bad area", regs, signr); - return; - - /* - * We ran out of memory, or some other thing happened to us - * that made us unable to handle the page fault gracefully. - */ -out_of_memory: - up_read(&mm->mmap_sem); - if (!user_mode(regs)) - goto no_context; - pagefault_out_of_memory(); - return; - -do_sigbus: - up_read(&mm->mmap_sem); - - /* Kernel mode? Handle exceptions or die */ - signr = SIGBUS; - code = BUS_ADRERR; - if (!user_mode(regs)) - goto no_context; - - if (exception_trace) - printk("%s%s[%d]: bus error at %08lx pc %08lx " - "sp %08lx ecr %lu\n", - is_global_init(tsk) ? KERN_EMERG : KERN_INFO, - tsk->comm, tsk->pid, address, regs->pc, - regs->sp, ecr); - - _exception(SIGBUS, regs, BUS_ADRERR, address); -} - -asmlinkage void do_bus_error(unsigned long addr, int write_access, - struct pt_regs *regs) -{ - printk(KERN_ALERT - "Bus error at physical address 0x%08lx (%s access)\n", - addr, write_access ? "write" : "read"); - printk(KERN_INFO "DTLB dump:\n"); - dump_dtlb(); - die("Bus Error", regs, SIGKILL); -} diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c deleted file mode 100644 index def5391d927a..000000000000 --- a/arch/avr32/mm/init.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/gfp.h> -#include <linux/mm.h> -#include <linux/swap.h> -#include <linux/init.h> -#include <linux/mmzone.h> -#include <linux/module.h> -#include <linux/bootmem.h> -#include <linux/pagemap.h> -#include <linux/nodemask.h> - -#include <asm/page.h> -#include <asm/mmu_context.h> -#include <asm/tlb.h> -#include <asm/io.h> -#include <asm/dma.h> -#include <asm/setup.h> -#include <asm/sections.h> - -pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_data; - -struct page *empty_zero_page; -EXPORT_SYMBOL(empty_zero_page); - -/* - * Cache of MMU context last used. - */ -unsigned long mmu_context_cache = NO_CONTEXT; - -/* - * paging_init() sets up the page tables - * - * This routine also unmaps the page at virtual kernel address 0, so - * that we can trap those pesky NULL-reference errors in the kernel. - */ -void __init paging_init(void) -{ - extern unsigned long _evba; - void *zero_page; - int nid; - - /* - * Make sure we can handle exceptions before enabling - * paging. Not that we should ever _get_ any exceptions this - * early, but you never know... - */ - printk("Exception vectors start at %p\n", &_evba); - sysreg_write(EVBA, (unsigned long)&_evba); - - /* - * Since we are ready to handle exceptions now, we should let - * the CPU generate them... - */ - __asm__ __volatile__ ("csrf %0" : : "i"(SR_EM_BIT)); - - /* - * Allocate the zero page. The allocator will panic if it - * can't satisfy the request, so no need to check. - */ - zero_page = alloc_bootmem_low_pages_node(NODE_DATA(0), - PAGE_SIZE); - - sysreg_write(PTBR, (unsigned long)swapper_pg_dir); - enable_mmu(); - printk ("CPU: Paging enabled\n"); - - for_each_online_node(nid) { - pg_data_t *pgdat = NODE_DATA(nid); - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long low, start_pfn; - - start_pfn = pgdat->bdata->node_min_pfn; - low = pgdat->bdata->node_low_pfn; - - memset(zones_size, 0, sizeof(zones_size)); - zones_size[ZONE_NORMAL] = low - start_pfn; - - printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n", - nid, start_pfn, low); - - free_area_init_node(nid, zones_size, start_pfn, NULL); - - printk("Node %u: mem_map starts at %p\n", - pgdat->node_id, pgdat->node_mem_map); - } - - mem_map = NODE_DATA(0)->node_mem_map; - - empty_zero_page = virt_to_page(zero_page); - flush_dcache_page(empty_zero_page); -} - -void __init mem_init(void) -{ - pg_data_t *pgdat; - - high_memory = NULL; - for_each_online_pgdat(pgdat) - high_memory = max_t(void *, high_memory, - __va(pgdat_end_pfn(pgdat) << PAGE_SHIFT)); - - set_max_mapnr(MAP_NR(high_memory)); - free_all_bootmem(); - mem_init_print_info(NULL); -} - -void free_initmem(void) -{ - free_initmem_default(-1); -} - -#ifdef CONFIG_BLK_DEV_INITRD -void free_initrd_mem(unsigned long start, unsigned long end) -{ - free_reserved_area((void *)start, (void *)end, -1, "initrd"); -} -#endif diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c deleted file mode 100644 index 7def0d84cec6..000000000000 --- a/arch/avr32/mm/ioremap.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/vmalloc.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/io.h> -#include <linux/slab.h> - -#include <asm/pgtable.h> -#include <asm/addrspace.h> - -/* - * Re-map an arbitrary physical address space into the kernel virtual - * address space. Needed when the kernel wants to access physical - * memory directly. - */ -void __iomem *__ioremap(unsigned long phys_addr, size_t size, - unsigned long flags) -{ - unsigned long addr; - struct vm_struct *area; - unsigned long offset, last_addr; - pgprot_t prot; - - /* - * Check if we can simply use the P4 segment. This area is - * uncacheable, so if caching/buffering is requested, we can't - * use it. - */ - if ((phys_addr >= P4SEG) && (flags == 0)) - return (void __iomem *)phys_addr; - - /* Don't allow wraparound or zero size */ - last_addr = phys_addr + size - 1; - if (!size || last_addr < phys_addr) - return NULL; - - /* - * XXX: When mapping regular RAM, we'd better make damn sure - * it's never used for anything else. But this is really the - * caller's responsibility... - */ - if (PHYSADDR(P2SEGADDR(phys_addr)) == phys_addr) - return (void __iomem *)P2SEGADDR(phys_addr); - - /* Mappings have to be page-aligned */ - offset = phys_addr & ~PAGE_MASK; - phys_addr &= PAGE_MASK; - size = PAGE_ALIGN(last_addr + 1) - phys_addr; - - prot = __pgprot(_PAGE_PRESENT | _PAGE_GLOBAL | _PAGE_RW | _PAGE_DIRTY - | _PAGE_ACCESSED | _PAGE_TYPE_SMALL | flags); - - /* - * Ok, go for it.. - */ - area = get_vm_area(size, VM_IOREMAP); - if (!area) - return NULL; - area->phys_addr = phys_addr; - addr = (unsigned long )area->addr; - if (ioremap_page_range(addr, addr + size, phys_addr, prot)) { - vunmap((void *)addr); - return NULL; - } - - return (void __iomem *)(offset + (char *)addr); -} -EXPORT_SYMBOL(__ioremap); - -void __iounmap(void __iomem *addr) -{ - struct vm_struct *p; - - if ((unsigned long)addr >= P4SEG) - return; - if (PXSEG(addr) == P2SEG) - return; - - p = remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr)); - if (unlikely(!p)) { - printk (KERN_ERR "iounmap: bad address %p\n", addr); - return; - } - - kfree (p); -} -EXPORT_SYMBOL(__iounmap); diff --git a/arch/avr32/mm/tlb.c b/arch/avr32/mm/tlb.c deleted file mode 100644 index 0da23109f817..000000000000 --- a/arch/avr32/mm/tlb.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * AVR32 TLB operations - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/mm.h> - -#include <asm/mmu_context.h> - -/* TODO: Get the correct number from the CONFIG1 system register */ -#define NR_TLB_ENTRIES 32 - -static void show_dtlb_entry(unsigned int index) -{ - u32 tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save; - unsigned long flags; - - local_irq_save(flags); - mmucr_save = sysreg_read(MMUCR); - tlbehi_save = sysreg_read(TLBEHI); - mmucr = SYSREG_BFINS(DRP, index, mmucr_save); - sysreg_write(MMUCR, mmucr); - - __builtin_tlbr(); - cpu_sync_pipeline(); - - tlbehi = sysreg_read(TLBEHI); - tlbelo = sysreg_read(TLBELO); - - printk("%2u: %c %c %02x %05x %05x %o %o %c %c %c %c\n", - index, - SYSREG_BFEXT(TLBEHI_V, tlbehi) ? '1' : '0', - SYSREG_BFEXT(G, tlbelo) ? '1' : '0', - SYSREG_BFEXT(ASID, tlbehi), - SYSREG_BFEXT(VPN, tlbehi) >> 2, - SYSREG_BFEXT(PFN, tlbelo) >> 2, - SYSREG_BFEXT(AP, tlbelo), - SYSREG_BFEXT(SZ, tlbelo), - SYSREG_BFEXT(TLBELO_C, tlbelo) ? 'C' : ' ', - SYSREG_BFEXT(B, tlbelo) ? 'B' : ' ', - SYSREG_BFEXT(W, tlbelo) ? 'W' : ' ', - SYSREG_BFEXT(TLBELO_D, tlbelo) ? 'D' : ' '); - - sysreg_write(MMUCR, mmucr_save); - sysreg_write(TLBEHI, tlbehi_save); - cpu_sync_pipeline(); - local_irq_restore(flags); -} - -void dump_dtlb(void) -{ - unsigned int i; - - printk("ID V G ASID VPN PFN AP SZ C B W D\n"); - for (i = 0; i < NR_TLB_ENTRIES; i++) - show_dtlb_entry(i); -} - -static void update_dtlb(unsigned long address, pte_t pte) -{ - u32 tlbehi; - u32 mmucr; - - /* - * We're not changing the ASID here, so no need to flush the - * pipeline. - */ - tlbehi = sysreg_read(TLBEHI); - tlbehi = SYSREG_BF(ASID, SYSREG_BFEXT(ASID, tlbehi)); - tlbehi |= address & MMU_VPN_MASK; - tlbehi |= SYSREG_BIT(TLBEHI_V); - sysreg_write(TLBEHI, tlbehi); - - /* Does this mapping already exist? */ - __builtin_tlbs(); - mmucr = sysreg_read(MMUCR); - - if (mmucr & SYSREG_BIT(MMUCR_N)) { - /* Not found -- pick a not-recently-accessed entry */ - unsigned int rp; - u32 tlbar = sysreg_read(TLBARLO); - - rp = 32 - fls(tlbar); - if (rp == 32) { - rp = 0; - sysreg_write(TLBARLO, -1L); - } - - mmucr = SYSREG_BFINS(DRP, rp, mmucr); - sysreg_write(MMUCR, mmucr); - } - - sysreg_write(TLBELO, pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK); - - /* Let's go */ - __builtin_tlbw(); -} - -void update_mmu_cache(struct vm_area_struct *vma, - unsigned long address, pte_t *ptep) -{ - unsigned long flags; - - /* ptrace may call this routine */ - if (vma && current->active_mm != vma->vm_mm) - return; - - local_irq_save(flags); - update_dtlb(address, *ptep); - local_irq_restore(flags); -} - -static void __flush_tlb_page(unsigned long asid, unsigned long page) -{ - u32 mmucr, tlbehi; - - /* - * Caller is responsible for masking out non-PFN bits in page - * and changing the current ASID if necessary. This means that - * we don't need to flush the pipeline after writing TLBEHI. - */ - tlbehi = page | asid; - sysreg_write(TLBEHI, tlbehi); - - __builtin_tlbs(); - mmucr = sysreg_read(MMUCR); - - if (!(mmucr & SYSREG_BIT(MMUCR_N))) { - unsigned int entry; - u32 tlbarlo; - - /* Clear the "valid" bit */ - sysreg_write(TLBEHI, tlbehi); - - /* mark the entry as "not accessed" */ - entry = SYSREG_BFEXT(DRP, mmucr); - tlbarlo = sysreg_read(TLBARLO); - tlbarlo |= (0x80000000UL >> entry); - sysreg_write(TLBARLO, tlbarlo); - - /* update the entry with valid bit clear */ - __builtin_tlbw(); - } -} - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (vma->vm_mm && vma->vm_mm->context != NO_CONTEXT) { - unsigned long flags, asid; - unsigned long saved_asid = MMU_NO_ASID; - - asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK; - page &= PAGE_MASK; - - local_irq_save(flags); - if (vma->vm_mm != current->mm) { - saved_asid = get_asid(); - set_asid(asid); - } - - __flush_tlb_page(asid, page); - - if (saved_asid != MMU_NO_ASID) - set_asid(saved_asid); - local_irq_restore(flags); - } -} - -void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context != NO_CONTEXT) { - unsigned long flags; - int size; - - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - - if (size > (MMU_DTLB_ENTRIES / 4)) { /* Too many entries to flush */ - mm->context = NO_CONTEXT; - if (mm == current->mm) - activate_context(mm); - } else { - unsigned long asid; - unsigned long saved_asid; - - asid = mm->context & MMU_CONTEXT_ASID_MASK; - saved_asid = MMU_NO_ASID; - - start &= PAGE_MASK; - end += (PAGE_SIZE - 1); - end &= PAGE_MASK; - - if (mm != current->mm) { - saved_asid = get_asid(); - set_asid(asid); - } - - while (start < end) { - __flush_tlb_page(asid, start); - start += PAGE_SIZE; - } - if (saved_asid != MMU_NO_ASID) - set_asid(saved_asid); - } - local_irq_restore(flags); - } -} - -/* - * This function depends on the pages to be flushed having the G - * (global) bit set in their pte. This is true for all - * PAGE_KERNEL(_RO) pages. - */ -void flush_tlb_kernel_range(unsigned long start, unsigned long end) -{ - unsigned long flags; - int size; - - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - if (size > (MMU_DTLB_ENTRIES / 4)) { /* Too many entries to flush */ - flush_tlb_all(); - } else { - unsigned long asid; - - local_irq_save(flags); - asid = get_asid(); - - start &= PAGE_MASK; - end += (PAGE_SIZE - 1); - end &= PAGE_MASK; - - while (start < end) { - __flush_tlb_page(asid, start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - /* Invalidate all TLB entries of this process by getting a new ASID */ - if (mm->context != NO_CONTEXT) { - unsigned long flags; - - local_irq_save(flags); - mm->context = NO_CONTEXT; - if (mm == current->mm) - activate_context(mm); - local_irq_restore(flags); - } -} - -void flush_tlb_all(void) -{ - unsigned long flags; - - local_irq_save(flags); - sysreg_write(MMUCR, sysreg_read(MMUCR) | SYSREG_BIT(MMUCR_I)); - local_irq_restore(flags); -} - -#ifdef CONFIG_PROC_FS - -#include <linux/seq_file.h> -#include <linux/proc_fs.h> -#include <linux/init.h> - -static void *tlb_start(struct seq_file *tlb, loff_t *pos) -{ - static unsigned long tlb_index; - - if (*pos >= NR_TLB_ENTRIES) - return NULL; - - tlb_index = 0; - return &tlb_index; -} - -static void *tlb_next(struct seq_file *tlb, void *v, loff_t *pos) -{ - unsigned long *index = v; - - if (*index >= NR_TLB_ENTRIES - 1) - return NULL; - - ++*pos; - ++*index; - return index; -} - -static void tlb_stop(struct seq_file *tlb, void *v) -{ - -} - -static int tlb_show(struct seq_file *tlb, void *v) -{ - unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save; - unsigned long flags; - unsigned long *index = v; - - if (*index == 0) - seq_puts(tlb, "ID V G ASID VPN PFN AP SZ C B W D\n"); - - BUG_ON(*index >= NR_TLB_ENTRIES); - - local_irq_save(flags); - mmucr_save = sysreg_read(MMUCR); - tlbehi_save = sysreg_read(TLBEHI); - mmucr = SYSREG_BFINS(DRP, *index, mmucr_save); - sysreg_write(MMUCR, mmucr); - - /* TLBR might change the ASID */ - __builtin_tlbr(); - cpu_sync_pipeline(); - - tlbehi = sysreg_read(TLBEHI); - tlbelo = sysreg_read(TLBELO); - - sysreg_write(MMUCR, mmucr_save); - sysreg_write(TLBEHI, tlbehi_save); - cpu_sync_pipeline(); - local_irq_restore(flags); - - seq_printf(tlb, "%2lu: %c %c %02x %05x %05x %o %o %c %c %c %c\n", - *index, - SYSREG_BFEXT(TLBEHI_V, tlbehi) ? '1' : '0', - SYSREG_BFEXT(G, tlbelo) ? '1' : '0', - SYSREG_BFEXT(ASID, tlbehi), - SYSREG_BFEXT(VPN, tlbehi) >> 2, - SYSREG_BFEXT(PFN, tlbelo) >> 2, - SYSREG_BFEXT(AP, tlbelo), - SYSREG_BFEXT(SZ, tlbelo), - SYSREG_BFEXT(TLBELO_C, tlbelo) ? '1' : '0', - SYSREG_BFEXT(B, tlbelo) ? '1' : '0', - SYSREG_BFEXT(W, tlbelo) ? '1' : '0', - SYSREG_BFEXT(TLBELO_D, tlbelo) ? '1' : '0'); - - return 0; -} - -static const struct seq_operations tlb_ops = { - .start = tlb_start, - .next = tlb_next, - .stop = tlb_stop, - .show = tlb_show, -}; - -static int tlb_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &tlb_ops); -} - -static const struct file_operations proc_tlb_operations = { - .open = tlb_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static int __init proctlb_init(void) -{ - proc_create("tlb", 0, NULL, &proc_tlb_operations); - return 0; -} -late_initcall(proctlb_init); -#endif /* CONFIG_PROC_FS */ diff --git a/arch/avr32/oprofile/Makefile b/arch/avr32/oprofile/Makefile deleted file mode 100644 index e0eb520e0287..000000000000 --- a/arch/avr32/oprofile/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -obj-$(CONFIG_OPROFILE) += oprofile.o - -oprofile-y := $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o) -oprofile-y += op_model_avr32.o backtrace.o diff --git a/arch/avr32/oprofile/backtrace.c b/arch/avr32/oprofile/backtrace.c deleted file mode 100644 index 29cf2f191bfd..000000000000 --- a/arch/avr32/oprofile/backtrace.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * AVR32 specific backtracing code for oprofile - * - * Copyright 2008 Weinmann GmbH - * - * Author: Nikolaus Voss <n.voss@weinmann.de> - * - * Based on i386 oprofile backtrace code by John Levon and David Smith - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include <linux/oprofile.h> -#include <linux/ptrace.h> -#include <linux/uaccess.h> - -/* The first two words of each frame on the stack look like this if we have - * frame pointers */ -struct frame_head { - unsigned long lr; - struct frame_head *fp; -}; - -/* copied from arch/avr32/kernel/process.c */ -static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p) -{ - return (p > (unsigned long)tinfo) - && (p < (unsigned long)tinfo + THREAD_SIZE - 3); -} - -/* copied from arch/x86/oprofile/backtrace.c */ -static struct frame_head *dump_user_backtrace(struct frame_head *head) -{ - struct frame_head bufhead[2]; - - /* Also check accessibility of one struct frame_head beyond */ - if (!access_ok(VERIFY_READ, head, sizeof(bufhead))) - return NULL; - if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead))) - return NULL; - - oprofile_add_trace(bufhead[0].lr); - - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (bufhead[0].fp <= head) - return NULL; - - return bufhead[0].fp; -} - -void avr32_backtrace(struct pt_regs * const regs, unsigned int depth) -{ - /* Get first frame pointer */ - struct frame_head *head = (struct frame_head *)(regs->r7); - - if (!user_mode(regs)) { -#ifdef CONFIG_FRAME_POINTER - /* - * Traverse the kernel stack from frame to frame up to - * "depth" steps. - */ - while (depth-- && valid_stack_ptr(task_thread_info(current), - (unsigned long)head)) { - oprofile_add_trace(head->lr); - if (head->fp <= head) - break; - head = head->fp; - } -#endif - } else { - /* Assume we have frame pointers in user mode process */ - while (depth-- && head) - head = dump_user_backtrace(head); - } -} - - diff --git a/arch/avr32/oprofile/op_model_avr32.c b/arch/avr32/oprofile/op_model_avr32.c deleted file mode 100644 index 08308be2c02c..000000000000 --- a/arch/avr32/oprofile/op_model_avr32.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * AVR32 Performance Counter Driver - * - * Copyright (C) 2005-2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Author: Ronny Pedersen - */ -#include <linux/errno.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/oprofile.h> -#include <linux/sched.h> -#include <linux/types.h> - -#include <asm/sysreg.h> - -#define AVR32_PERFCTR_IRQ_GROUP 0 -#define AVR32_PERFCTR_IRQ_LINE 1 - -void avr32_backtrace(struct pt_regs * const regs, unsigned int depth); - -enum { PCCNT, PCNT0, PCNT1, NR_counter }; - -struct avr32_perf_counter { - unsigned long enabled; - unsigned long event; - unsigned long count; - unsigned long unit_mask; - unsigned long kernel; - unsigned long user; - - u32 ie_mask; - u32 flag_mask; -}; - -static struct avr32_perf_counter counter[NR_counter] = { - { - .ie_mask = SYSREG_BIT(IEC), - .flag_mask = SYSREG_BIT(FC), - }, { - .ie_mask = SYSREG_BIT(IE0), - .flag_mask = SYSREG_BIT(F0), - }, { - .ie_mask = SYSREG_BIT(IE1), - .flag_mask = SYSREG_BIT(F1), - }, -}; - -static void avr32_perf_counter_reset(void) -{ - /* Reset all counter and disable/clear all interrupts */ - sysreg_write(PCCR, (SYSREG_BIT(PCCR_R) - | SYSREG_BIT(PCCR_C) - | SYSREG_BIT(FC) - | SYSREG_BIT(F0) - | SYSREG_BIT(F1))); -} - -static irqreturn_t avr32_perf_counter_interrupt(int irq, void *dev_id) -{ - struct avr32_perf_counter *ctr = dev_id; - struct pt_regs *regs; - u32 pccr; - - if (likely(!(intc_get_pending(AVR32_PERFCTR_IRQ_GROUP) - & (1 << AVR32_PERFCTR_IRQ_LINE)))) - return IRQ_NONE; - - regs = get_irq_regs(); - pccr = sysreg_read(PCCR); - - /* Clear the interrupt flags we're about to handle */ - sysreg_write(PCCR, pccr); - - /* PCCNT */ - if (ctr->enabled && (pccr & ctr->flag_mask)) { - sysreg_write(PCCNT, -ctr->count); - oprofile_add_sample(regs, PCCNT); - } - ctr++; - /* PCNT0 */ - if (ctr->enabled && (pccr & ctr->flag_mask)) { - sysreg_write(PCNT0, -ctr->count); - oprofile_add_sample(regs, PCNT0); - } - ctr++; - /* PCNT1 */ - if (ctr->enabled && (pccr & ctr->flag_mask)) { - sysreg_write(PCNT1, -ctr->count); - oprofile_add_sample(regs, PCNT1); - } - - return IRQ_HANDLED; -} - -static int avr32_perf_counter_create_files(struct dentry *root) -{ - struct dentry *dir; - unsigned int i; - char filename[4]; - - for (i = 0; i < NR_counter; i++) { - snprintf(filename, sizeof(filename), "%u", i); - dir = oprofilefs_mkdir(root, filename); - - oprofilefs_create_ulong(dir, "enabled", - &counter[i].enabled); - oprofilefs_create_ulong(dir, "event", - &counter[i].event); - oprofilefs_create_ulong(dir, "count", - &counter[i].count); - - /* Dummy entries */ - oprofilefs_create_ulong(dir, "kernel", - &counter[i].kernel); - oprofilefs_create_ulong(dir, "user", - &counter[i].user); - oprofilefs_create_ulong(dir, "unit_mask", - &counter[i].unit_mask); - } - - return 0; -} - -static int avr32_perf_counter_setup(void) -{ - struct avr32_perf_counter *ctr; - u32 pccr; - int ret; - int i; - - pr_debug("avr32_perf_counter_setup\n"); - - if (sysreg_read(PCCR) & SYSREG_BIT(PCCR_E)) { - printk(KERN_ERR - "oprofile: setup: perf counter already enabled\n"); - return -EBUSY; - } - - ret = request_irq(AVR32_PERFCTR_IRQ_GROUP, - avr32_perf_counter_interrupt, IRQF_SHARED, - "oprofile", counter); - if (ret) - return ret; - - avr32_perf_counter_reset(); - - pccr = 0; - for (i = PCCNT; i < NR_counter; i++) { - ctr = &counter[i]; - if (!ctr->enabled) - continue; - - pr_debug("enabling counter %d...\n", i); - - pccr |= ctr->ie_mask; - - switch (i) { - case PCCNT: - /* PCCNT always counts cycles, so no events */ - sysreg_write(PCCNT, -ctr->count); - break; - case PCNT0: - pccr |= SYSREG_BF(CONF0, ctr->event); - sysreg_write(PCNT0, -ctr->count); - break; - case PCNT1: - pccr |= SYSREG_BF(CONF1, ctr->event); - sysreg_write(PCNT1, -ctr->count); - break; - } - } - - pr_debug("oprofile: writing 0x%x to PCCR...\n", pccr); - - sysreg_write(PCCR, pccr); - - return 0; -} - -static void avr32_perf_counter_shutdown(void) -{ - pr_debug("avr32_perf_counter_shutdown\n"); - - avr32_perf_counter_reset(); - free_irq(AVR32_PERFCTR_IRQ_GROUP, counter); -} - -static int avr32_perf_counter_start(void) -{ - pr_debug("avr32_perf_counter_start\n"); - - sysreg_write(PCCR, sysreg_read(PCCR) | SYSREG_BIT(PCCR_E)); - - return 0; -} - -static void avr32_perf_counter_stop(void) -{ - pr_debug("avr32_perf_counter_stop\n"); - - sysreg_write(PCCR, sysreg_read(PCCR) & ~SYSREG_BIT(PCCR_E)); -} - -static struct oprofile_operations avr32_perf_counter_ops __initdata = { - .create_files = avr32_perf_counter_create_files, - .setup = avr32_perf_counter_setup, - .shutdown = avr32_perf_counter_shutdown, - .start = avr32_perf_counter_start, - .stop = avr32_perf_counter_stop, - .cpu_type = "avr32", -}; - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - if (!(current_cpu_data.features & AVR32_FEATURE_PCTR)) - return -ENODEV; - - memcpy(ops, &avr32_perf_counter_ops, - sizeof(struct oprofile_operations)); - - ops->backtrace = avr32_backtrace; - - printk(KERN_INFO "oprofile: using AVR32 performance monitoring.\n"); - - return 0; -} - -void oprofile_arch_exit(void) -{ - -} diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild index 625db8ac815e..dc4ef9ac1e83 100644 --- a/arch/blackfin/include/asm/Kbuild +++ b/arch/blackfin/include/asm/Kbuild @@ -7,6 +7,7 @@ generic-y += device.h generic-y += div64.h generic-y += emergency-restart.h generic-y += errno.h +generic-y += extable.h generic-y += fb.h generic-y += futex.h generic-y += hw_irq.h diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h index 0eff88aa6d6a..f54a34f31cea 100644 --- a/arch/blackfin/include/asm/uaccess.h +++ b/arch/blackfin/include/asm/uaccess.h @@ -12,7 +12,6 @@ /* * User space memory access functions */ -#include <linux/sched.h> #include <linux/mm.h> #include <linux/string.h> @@ -29,9 +28,6 @@ static inline void set_fs(mm_segment_t fs) #define segment_eq(a, b) ((a) == (b)) -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - #define access_ok(type, addr, size) _access_ok((unsigned long)(addr), (size)) /* @@ -46,22 +42,7 @@ static inline int _access_ok(unsigned long addr, unsigned long size) { return 1; extern int _access_ok(unsigned long addr, unsigned long size); #endif -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry { - unsigned long insn, fixup; -}; +#include <asm/extable.h> /* * These are the main single-value transfer routines. They automatically @@ -163,41 +144,23 @@ static inline int bad_user_access_length(void) : "a" (__ptr(ptr))); \ }) -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - static inline unsigned long __must_check -__copy_from_user(void *to, const void __user *from, unsigned long n) +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { memcpy(to, (const void __force *)from, n); return 0; } static inline unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n) +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { memcpy((void __force *)to, from, n); SSYNC(); return 0; } -static inline unsigned long __must_check -copy_from_user(void *to, const void __user *from, unsigned long n) -{ - if (likely(access_ok(VERIFY_READ, from, n))) - return __copy_from_user(to, from, n); - memset(to, 0, n); - return n; -} - -static inline unsigned long __must_check -copy_to_user(void __user *to, const void *from, unsigned long n) -{ - if (likely(access_ok(VERIFY_WRITE, to, n))) - return __copy_to_user(to, from, n); - return n; -} - +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER /* * Copy a null terminated string from userspace. */ diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 89d5162d4ca6..89814850b08b 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -370,7 +370,7 @@ int _access_ok(unsigned long addr, unsigned long size) /* Check that things do not wrap around */ if (addr > ULONG_MAX - size) return 0; - if (segment_eq(get_fs(), KERNEL_DS)) + if (uaccess_kernel()) return 1; #ifdef CONFIG_MTD_UCLINUX if (1) diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 0e9fcf841d67..01350557fbd7 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -230,7 +230,9 @@ static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt) clock_tick = get_sclk(); evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift); evt->max_delta_ns = clockevent_delta2ns(-1, evt); + evt->max_delta_ticks = (unsigned long)-1; evt->min_delta_ns = clockevent_delta2ns(100, evt); + evt->min_delta_ticks = 100; evt->cpumask = cpumask_of(0); @@ -344,7 +346,9 @@ void bfin_coretmr_clockevent_init(void) clock_tick = get_cclk() / TIME_SCALE; evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift); evt->max_delta_ns = clockevent_delta2ns(-1, evt); + evt->max_delta_ticks = (unsigned long)-1; evt->min_delta_ns = clockevent_delta2ns(100, evt); + evt->min_delta_ticks = 100; evt->cpumask = cpumask_of(cpu); diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 68069a120055..334ef8139b35 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -115,6 +115,8 @@ SECTIONS __data_lma = LOADADDR(.data); __data_len = SIZEOF(.data); + BUG_TABLE + /* The init section should be last, so when we free it, it goes into * the general memory pool, and (hopefully) will decrease fragmentation * a tiny bit. The init section has a _requirement_ that it be diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild index 82619c32d25b..f0eaf0475e7e 100644 --- a/arch/c6x/include/asm/Kbuild +++ b/arch/c6x/include/asm/Kbuild @@ -12,6 +12,7 @@ generic-y += dma.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += fb.h generic-y += fcntl.h generic-y += futex.h diff --git a/arch/c6x/include/asm/uaccess.h b/arch/c6x/include/asm/uaccess.h index 453dd263bee3..ba6756879f00 100644 --- a/arch/c6x/include/asm/uaccess.h +++ b/arch/c6x/include/asm/uaccess.h @@ -13,17 +13,11 @@ #include <linux/compiler.h> #include <linux/string.h> -#ifdef CONFIG_ACCESS_CHECK -#define __access_ok _access_ok -#endif - /* - * __copy_from_user/copy_to_user are based on ones in asm-generic/uaccess.h - * * C6X supports unaligned 32 and 64 bit loads and stores. */ -static inline __must_check long __copy_from_user(void *to, - const void __user *from, unsigned long n) +static inline __must_check unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { u32 tmp32; u64 tmp64; @@ -58,8 +52,8 @@ static inline __must_check long __copy_from_user(void *to, return 0; } -static inline __must_check long __copy_to_user(void __user *to, - const void *from, unsigned long n) +static inline __must_check unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { u32 tmp32; u64 tmp64; @@ -93,9 +87,8 @@ static inline __must_check long __copy_to_user(void __user *to, memcpy((void __force *)to, from, n); return 0; } - -#define __copy_to_user __copy_to_user -#define __copy_from_user __copy_from_user +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER extern int _access_ok(unsigned long addr, unsigned long size); #ifdef CONFIG_ACCESS_CHECK diff --git a/arch/c6x/kernel/sys_c6x.c b/arch/c6x/kernel/sys_c6x.c index 3e9bdfbee8ad..a742ae259239 100644 --- a/arch/c6x/kernel/sys_c6x.c +++ b/arch/c6x/kernel/sys_c6x.c @@ -23,7 +23,7 @@ int _access_ok(unsigned long addr, unsigned long size) if (!addr || addr > (0xffffffffUL - (size - 1))) goto _bad_access; - if (segment_eq(get_fs(), KERNEL_DS)) + if (uaccess_kernel()) return 1; if (memory_start <= addr && (addr + size - 1) < memory_end) diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S index a1a5c166bc9b..29ebea49ddd5 100644 --- a/arch/c6x/kernel/vmlinux.lds.S +++ b/arch/c6x/kernel/vmlinux.lds.S @@ -128,6 +128,8 @@ SECTIONS . = ALIGN(8); } + BUG_TABLE + _edata = .; __bss_start = .; diff --git a/arch/c6x/platforms/timer64.c b/arch/c6x/platforms/timer64.c index c19901e5f055..0bd0452ded80 100644 --- a/arch/c6x/platforms/timer64.c +++ b/arch/c6x/platforms/timer64.c @@ -234,7 +234,9 @@ void __init timer64_init(void) clockevents_calc_mult_shift(cd, c6x_core_freq / TIMER_DIVISOR, 5); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->max_delta_ticks = 0x7fffffff; cd->min_delta_ns = clockevent_delta2ns(250, cd); + cd->min_delta_ticks = 250; cd->cpumask = cpumask_of(smp_processor_id()); diff --git a/arch/cris/arch-v10/lib/usercopy.c b/arch/cris/arch-v10/lib/usercopy.c index 1ba7cc000dfc..48fa37fe0f9b 100644 --- a/arch/cris/arch-v10/lib/usercopy.c +++ b/arch/cris/arch-v10/lib/usercopy.c @@ -188,11 +188,10 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, unsigned long pn) } EXPORT_SYMBOL(__copy_user); -/* Copy from user to kernel, zeroing the bytes that were inaccessible in - userland. The return-value is the number of bytes that were +/* Copy from user to kernel. The return-value is the number of bytes that were inaccessible. */ -unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, +unsigned long __copy_user_in(void *pdst, const void __user *psrc, unsigned long pn) { /* We want the parameters put in special registers. @@ -217,19 +216,17 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, { __asm_copy_from_user_1 (dst, src, retn); n--; + if (retn) + goto exception; } if (((unsigned long) src & 2) && n >= 2) { __asm_copy_from_user_2 (dst, src, retn); n -= 2; + if (retn) + goto exception; } - - /* We only need one check after the unalignment-adjustments, because - if both adjustments were done, either both or neither reference - had an exception. */ - if (retn != 0) - goto copy_exception_bytes; } /* Decide which copying method to use. */ @@ -328,7 +325,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, n -= 4; if (retn) - goto copy_exception_bytes; + goto exception; } /* If we get here, there were no memory read faults. */ @@ -356,20 +353,10 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, bytes. */ return retn; -copy_exception_bytes: - /* We already have "retn" bytes cleared, and need to clear the - remaining "n" bytes. A non-optimized simple byte-for-byte in-line - memset is preferred here, since this isn't speed-critical code and - we'd rather have this a leaf-function than calling memset. */ - { - char *endp; - for (endp = dst + n; dst < endp; dst++) - *dst = 0; - } - +exception: return retn + n; } -EXPORT_SYMBOL(__copy_user_zeroing); +EXPORT_SYMBOL(__copy_user_in); /* Zero userspace. */ unsigned long __do_clear_user(void __user *pto, unsigned long pn) diff --git a/arch/cris/arch-v32/lib/usercopy.c b/arch/cris/arch-v32/lib/usercopy.c index 05e58dab800d..20b608026913 100644 --- a/arch/cris/arch-v32/lib/usercopy.c +++ b/arch/cris/arch-v32/lib/usercopy.c @@ -156,10 +156,9 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, unsigned long pn) } EXPORT_SYMBOL(__copy_user); -/* Copy from user to kernel, zeroing the bytes that were inaccessible in - userland. The return-value is the number of bytes that were +/* Copy from user to kernel. The return-value is the number of bytes that were inaccessible. */ -unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, +unsigned long __copy_user_in(void *pdst, const void __user *psrc, unsigned long pn) { /* We want the parameters put in special registers. @@ -184,19 +183,18 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, { __asm_copy_from_user_1 (dst, src, retn); n--; + if (retn != 0) + goto exception; } if (((unsigned long) src & 2) && n >= 2) { __asm_copy_from_user_2 (dst, src, retn); n -= 2; + if (retn != 0) + goto exception; } - /* We only need one check after the unalignment-adjustments, because - if both adjustments were done, either both or neither reference - had an exception. */ - if (retn != 0) - goto copy_exception_bytes; } /* Movem is dirt cheap. The overheap is low enough to always use the @@ -279,7 +277,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, n -= 4; if (retn) - goto copy_exception_bytes; + goto exception; } /* If we get here, there were no memory read faults. */ @@ -307,20 +305,10 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, bytes. */ return retn; -copy_exception_bytes: - /* We already have "retn" bytes cleared, and need to clear the - remaining "n" bytes. A non-optimized simple byte-for-byte in-line - memset is preferred here, since this isn't speed-critical code and - we'd rather have this a leaf-function than calling memset. */ - { - char *endp; - for (endp = dst + n; dst < endp; dst++) - *dst = 0; - } - +exception: return retn + n; } -EXPORT_SYMBOL(__copy_user_zeroing); +EXPORT_SYMBOL(__copy_user_in); /* Zero userspace. */ unsigned long __do_clear_user(void __user *pto, unsigned long pn) diff --git a/arch/cris/include/arch-v10/arch/uaccess.h b/arch/cris/include/arch-v10/arch/uaccess.h index 65b02d9b605a..5477c98c2281 100644 --- a/arch/cris/include/arch-v10/arch/uaccess.h +++ b/arch/cris/include/arch-v10/arch/uaccess.h @@ -172,16 +172,14 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_user_cont(to, from, ret, \ " move.b [%1+],$r9\n" \ "2: move.b $r9,[%0+]\n", \ - "3: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "3: addq 1,%2\n", \ " .dword 2b,3b\n") #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ __asm_copy_user_cont(to, from, ret, \ " move.w [%1+],$r9\n" \ "2: move.w $r9,[%0+]\n" COPY, \ - "3: addq 2,%2\n" \ - " clear.w [%0+]\n" FIXUP, \ + "3: addq 2,%2\n" FIXUP, \ " .dword 2b,3b\n" TENTRY) #define __asm_copy_from_user_2(to, from, ret) \ @@ -191,16 +189,14 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_2x_cont(to, from, ret, \ " move.b [%1+],$r9\n" \ "4: move.b $r9,[%0+]\n", \ - "5: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "5: addq 1,%2\n", \ " .dword 4b,5b\n") #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ __asm_copy_user_cont(to, from, ret, \ " move.d [%1+],$r9\n" \ "2: move.d $r9,[%0+]\n" COPY, \ - "3: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ + "3: addq 4,%2\n" FIXUP, \ " .dword 2b,3b\n" TENTRY) #define __asm_copy_from_user_4(to, from, ret) \ @@ -210,8 +206,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_4x_cont(to, from, ret, \ " move.b [%1+],$r9\n" \ "4: move.b $r9,[%0+]\n", \ - "5: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "5: addq 1,%2\n", \ " .dword 4b,5b\n") #define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -219,7 +214,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) " move.w [%1+],$r9\n" \ "4: move.w $r9,[%0+]\n" COPY, \ "5: addq 2,%2\n" \ - " clear.w [%0+]\n" FIXUP, \ + FIXUP, \ " .dword 4b,5b\n" TENTRY) #define __asm_copy_from_user_6(to, from, ret) \ @@ -229,8 +224,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_6x_cont(to, from, ret, \ " move.b [%1+],$r9\n" \ "6: move.b $r9,[%0+]\n", \ - "7: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "7: addq 1,%2\n", \ " .dword 6b,7b\n") #define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -238,7 +232,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) " move.d [%1+],$r9\n" \ "4: move.d $r9,[%0+]\n" COPY, \ "5: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ + FIXUP, \ " .dword 4b,5b\n" TENTRY) #define __asm_copy_from_user_8(to, from, ret) \ @@ -248,8 +242,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_8x_cont(to, from, ret, \ " move.b [%1+],$r9\n" \ "6: move.b $r9,[%0+]\n", \ - "7: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "7: addq 1,%2\n", \ " .dword 6b,7b\n") #define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -257,7 +250,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) " move.w [%1+],$r9\n" \ "6: move.w $r9,[%0+]\n" COPY, \ "7: addq 2,%2\n" \ - " clear.w [%0+]\n" FIXUP, \ + FIXUP, \ " .dword 6b,7b\n" TENTRY) #define __asm_copy_from_user_10(to, from, ret) \ @@ -267,8 +260,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_10x_cont(to, from, ret, \ " move.b [%1+],$r9\n" \ "8: move.b $r9,[%0+]\n", \ - "9: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "9: addq 1,%2\n", \ " .dword 8b,9b\n") #define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -276,7 +268,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) " move.d [%1+],$r9\n" \ "6: move.d $r9,[%0+]\n" COPY, \ "7: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ + FIXUP, \ " .dword 6b,7b\n" TENTRY) #define __asm_copy_from_user_12(to, from, ret) \ @@ -286,8 +278,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_12x_cont(to, from, ret, \ " move.b [%1+],$r9\n" \ "8: move.b $r9,[%0+]\n", \ - "9: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "9: addq 1,%2\n", \ " .dword 8b,9b\n") #define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -295,7 +286,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) " move.w [%1+],$r9\n" \ "8: move.w $r9,[%0+]\n" COPY, \ "9: addq 2,%2\n" \ - " clear.w [%0+]\n" FIXUP, \ + FIXUP, \ " .dword 8b,9b\n" TENTRY) #define __asm_copy_from_user_14(to, from, ret) \ @@ -305,8 +296,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_14x_cont(to, from, ret, \ " move.b [%1+],$r9\n" \ "10: move.b $r9,[%0+]\n", \ - "11: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "11: addq 1,%2\n", \ " .dword 10b,11b\n") #define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -314,7 +304,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) " move.d [%1+],$r9\n" \ "8: move.d $r9,[%0+]\n" COPY, \ "9: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ + FIXUP, \ " .dword 8b,9b\n" TENTRY) #define __asm_copy_from_user_16(to, from, ret) \ @@ -325,7 +315,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) " move.d [%1+],$r9\n" \ "10: move.d $r9,[%0+]\n" COPY, \ "11: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ + FIXUP, \ " .dword 10b,11b\n" TENTRY) #define __asm_copy_from_user_20(to, from, ret) \ @@ -336,7 +326,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) " move.d [%1+],$r9\n" \ "12: move.d $r9,[%0+]\n" COPY, \ "13: addq 4,%2\n" \ - " clear.d [%0+]\n" FIXUP, \ + FIXUP, \ " .dword 12b,13b\n" TENTRY) #define __asm_copy_from_user_24(to, from, ret) \ diff --git a/arch/cris/include/arch-v32/arch/uaccess.h b/arch/cris/include/arch-v32/arch/uaccess.h index 3196019706cb..dc2ce090f624 100644 --- a/arch/cris/include/arch-v32/arch/uaccess.h +++ b/arch/cris/include/arch-v32/arch/uaccess.h @@ -178,8 +178,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) "2: move.b [%1+],$acr\n" \ " move.b $acr,[%0+]\n", \ "3: addq 1,%2\n" \ - " jump 1b\n" \ - " clear.b [%0+]\n", \ + " jump 1b\n", \ " .dword 2b,3b\n") #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -189,8 +188,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) " move.w $acr,[%0+]\n", \ FIXUP \ "3: addq 2,%2\n" \ - " jump 1b\n" \ - " clear.w [%0+]\n", \ + " jump 1b\n", \ TENTRY \ " .dword 2b,3b\n") @@ -201,8 +199,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_2x_cont(to, from, ret, \ "4: move.b [%1+],$acr\n" \ " move.b $acr,[%0+]\n", \ - "5: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "5: addq 1,%2\n", \ " .dword 4b,5b\n") #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -212,8 +209,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) " move.d $acr,[%0+]\n", \ FIXUP \ "3: addq 4,%2\n" \ - " jump 1b\n" \ - " clear.d [%0+]\n", \ + " jump 1b\n", \ TENTRY \ " .dword 2b,3b\n") @@ -224,8 +220,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_4x_cont(to, from, ret, \ "4: move.b [%1+],$acr\n" \ " move.b $acr,[%0+]\n", \ - "5: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "5: addq 1,%2\n", \ " .dword 4b,5b\n") #define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -234,8 +229,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) "4: move.w [%1+],$acr\n" \ " move.w $acr,[%0+]\n", \ FIXUP \ - "5: addq 2,%2\n" \ - " clear.w [%0+]\n", \ + "5: addq 2,%2\n", \ TENTRY \ " .dword 4b,5b\n") @@ -246,8 +240,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_6x_cont(to, from, ret, \ "6: move.b [%1+],$acr\n" \ " move.b $acr,[%0+]\n", \ - "7: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "7: addq 1,%2\n", \ " .dword 6b,7b\n") #define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -256,8 +249,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) "4: move.d [%1+],$acr\n" \ " move.d $acr,[%0+]\n", \ FIXUP \ - "5: addq 4,%2\n" \ - " clear.d [%0+]\n", \ + "5: addq 4,%2\n", \ TENTRY \ " .dword 4b,5b\n") @@ -268,8 +260,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_8x_cont(to, from, ret, \ "6: move.b [%1+],$acr\n" \ " move.b $acr,[%0+]\n", \ - "7: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "7: addq 1,%2\n", \ " .dword 6b,7b\n") #define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -278,8 +269,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) "6: move.w [%1+],$acr\n" \ " move.w $acr,[%0+]\n", \ FIXUP \ - "7: addq 2,%2\n" \ - " clear.w [%0+]\n", \ + "7: addq 2,%2\n", \ TENTRY \ " .dword 6b,7b\n") @@ -290,8 +280,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_10x_cont(to, from, ret, \ "8: move.b [%1+],$acr\n" \ " move.b $acr,[%0+]\n", \ - "9: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "9: addq 1,%2\n", \ " .dword 8b,9b\n") #define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -300,8 +289,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) "6: move.d [%1+],$acr\n" \ " move.d $acr,[%0+]\n", \ FIXUP \ - "7: addq 4,%2\n" \ - " clear.d [%0+]\n", \ + "7: addq 4,%2\n", \ TENTRY \ " .dword 6b,7b\n") @@ -312,8 +300,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_12x_cont(to, from, ret, \ "8: move.b [%1+],$acr\n" \ " move.b $acr,[%0+]\n", \ - "9: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "9: addq 1,%2\n", \ " .dword 8b,9b\n") #define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -322,8 +309,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) "8: move.w [%1+],$acr\n" \ " move.w $acr,[%0+]\n", \ FIXUP \ - "9: addq 2,%2\n" \ - " clear.w [%0+]\n", \ + "9: addq 2,%2\n", \ TENTRY \ " .dword 8b,9b\n") @@ -334,8 +320,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) __asm_copy_from_user_14x_cont(to, from, ret, \ "10: move.b [%1+],$acr\n" \ " move.b $acr,[%0+]\n", \ - "11: addq 1,%2\n" \ - " clear.b [%0+]\n", \ + "11: addq 1,%2\n", \ " .dword 10b,11b\n") #define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ @@ -344,8 +329,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) "8: move.d [%1+],$acr\n" \ " move.d $acr,[%0+]\n", \ FIXUP \ - "9: addq 4,%2\n" \ - " clear.d [%0+]\n", \ + "9: addq 4,%2\n", \ TENTRY \ " .dword 8b,9b\n") @@ -358,8 +342,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) "10: move.d [%1+],$acr\n" \ " move.d $acr,[%0+]\n", \ FIXUP \ - "11: addq 4,%2\n" \ - " clear.d [%0+]\n", \ + "11: addq 4,%2\n", \ TENTRY \ " .dword 10b,11b\n") @@ -372,8 +355,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count) "12: move.d [%1+],$acr\n" \ " move.d $acr,[%0+]\n", \ FIXUP \ - "13: addq 4,%2\n" \ - " clear.d [%0+]\n", \ + "13: addq 4,%2\n", \ TENTRY \ " .dword 12b,13b\n") diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index 0f5132b08896..2890099992a9 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -9,6 +9,7 @@ generic-y += device.h generic-y += div64.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += emergency-restart.h generic-y += fcntl.h generic-y += futex.h diff --git a/arch/cris/include/asm/uaccess.h b/arch/cris/include/asm/uaccess.h index 56c7d5750abd..0d473aec3066 100644 --- a/arch/cris/include/asm/uaccess.h +++ b/arch/cris/include/asm/uaccess.h @@ -15,15 +15,9 @@ #ifndef _CRIS_UACCESS_H #define _CRIS_UACCESS_H -#ifndef __ASSEMBLY__ -#include <linux/sched.h> -#include <linux/errno.h> #include <asm/processor.h> #include <asm/page.h> -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - /* * The fs value determines whether argument validity checking should be * performed or not. If get_fs() == USER_DS, checking is performed, with @@ -49,30 +43,14 @@ #define segment_eq(a, b) ((a).seg == (b).seg) -#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) +#define __kernel_ok (uaccess_kernel()) #define __user_ok(addr, size) \ (((size) <= TASK_SIZE) && ((addr) <= TASK_SIZE-(size))) #define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size))) #define access_ok(type, addr, size) __access_ok((unsigned long)(addr), (size)) #include <arch/uaccess.h> - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry { - unsigned long insn, fixup; -}; +#include <asm/extable.h> /* * These are the main single-value transfer routines. They automatically @@ -191,7 +169,7 @@ extern long __get_user_bad(void); live in lib/usercopy.c */ extern unsigned long __copy_user(void __user *to, const void *from, unsigned long n); -extern unsigned long __copy_user_zeroing(void *to, const void __user *from, unsigned long n); +extern unsigned long __copy_user_in(void *to, const void __user *from, unsigned long n); extern unsigned long __do_clear_user(void __user *to, unsigned long n); static inline long @@ -258,7 +236,7 @@ __constant_copy_from_user(void *to, const void __user *from, unsigned long n) else if (n == 24) __asm_copy_from_user_24(to, from, ret); else - ret = __copy_user_zeroing(to, from, n); + ret = __copy_user_in(to, from, n); return ret; } @@ -358,64 +336,33 @@ static inline size_t clear_user(void __user *to, size_t n) return __do_clear_user(to, n); } -static inline size_t copy_from_user(void *to, const void __user *from, size_t n) +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - if (unlikely(!access_ok(VERIFY_READ, from, n))) { - memset(to, 0, n); - return n; - } if (__builtin_constant_p(n)) return __constant_copy_from_user(to, from, n); else - return __copy_user_zeroing(to, from, n); + return __copy_user_in(to, from, n); } -static inline size_t copy_to_user(void __user *to, const void *from, size_t n) +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - if (unlikely(!access_ok(VERIFY_WRITE, to, n))) - return n; if (__builtin_constant_p(n)) return __constant_copy_to_user(to, from, n); else return __copy_user(to, from, n); } -/* We let the __ versions of copy_from/to_user inline, because they're often - * used in fast paths and have only a small space overhead. - */ +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER static inline unsigned long -__generic_copy_from_user_nocheck(void *to, const void __user *from, - unsigned long n) -{ - return __copy_user_zeroing(to, from, n); -} - -static inline unsigned long -__generic_copy_to_user_nocheck(void __user *to, const void *from, - unsigned long n) -{ - return __copy_user(to, from, n); -} - -static inline unsigned long -__generic_clear_user_nocheck(void __user *to, unsigned long n) +__clear_user(void __user *to, unsigned long n) { return __do_clear_user(to, n); } -/* without checking */ - -#define __copy_to_user(to, from, n) \ - __generic_copy_to_user_nocheck((to), (from), (n)) -#define __copy_from_user(to, from, n) \ - __generic_copy_from_user_nocheck((to), (from), (n)) -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user -#define __clear_user(to, n) __generic_clear_user_nocheck((to), (n)) - #define strlen_user(str) strnlen_user((str), 0x7ffffffe) -#endif /* __ASSEMBLY__ */ - #endif /* _CRIS_UACCESS_H */ diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S index 979586261520..867f237d7c5c 100644 --- a/arch/cris/kernel/vmlinux.lds.S +++ b/arch/cris/kernel/vmlinux.lds.S @@ -68,6 +68,8 @@ SECTIONS __edata = . ; /* End of data section. */ _edata = . ; + BUG_TABLE + INIT_TASK_DATA_SECTION(PAGE_SIZE) . = ALIGN(PAGE_SIZE); /* Init code and data. */ diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild index c33b46715f65..cce3bc3603ea 100644 --- a/arch/frv/include/asm/Kbuild +++ b/arch/frv/include/asm/Kbuild @@ -1,6 +1,7 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += extable.h generic-y += irq_work.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/frv/include/asm/uaccess.h b/arch/frv/include/asm/uaccess.h index c0f4057eab60..e4e33b4cd3ae 100644 --- a/arch/frv/include/asm/uaccess.h +++ b/arch/frv/include/asm/uaccess.h @@ -15,16 +15,13 @@ /* * User space memory access functions */ -#include <linux/sched.h> #include <linux/mm.h> #include <asm/segment.h> #include <asm/sections.h> +#include <asm/extable.h> #define __ptr(x) ((unsigned long __force *)(x)) -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - /* * check that a range of addresses falls within the current address limit */ @@ -63,26 +60,6 @@ static inline int ___range_ok(unsigned long addr, unsigned long size) #define access_ok(type,addr,size) (__range_ok((void __user *)(addr), (size)) == 0) #define __access_ok(addr,size) (__range_ok((addr), (size)) == 0) -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -/* Returns 0 if exception not found and fixup otherwise. */ -extern unsigned long search_exception_table(unsigned long); - /* * These are the main single-value transfer routines. They automatically @@ -256,61 +233,50 @@ do { \ /* * */ + #define ____force(x) (__force void *)(void __user *)(x) #ifdef CONFIG_MMU extern long __memset_user(void *dst, unsigned long count); extern long __memcpy_user(void *dst, const void *src, unsigned long count); #define __clear_user(dst,count) __memset_user(____force(dst), (count)) -#define __copy_from_user_inatomic(to, from, n) __memcpy_user((to), ____force(from), (n)) -#define __copy_to_user_inatomic(to, from, n) __memcpy_user(____force(to), (from), (n)) #else #define __clear_user(dst,count) (memset(____force(dst), 0, (count)), 0) -#define __copy_from_user_inatomic(to, from, n) (memcpy((to), ____force(from), (n)), 0) -#define __copy_to_user_inatomic(to, from, n) (memcpy(____force(to), (from), (n)), 0) #endif -static inline unsigned long __must_check -clear_user(void __user *to, unsigned long n) -{ - if (likely(__access_ok(to, n))) - n = __clear_user(to, n); - return n; -} - -static inline unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n) -{ - might_fault(); - return __copy_to_user_inatomic(to, from, n); -} - static inline unsigned long -__copy_from_user(void *to, const void __user *from, unsigned long n) +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - might_fault(); - return __copy_from_user_inatomic(to, from, n); +#ifdef CONFIG_MMU + return __memcpy_user(to, (__force const void *)from, n); +#else + memcpy(to, (__force const void *)from, n); + return 0; +#endif } -static inline long copy_from_user(void *to, const void __user *from, unsigned long n) +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - unsigned long ret = n; - - if (likely(__access_ok(from, n))) - ret = __copy_from_user(to, from, n); - - if (unlikely(ret != 0)) - memset(to + (n - ret), 0, ret); - - return ret; +#ifdef CONFIG_MMU + return __memcpy_user((__force void *)to, from, n); +#else + memcpy((__force void *)to, from, n); + return 0; +#endif } +#define INLINE_COPY_TO_USER +#define INLINE_COPY_FROM_USER -static inline long copy_to_user(void __user *to, const void *from, unsigned long n) +static inline unsigned long __must_check +clear_user(void __user *to, unsigned long n) { - return likely(__access_ok(to, n)) ? __copy_to_user(to, from, n) : n; + if (likely(__access_ok(to, n))) + n = __clear_user(to, n); + return n; } extern long strncpy_from_user(char *dst, const char __user *src, long count); @@ -318,6 +284,4 @@ extern long strnlen_user(const char __user *src, long count); #define strlen_user(str) strnlen_user(str, 32767) -extern unsigned long search_exception_table(unsigned long addr); - #endif /* _ASM_UACCESS_H */ diff --git a/arch/frv/kernel/traps.c b/arch/frv/kernel/traps.c index ce29991e4219..fb08ebe0dab4 100644 --- a/arch/frv/kernel/traps.c +++ b/arch/frv/kernel/traps.c @@ -360,13 +360,8 @@ asmlinkage void memory_access_exception(unsigned long esr0, siginfo_t info; #ifdef CONFIG_MMU - unsigned long fixup; - - fixup = search_exception_table(__frame->pc); - if (fixup) { - __frame->pc = fixup; + if (fixup_exception(__frame)) return; - } #endif die_if_kernel("-- Memory Access Exception --\n" diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S index aa6e573d57da..3f44dcbbad4d 100644 --- a/arch/frv/kernel/vmlinux.lds.S +++ b/arch/frv/kernel/vmlinux.lds.S @@ -102,6 +102,8 @@ SECTIONS _edata = .; /* End of data section */ + BUG_TABLE + /* GP section */ . = ALIGN(L1_CACHE_BYTES); _gp = . + 2048; diff --git a/arch/frv/mm/extable.c b/arch/frv/mm/extable.c index a0e8b3e03e4c..9198ddd16092 100644 --- a/arch/frv/mm/extable.c +++ b/arch/frv/mm/extable.c @@ -10,40 +10,39 @@ extern const void __memset_end, __memset_user_error_lr, __memset_user_error_hand extern const void __memcpy_end, __memcpy_user_error_lr, __memcpy_user_error_handler; extern spinlock_t modlist_lock; - -/*****************************************************************************/ -/* - * see if there's a fixup handler available to deal with a kernel fault - */ -unsigned long search_exception_table(unsigned long pc) +int fixup_exception(struct pt_regs *regs) { const struct exception_table_entry *extab; + unsigned long pc = regs->pc; /* determine if the fault lay during a memcpy_user or a memset_user */ - if (__frame->lr == (unsigned long) &__memset_user_error_lr && + if (regs->lr == (unsigned long) &__memset_user_error_lr && (unsigned long) &memset <= pc && pc < (unsigned long) &__memset_end ) { /* the fault occurred in a protected memset * - we search for the return address (in LR) instead of the program counter * - it was probably during a clear_user() */ - return (unsigned long) &__memset_user_error_handler; + regs->pc = (unsigned long) &__memset_user_error_handler; + return 1; } - if (__frame->lr == (unsigned long) &__memcpy_user_error_lr && + if (regs->lr == (unsigned long) &__memcpy_user_error_lr && (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end ) { /* the fault occurred in a protected memset * - we search for the return address (in LR) instead of the program counter * - it was probably during a copy_to/from_user() */ - return (unsigned long) &__memcpy_user_error_handler; + regs->pc = (unsigned long) &__memcpy_user_error_handler; + return 1; } extab = search_exception_tables(pc); - if (extab) - return extab->fixup; + if (extab) { + regs->pc = extab->fixup; + return 1; + } return 0; - -} /* end search_exception_table() */ +} diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c index 614a46c413d2..179e79e220e5 100644 --- a/arch/frv/mm/fault.c +++ b/arch/frv/mm/fault.c @@ -33,7 +33,7 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear { struct vm_area_struct *vma; struct mm_struct *mm; - unsigned long _pme, lrai, lrad, fixup; + unsigned long _pme, lrai, lrad; unsigned long flags = 0; siginfo_t info; pgd_t *pge; @@ -201,10 +201,8 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear no_context: /* are we prepared to handle this kernel fault? */ - if ((fixup = search_exception_table(__frame->pc)) != 0) { - __frame->pc = fixup; + if (fixup_exception(__frame)) return; - } /* * Oops. The kernel tried to access some bad page. We'll have to diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild index 341740c3581c..757cdeb24e6e 100644 --- a/arch/h8300/include/asm/Kbuild +++ b/arch/h8300/include/asm/Kbuild @@ -13,6 +13,7 @@ generic-y += dma.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += fb.h generic-y += fcntl.h generic-y += ftrace.h @@ -68,7 +69,6 @@ generic-y += tlbflush.h generic-y += trace_clock.h generic-y += topology.h generic-y += types.h -generic-y += uaccess.h generic-y += ucontext.h generic-y += unaligned.h generic-y += vga.h diff --git a/arch/h8300/include/asm/uaccess.h b/arch/h8300/include/asm/uaccess.h new file mode 100644 index 000000000000..6f6144a240ce --- /dev/null +++ b/arch/h8300/include/asm/uaccess.h @@ -0,0 +1,54 @@ +#ifndef _ASM_UACCESS_H +#define _ASM_UACCESS_H + +#include <linux/string.h> + +static inline __must_check unsigned long +raw_copy_from_user(void *to, const void __user * from, unsigned long n) +{ + if (__builtin_constant_p(n)) { + switch(n) { + case 1: + *(u8 *)to = *(u8 __force *)from; + return 0; + case 2: + *(u16 *)to = *(u16 __force *)from; + return 0; + case 4: + *(u32 *)to = *(u32 __force *)from; + return 0; + } + } + + memcpy(to, (const void __force *)from, n); + return 0; +} + +static inline __must_check unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + if (__builtin_constant_p(n)) { + switch(n) { + case 1: + *(u8 __force *)to = *(u8 *)from; + return 0; + case 2: + *(u16 __force *)to = *(u16 *)from; + return 0; + case 4: + *(u32 __force *)to = *(u32 *)from; + return 0; + default: + break; + } + } + + memcpy((void __force *)to, from, n); + return 0; +} +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER + +#include <asm-generic/uaccess.h> + +#endif diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 797b64a4b80b..a2036bfda8af 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild @@ -11,6 +11,7 @@ generic-y += device.h generic-y += div64.h generic-y += emergency-restart.h generic-y += errno.h +generic-y += extable.h generic-y += fb.h generic-y += fcntl.h generic-y += ftrace.h diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h index f61cfb28e9f2..458b69886b34 100644 --- a/arch/hexagon/include/asm/uaccess.h +++ b/arch/hexagon/include/asm/uaccess.h @@ -23,7 +23,6 @@ /* * User space memory access functions */ -#include <linux/sched.h> #include <linux/mm.h> #include <asm/segment.h> #include <asm/sections.h> @@ -50,8 +49,6 @@ * reasonably simple and not *too* slow. After all, we've got the * MMU for backup. */ -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 #define __access_ok(addr, size) \ ((get_fs().seg == KERNEL_DS.seg) || \ @@ -68,19 +65,12 @@ */ /* Assembly somewhat optimized copy routines */ -unsigned long __copy_from_user_hexagon(void *to, const void __user *from, +unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n); -unsigned long __copy_to_user_hexagon(void __user *to, const void *from, +unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n); - -#define __copy_from_user(to, from, n) __copy_from_user_hexagon(to, from, n) -#define __copy_to_user(to, from, n) __copy_to_user_hexagon(to, from, n) - -/* - * XXX todo: some additonal performance gain is possible by - * implementing __copy_to/from_user_inatomic, which is much - * like __copy_to/from_user, but performs slightly less checking. - */ +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER __kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count); #define __clear_user(a, s) __clear_user_hexagon((a), (s)) @@ -107,10 +97,14 @@ static inline long hexagon_strncpy_from_user(char *dst, const char __user *src, return -EFAULT; if (res > n) { - copy_from_user(dst, src, n); + long left = raw_copy_from_user(dst, src, n); + if (unlikely(left)) + memset(dst + (n - left), 0, left); return n; } else { - copy_from_user(dst, src, res); + long left = raw_copy_from_user(dst, src, res); + if (unlikely(left)) + memset(dst + (res - left), 0, left); return res-1; } } diff --git a/arch/hexagon/kernel/hexagon_ksyms.c b/arch/hexagon/kernel/hexagon_ksyms.c index af9dec4c28eb..00bcad9cbd8f 100644 --- a/arch/hexagon/kernel/hexagon_ksyms.c +++ b/arch/hexagon/kernel/hexagon_ksyms.c @@ -25,8 +25,8 @@ /* Additional functions */ EXPORT_SYMBOL(__clear_user_hexagon); -EXPORT_SYMBOL(__copy_from_user_hexagon); -EXPORT_SYMBOL(__copy_to_user_hexagon); +EXPORT_SYMBOL(raw_copy_from_user); +EXPORT_SYMBOL(raw_copy_to_user); EXPORT_SYMBOL(__iounmap); EXPORT_SYMBOL(__strnlen_user); EXPORT_SYMBOL(__vmgetie); diff --git a/arch/hexagon/kernel/time.c b/arch/hexagon/kernel/time.c index ff4e9bf995e9..29b1f57116c8 100644 --- a/arch/hexagon/kernel/time.c +++ b/arch/hexagon/kernel/time.c @@ -199,7 +199,9 @@ void __init time_init_deferred(void) clockevents_calc_mult_shift(ce_dev, sleep_clk_freq, 4); ce_dev->max_delta_ns = clockevent_delta2ns(0x7fffffff, ce_dev); + ce_dev->max_delta_ticks = 0x7fffffff; ce_dev->min_delta_ns = clockevent_delta2ns(0xf, ce_dev); + ce_dev->min_delta_ticks = 0xf; #ifdef CONFIG_SMP setup_percpu_clockdev(); diff --git a/arch/hexagon/mm/copy_from_user.S b/arch/hexagon/mm/copy_from_user.S index 7fc94f3e6642..7da066fbd16f 100644 --- a/arch/hexagon/mm/copy_from_user.S +++ b/arch/hexagon/mm/copy_from_user.S @@ -44,7 +44,7 @@ #define bytes r2 #define loopcount r5 -#define FUNCNAME __copy_from_user_hexagon +#define FUNCNAME raw_copy_from_user #include "copy_user_template.S" /* LOAD FAULTS from COPY_FROM_USER */ diff --git a/arch/hexagon/mm/copy_to_user.S b/arch/hexagon/mm/copy_to_user.S index 0cfbcc09d1d9..a7b7f8db21df 100644 --- a/arch/hexagon/mm/copy_to_user.S +++ b/arch/hexagon/mm/copy_to_user.S @@ -43,7 +43,7 @@ #define bytes r2 #define loopcount r5 -#define FUNCNAME __copy_to_user_hexagon +#define FUNCNAME raw_copy_to_user #include "copy_user_template.S" /* STORE FAULTS from COPY_TO_USER */ diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 18ca6a9ce566..6a15083cc366 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -52,7 +52,6 @@ config IA64 select MODULES_USE_ELF_RELA select ARCH_USE_CMPXCHG_LOCKREF select HAVE_ARCH_AUDITSYSCALL - select HAVE_ARCH_HARDENED_USERCOPY default y help The Itanium Processor Family is Intel's 64-bit successor to diff --git a/arch/ia64/include/asm/asm-prototypes.h b/arch/ia64/include/asm/asm-prototypes.h new file mode 100644 index 000000000000..a2c139808cfe --- /dev/null +++ b/arch/ia64/include/asm/asm-prototypes.h @@ -0,0 +1,29 @@ +#ifndef _ASM_IA64_ASM_PROTOTYPES_H +#define _ASM_IA64_ASM_PROTOTYPES_H + +#include <asm/cacheflush.h> +#include <asm/checksum.h> +#include <asm/esi.h> +#include <asm/ftrace.h> +#include <asm/page.h> +#include <asm/pal.h> +#include <asm/string.h> +#include <asm/uaccess.h> +#include <asm/unwind.h> +#include <asm/xor.h> + +extern const char ia64_ivt[]; + +signed int __divsi3(signed int, unsigned int); +signed int __modsi3(signed int, unsigned int); + +signed long long __divdi3(signed long long, unsigned long long); +signed long long __moddi3(signed long long, unsigned long long); + +unsigned int __udivsi3(unsigned int, unsigned int); +unsigned int __umodsi3(unsigned int, unsigned int); + +unsigned long long __udivdi3(unsigned long long, unsigned long long); +unsigned long long __umoddi3(unsigned long long, unsigned long long); + +#endif /* _ASM_IA64_ASM_PROTOTYPES_H */ diff --git a/arch/ia64/include/asm/extable.h b/arch/ia64/include/asm/extable.h new file mode 100644 index 000000000000..20376e71eab4 --- /dev/null +++ b/arch/ia64/include/asm/extable.h @@ -0,0 +1,11 @@ +#ifndef _ASM_IA64_EXTABLE_H +#define _ASM_IA64_EXTABLE_H + +#define ARCH_HAS_RELATIVE_EXTABLE + +struct exception_table_entry { + int insn; /* location-relative address of insn this fixup is for */ + int fixup; /* location-relative continuation addr.; if bit 2 is set, r9 is set to 0 */ +}; + +#endif diff --git a/arch/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h index 471044be2a3b..82a7646c4416 100644 --- a/arch/ia64/include/asm/uaccess.h +++ b/arch/ia64/include/asm/uaccess.h @@ -33,14 +33,13 @@ */ #include <linux/compiler.h> -#include <linux/errno.h> -#include <linux/sched.h> #include <linux/page-flags.h> #include <linux/mm.h> #include <asm/intrinsics.h> #include <asm/pgtable.h> #include <asm/io.h> +#include <asm/extable.h> /* * For historical reasons, the following macros are grossly misnamed: @@ -48,9 +47,6 @@ #define KERNEL_DS ((mm_segment_t) { ~0UL }) /* cf. access_ok() */ #define USER_DS ((mm_segment_t) { TASK_SIZE-1 }) /* cf. access_ok() */ -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - #define get_ds() (KERNEL_DS) #define get_fs() (current_thread_info()->addr_limit) #define set_fs(x) (current_thread_info()->addr_limit = (x)) @@ -63,14 +59,14 @@ * address TASK_SIZE is never valid. We also need to make sure that the address doesn't * point inside the virtually mapped linear page table. */ -#define __access_ok(addr, size, segment) \ -({ \ - __chk_user_ptr(addr); \ - (likely((unsigned long) (addr) <= (segment).seg) \ - && ((segment).seg == KERNEL_DS.seg \ - || likely(REGION_OFFSET((unsigned long) (addr)) < RGN_MAP_LIMIT))); \ -}) -#define access_ok(type, addr, size) __access_ok((addr), (size), get_fs()) +static inline int __access_ok(const void __user *p, unsigned long size) +{ + unsigned long addr = (unsigned long)p; + unsigned long seg = get_fs().seg; + return likely(addr <= seg) && + (seg == KERNEL_DS.seg || likely(REGION_OFFSET(addr) < RGN_MAP_LIMIT)); +} +#define access_ok(type, addr, size) __access_ok((addr), (size)) /* * These are the main single-value transfer routines. They automatically @@ -80,8 +76,8 @@ * (a) re-use the arguments for side effects (sizeof/typeof is ok) * (b) require any knowledge of processes at this stage */ -#define put_user(x, ptr) __put_user_check((__typeof__(*(ptr))) (x), (ptr), sizeof(*(ptr)), get_fs()) -#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr)), get_fs()) +#define put_user(x, ptr) __put_user_check((__typeof__(*(ptr))) (x), (ptr), sizeof(*(ptr))) +#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr))) /* * The "__xxx" versions do not do address space checking, useful when @@ -184,13 +180,13 @@ extern void __get_user_unknown (void); * could clobber r8 and r9 (among others). Thus, be careful not to evaluate it while * using r8/r9. */ -#define __do_get_user(check, x, ptr, size, segment) \ +#define __do_get_user(check, x, ptr, size) \ ({ \ const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ __typeof__ (size) __gu_size = (size); \ long __gu_err = -EFAULT; \ unsigned long __gu_val = 0; \ - if (!check || __access_ok(__gu_ptr, size, segment)) \ + if (!check || __access_ok(__gu_ptr, size)) \ switch (__gu_size) { \ case 1: __get_user_size(__gu_val, __gu_ptr, 1, __gu_err); break; \ case 2: __get_user_size(__gu_val, __gu_ptr, 2, __gu_err); break; \ @@ -202,8 +198,8 @@ extern void __get_user_unknown (void); __gu_err; \ }) -#define __get_user_nocheck(x, ptr, size) __do_get_user(0, x, ptr, size, KERNEL_DS) -#define __get_user_check(x, ptr, size, segment) __do_get_user(1, x, ptr, size, segment) +#define __get_user_nocheck(x, ptr, size) __do_get_user(0, x, ptr, size) +#define __get_user_check(x, ptr, size) __do_get_user(1, x, ptr, size) extern void __put_user_unknown (void); @@ -211,14 +207,14 @@ extern void __put_user_unknown (void); * Evaluating arguments X, PTR, SIZE, and SEGMENT may involve subroutine-calls, which * could clobber r8 (among others). Thus, be careful not to evaluate them while using r8. */ -#define __do_put_user(check, x, ptr, size, segment) \ +#define __do_put_user(check, x, ptr, size) \ ({ \ __typeof__ (x) __pu_x = (x); \ __typeof__ (*(ptr)) __user *__pu_ptr = (ptr); \ __typeof__ (size) __pu_size = (size); \ long __pu_err = -EFAULT; \ \ - if (!check || __access_ok(__pu_ptr, __pu_size, segment)) \ + if (!check || __access_ok(__pu_ptr, __pu_size)) \ switch (__pu_size) { \ case 1: __put_user_size(__pu_x, __pu_ptr, 1, __pu_err); break; \ case 2: __put_user_size(__pu_x, __pu_ptr, 2, __pu_err); break; \ @@ -229,8 +225,8 @@ extern void __put_user_unknown (void); __pu_err; \ }) -#define __put_user_nocheck(x, ptr, size) __do_put_user(0, x, ptr, size, KERNEL_DS) -#define __put_user_check(x, ptr, size, segment) __do_put_user(1, x, ptr, size, segment) +#define __put_user_nocheck(x, ptr, size) __do_put_user(0, x, ptr, size) +#define __put_user_check(x, ptr, size) __do_put_user(1, x, ptr, size) /* * Complex access routines @@ -239,56 +235,19 @@ extern unsigned long __must_check __copy_user (void __user *to, const void __use unsigned long count); static inline unsigned long -__copy_to_user (void __user *to, const void *from, unsigned long count) +raw_copy_to_user(void __user *to, const void *from, unsigned long count) { - check_object_size(from, count, true); - return __copy_user(to, (__force void __user *) from, count); } static inline unsigned long -__copy_from_user (void *to, const void __user *from, unsigned long count) +raw_copy_from_user(void *to, const void __user *from, unsigned long count) { - check_object_size(to, count, false); - return __copy_user((__force void __user *) to, from, count); } -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user -#define copy_to_user(to, from, n) \ -({ \ - void __user *__cu_to = (to); \ - const void *__cu_from = (from); \ - long __cu_len = (n); \ - \ - if (__access_ok(__cu_to, __cu_len, get_fs())) { \ - check_object_size(__cu_from, __cu_len, true); \ - __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \ - } \ - __cu_len; \ -}) - -static inline unsigned long -copy_from_user(void *to, const void __user *from, unsigned long n) -{ - check_object_size(to, n, false); - if (likely(__access_ok(from, n, get_fs()))) - n = __copy_user((__force void __user *) to, from, n); - else - memset(to, 0, n); - return n; -} - -#define __copy_in_user(to, from, size) __copy_user((to), (from), (size)) - -static inline unsigned long -copy_in_user (void __user *to, const void __user *from, unsigned long n) -{ - if (likely(access_ok(VERIFY_READ, from, n) && access_ok(VERIFY_WRITE, to, n))) - n = __copy_user(to, from, n); - return n; -} +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER extern unsigned long __do_clear_user (void __user *, unsigned long); @@ -297,7 +256,7 @@ extern unsigned long __do_clear_user (void __user *, unsigned long); #define clear_user(to, n) \ ({ \ unsigned long __cu_len = (n); \ - if (__access_ok(to, __cu_len, get_fs())) \ + if (__access_ok(to, __cu_len)) \ __cu_len = __do_clear_user(to, __cu_len); \ __cu_len; \ }) @@ -313,7 +272,7 @@ extern long __must_check __strncpy_from_user (char *to, const char __user *from, ({ \ const char __user * __sfu_from = (from); \ long __sfu_ret = -EFAULT; \ - if (__access_ok(__sfu_from, 0, get_fs())) \ + if (__access_ok(__sfu_from, 0)) \ __sfu_ret = __strncpy_from_user((to), __sfu_from, (n)); \ __sfu_ret; \ }) @@ -325,7 +284,7 @@ extern unsigned long __strlen_user (const char __user *); ({ \ const char __user *__su_str = (str); \ unsigned long __su_ret = 0; \ - if (__access_ok(__su_str, 0, get_fs())) \ + if (__access_ok(__su_str, 0)) \ __su_ret = __strlen_user(__su_str); \ __su_ret; \ }) @@ -341,18 +300,11 @@ extern unsigned long __strnlen_user (const char __user *, long); ({ \ const char __user *__su_str = (str); \ unsigned long __su_ret = 0; \ - if (__access_ok(__su_str, 0, get_fs())) \ + if (__access_ok(__su_str, 0)) \ __su_ret = __strnlen_user(__su_str, len); \ __su_ret; \ }) -#define ARCH_HAS_RELATIVE_EXTABLE - -struct exception_table_entry { - int insn; /* location-relative address of insn this fixup is for */ - int fixup; /* location-relative continuation addr.; if bit 2 is set, r9 is set to 0 */ -}; - #define ARCH_HAS_TRANSLATE_MEM_PTR 1 static __inline__ void * xlate_dev_mem_ptr(phys_addr_t p) diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index 6ab0ae7d6535..d1d945c6bd05 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c @@ -153,7 +153,7 @@ slot (const struct insn *insn) static int apply_imm64 (struct module *mod, struct insn *insn, uint64_t val) { - if (slot(insn) != 2) { + if (slot(insn) != 1 && slot(insn) != 2) { printk(KERN_ERR "%s: invalid slot number %d for IMM64\n", mod->name, slot(insn)); return 0; @@ -165,7 +165,7 @@ apply_imm64 (struct module *mod, struct insn *insn, uint64_t val) static int apply_imm60 (struct module *mod, struct insn *insn, uint64_t val) { - if (slot(insn) != 2) { + if (slot(insn) != 1 && slot(insn) != 2) { printk(KERN_ERR "%s: invalid slot number %d for IMM60\n", mod->name, slot(insn)); return 0; diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index d194d5c83d32..63dc9cdc95c5 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -179,14 +179,14 @@ struct salinfo_platform_oemdata_parms { const u8 *efi_guid; u8 **oemdata; u64 *oemdata_size; - int ret; }; -static void +static long salinfo_platform_oemdata_cpu(void *context) { struct salinfo_platform_oemdata_parms *parms = context; - parms->ret = salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size); + + return salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size); } static void @@ -380,16 +380,7 @@ salinfo_log_release(struct inode *inode, struct file *file) return 0; } -static void -call_on_cpu(int cpu, void (*fn)(void *), void *arg) -{ - cpumask_t save_cpus_allowed = current->cpus_allowed; - set_cpus_allowed_ptr(current, cpumask_of(cpu)); - (*fn)(arg); - set_cpus_allowed_ptr(current, &save_cpus_allowed); -} - -static void +static long salinfo_log_read_cpu(void *context) { struct salinfo_data *data = context; @@ -399,6 +390,7 @@ salinfo_log_read_cpu(void *context) /* Clear corrected errors as they are read from SAL */ if (rh->severity == sal_log_severity_corrected) ia64_sal_clear_state_info(data->type); + return 0; } static void @@ -430,7 +422,7 @@ retry: spin_unlock_irqrestore(&data_saved_lock, flags); if (!data->saved_num) - call_on_cpu(cpu, salinfo_log_read_cpu, data); + work_on_cpu_safe(cpu, salinfo_log_read_cpu, data); if (!data->log_size) { data->state = STATE_NO_DATA; cpumask_clear_cpu(cpu, &data->cpu_event); @@ -459,11 +451,13 @@ salinfo_log_read(struct file *file, char __user *buffer, size_t count, loff_t *p return simple_read_from_buffer(buffer, count, ppos, buf, bufsize); } -static void +static long salinfo_log_clear_cpu(void *context) { struct salinfo_data *data = context; + ia64_sal_clear_state_info(data->type); + return 0; } static int @@ -486,7 +480,7 @@ salinfo_log_clear(struct salinfo_data *data, int cpu) rh = (sal_log_record_header_t *)(data->log_buffer); /* Corrected errors have already been cleared from SAL */ if (rh->severity != sal_log_severity_corrected) - call_on_cpu(cpu, salinfo_log_clear_cpu, data); + work_on_cpu_safe(cpu, salinfo_log_clear_cpu, data); /* clearing a record may make a new record visible */ salinfo_log_new_read(cpu, data); if (data->state == STATE_LOG_RECORD) { @@ -531,9 +525,8 @@ salinfo_log_write(struct file *file, const char __user *buffer, size_t count, lo .oemdata = &data->oemdata, .oemdata_size = &data->oemdata_size }; - call_on_cpu(cpu, salinfo_platform_oemdata_cpu, &parms); - if (parms.ret) - count = parms.ret; + count = work_on_cpu_safe(cpu, salinfo_platform_oemdata_cpu, + &parms); } else data->oemdata_size = 0; } else diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 1a68f012a6dc..d76529cbff20 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -355,18 +355,12 @@ static int cache_add_dev(unsigned int cpu) unsigned long i, j; struct cache_info *this_object; int retval = 0; - cpumask_t oldmask; if (all_cpu_cache_info[cpu].kobj.parent) return 0; - oldmask = current->cpus_allowed; - retval = set_cpus_allowed_ptr(current, cpumask_of(cpu)); - if (unlikely(retval)) - return retval; retval = cpu_cache_sysfs_init(cpu); - set_cpus_allowed_ptr(current, &oldmask); if (unlikely(retval < 0)) return retval; diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index f89d20c97412..798026dde52e 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -192,6 +192,8 @@ SECTIONS { CONSTRUCTORS } + BUG_TABLE + . = ALIGN(16); /* gp must be 16-byte aligned for exc. table */ .got : AT(ADDR(.got) - LOAD_OFFSET) { *(.got.plt) diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 1f3d3877618f..0a40b14407b1 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -24,25 +24,25 @@ AFLAGS___modsi3.o = -DMODULO AFLAGS___umodsi3.o = -DUNSIGNED -DMODULO $(obj)/__divdi3.o: $(src)/idiv64.S FORCE - $(call if_changed_dep,as_o_S) + $(call if_changed_rule,as_o_S) $(obj)/__udivdi3.o: $(src)/idiv64.S FORCE - $(call if_changed_dep,as_o_S) + $(call if_changed_rule,as_o_S) $(obj)/__moddi3.o: $(src)/idiv64.S FORCE - $(call if_changed_dep,as_o_S) + $(call if_changed_rule,as_o_S) $(obj)/__umoddi3.o: $(src)/idiv64.S FORCE - $(call if_changed_dep,as_o_S) + $(call if_changed_rule,as_o_S) $(obj)/__divsi3.o: $(src)/idiv32.S FORCE - $(call if_changed_dep,as_o_S) + $(call if_changed_rule,as_o_S) $(obj)/__udivsi3.o: $(src)/idiv32.S FORCE - $(call if_changed_dep,as_o_S) + $(call if_changed_rule,as_o_S) $(obj)/__modsi3.o: $(src)/idiv32.S FORCE - $(call if_changed_dep,as_o_S) + $(call if_changed_rule,as_o_S) $(obj)/__umodsi3.o: $(src)/idiv32.S FORCE - $(call if_changed_dep,as_o_S) + $(call if_changed_rule,as_o_S) diff --git a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S index b264b6a7967b..bbbadc478f5b 100644 --- a/arch/ia64/lib/memcpy_mck.S +++ b/arch/ia64/lib/memcpy_mck.S @@ -556,9 +556,6 @@ EK(.ex_handler, (p17) st8 [dst1]=r39,8); \ #define D r22 #define F r28 -#define memset_arg0 r32 -#define memset_arg2 r33 - #define saved_retval loc0 #define saved_rtlink loc1 #define saved_pfs_stack loc2 @@ -622,7 +619,7 @@ EK(.ex_handler, (p17) st8 [dst1]=r39,8); \ * (faulting_addr - orig_dst) -> len to faulting st address * B = (cur_dst - orig_dst) -> len copied so far * C = A - B -> len need to be copied - * D = orig_len - A -> len need to be zeroed + * D = orig_len - A -> len need to be left along */ (p6) sub A = F, saved_in0 (p7) sub A = F, saved_in1 @@ -638,9 +635,6 @@ EK(.ex_handler, (p17) st8 [dst1]=r39,8); \ sub D = saved_in2, A ;; cmp.gt p8,p0=C,r0 // more than 1 byte? - add memset_arg0=saved_in0, A -(p6) mov memset_arg2=0 // copy_to_user should not call memset -(p7) mov memset_arg2=D // copy_from_user need to have kbuf zeroed mov r8=0 mov saved_retval = D mov saved_rtlink = b0 @@ -652,11 +646,6 @@ EK(.ex_handler, (p17) st8 [dst1]=r39,8); \ ;; add saved_retval=saved_retval,r8 // above might return non-zero value - cmp.gt p8,p0=memset_arg2,r0 // more than 1 byte? - mov out0=memset_arg0 // *s - mov out1=r0 // c - mov out2=memset_arg2 // n -(p8) br.call.sptk.few b0=memset ;; mov retval=saved_retval diff --git a/arch/ia64/mm/extable.c b/arch/ia64/mm/extable.c index 4edb816aba9a..10dd4a66e167 100644 --- a/arch/ia64/mm/extable.c +++ b/arch/ia64/mm/extable.c @@ -5,7 +5,10 @@ * David Mosberger-Tang <davidm@hpl.hp.com> */ -#include <linux/uaccess.h> +#include <asm/ptrace.h> +#include <asm/extable.h> +#include <asm/errno.h> +#include <asm/processor.h> void ia64_handle_exception (struct pt_regs *regs, const struct exception_table_entry *e) diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 52704f199dd6..55febd65911a 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -598,12 +598,17 @@ static void sn_hwperf_call_sal(void *info) op_info->ret = r; } +static long sn_hwperf_call_sal_work(void *info) +{ + sn_hwperf_call_sal(info); + return 0; +} + static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info) { u32 cpu; u32 use_ipi; int r = 0; - cpumask_t save_allowed; cpu = (op_info->a->arg & SN_HWPERF_ARG_CPU_MASK) >> 32; use_ipi = op_info->a->arg & SN_HWPERF_ARG_USE_IPI_MASK; @@ -629,13 +634,9 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info) /* use an interprocessor interrupt to call SAL */ smp_call_function_single(cpu, sn_hwperf_call_sal, op_info, 1); - } - else { - /* migrate the task before calling SAL */ - save_allowed = current->cpus_allowed; - set_cpus_allowed_ptr(current, cpumask_of(cpu)); - sn_hwperf_call_sal(op_info); - set_cpus_allowed_ptr(current, &save_allowed); + } else { + /* Call on the target CPU */ + work_on_cpu_safe(cpu, sn_hwperf_call_sal_work, op_info); } } r = op_info->ret; diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild index deb298777df2..c000ffac8586 100644 --- a/arch/m32r/include/asm/Kbuild +++ b/arch/m32r/include/asm/Kbuild @@ -2,6 +2,7 @@ generic-y += clkdev.h generic-y += current.h generic-y += exec.h +generic-y += extable.h generic-y += irq_work.h generic-y += kvm_para.h generic-y += mcs_spinlock.h diff --git a/arch/m32r/include/asm/uaccess.h b/arch/m32r/include/asm/uaccess.h index 6f8982157a75..07be349c00ad 100644 --- a/arch/m32r/include/asm/uaccess.h +++ b/arch/m32r/include/asm/uaccess.h @@ -11,13 +11,9 @@ /* * User space memory access functions */ -#include <linux/errno.h> -#include <linux/thread_info.h> #include <asm/page.h> #include <asm/setup.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 +#include <linux/prefetch.h> /* * The fs value determines whether argument validity checking should be @@ -114,25 +110,7 @@ static inline int access_ok(int type, const void *addr, unsigned long size) } #endif /* CONFIG_MMU */ -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -extern int fixup_exception(struct pt_regs *regs); +#include <asm/extable.h> /* * These are the main single-value transfer routines. They automatically @@ -483,174 +461,25 @@ do { \ : "r14", "memory"); \ } while (0) -#define __copy_user_zeroing(to, from, size) \ -do { \ - unsigned long __dst, __src, __c; \ - __asm__ __volatile__ ( \ - " mv r14, %0\n" \ - " or r14, %1\n" \ - " beq %0, %1, 9f\n" \ - " beqz %2, 9f\n" \ - " and3 r14, r14, #3\n" \ - " bnez r14, 2f\n" \ - " and3 %2, %2, #3\n" \ - " beqz %3, 2f\n" \ - " addi %0, #-4 ; word_copy \n" \ - " .fillinsn\n" \ - "0: ld r14, @%1+\n" \ - " addi %3, #-1\n" \ - " .fillinsn\n" \ - "1: st r14, @+%0\n" \ - " bnez %3, 0b\n" \ - " beqz %2, 9f\n" \ - " addi %0, #4\n" \ - " .fillinsn\n" \ - "2: ldb r14, @%1 ; byte_copy \n" \ - " .fillinsn\n" \ - "3: stb r14, @%0\n" \ - " addi %1, #1\n" \ - " addi %2, #-1\n" \ - " addi %0, #1\n" \ - " bnez %2, 2b\n" \ - " .fillinsn\n" \ - "9:\n" \ - ".section .fixup,\"ax\"\n" \ - " .balign 4\n" \ - "5: addi %3, #1\n" \ - " addi %1, #-4\n" \ - " .fillinsn\n" \ - "6: slli %3, #2\n" \ - " add %2, %3\n" \ - " addi %0, #4\n" \ - " .fillinsn\n" \ - "7: ldi r14, #0 ; store zero \n" \ - " .fillinsn\n" \ - "8: addi %2, #-1\n" \ - " stb r14, @%0 ; ACE? \n" \ - " addi %0, #1\n" \ - " bnez %2, 8b\n" \ - " seth r14, #high(9b)\n" \ - " or3 r14, r14, #low(9b)\n" \ - " jmp r14\n" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n" \ - " .balign 4\n" \ - " .long 0b,6b\n" \ - " .long 1b,5b\n" \ - " .long 2b,7b\n" \ - " .long 3b,7b\n" \ - ".previous\n" \ - : "=&r" (__dst), "=&r" (__src), "=&r" (size), \ - "=&r" (__c) \ - : "0" (to), "1" (from), "2" (size), "3" (size / 4) \ - : "r14", "memory"); \ -} while (0) - - /* We let the __ versions of copy_from/to_user inline, because they're often * used in fast paths and have only a small space overhead. */ -static inline unsigned long __generic_copy_from_user_nocheck(void *to, - const void __user *from, unsigned long n) +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - __copy_user_zeroing(to, from, n); + prefetchw(to); + __copy_user(to, from, n); return n; } -static inline unsigned long __generic_copy_to_user_nocheck(void __user *to, - const void *from, unsigned long n) +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { + prefetch(from); __copy_user(to, from, n); return n; } -unsigned long __generic_copy_to_user(void __user *, const void *, unsigned long); -unsigned long __generic_copy_from_user(void *, const void __user *, unsigned long); - -/** - * __copy_to_user: - Copy a block of data into user space, with less checking. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from kernel space to user space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - */ -#define __copy_to_user(to, from, n) \ - __generic_copy_to_user_nocheck((to), (from), (n)) - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - -/** - * copy_to_user: - Copy a block of data into user space. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from kernel space to user space. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - */ -#define copy_to_user(to, from, n) \ -({ \ - might_fault(); \ - __generic_copy_to_user((to), (from), (n)); \ -}) - -/** - * __copy_from_user: - Copy a block of data from user space, with less checking. * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from user space to kernel space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - */ -#define __copy_from_user(to, from, n) \ - __generic_copy_from_user_nocheck((to), (from), (n)) - -/** - * copy_from_user: - Copy a block of data from user space. - * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from user space to kernel space. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - */ -#define copy_from_user(to, from, n) \ -({ \ - might_fault(); \ - __generic_copy_from_user((to), (from), (n)); \ -}) - long __must_check strncpy_from_user(char *dst, const char __user *src, long count); long __must_check __strncpy_from_user(char *dst, diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c index d763f0bd2106..a4d43b5cc102 100644 --- a/arch/m32r/kernel/m32r_ksyms.c +++ b/arch/m32r/kernel/m32r_ksyms.c @@ -26,8 +26,6 @@ EXPORT_SYMBOL(strncpy_from_user); EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(clear_user); EXPORT_SYMBOL(__clear_user); -EXPORT_SYMBOL(__generic_copy_from_user); -EXPORT_SYMBOL(__generic_copy_to_user); EXPORT_SYMBOL(strnlen_user); #ifdef CONFIG_SMP diff --git a/arch/m32r/lib/usercopy.c b/arch/m32r/lib/usercopy.c index fd03f2731f20..b3ef2c899f96 100644 --- a/arch/m32r/lib/usercopy.c +++ b/arch/m32r/lib/usercopy.c @@ -11,27 +11,6 @@ #include <linux/thread_info.h> #include <linux/uaccess.h> -unsigned long -__generic_copy_to_user(void __user *to, const void *from, unsigned long n) -{ - prefetch(from); - if (access_ok(VERIFY_WRITE, to, n)) - __copy_user(to,from,n); - return n; -} - -unsigned long -__generic_copy_from_user(void *to, const void __user *from, unsigned long n) -{ - prefetchw(to); - if (access_ok(VERIFY_READ, from, n)) - __copy_user_zeroing(to,from,n); - else - memset(to, 0, n); - return n; -} - - /* * Copy a null terminated string from userspace. */ diff --git a/arch/m68k/coldfire/pit.c b/arch/m68k/coldfire/pit.c index 175553d5b8ed..6c0878018b44 100644 --- a/arch/m68k/coldfire/pit.c +++ b/arch/m68k/coldfire/pit.c @@ -149,8 +149,10 @@ void hw_timer_init(irq_handler_t handler) cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32); cf_pit_clockevent.max_delta_ns = clockevent_delta2ns(0xFFFF, &cf_pit_clockevent); + cf_pit_clockevent.max_delta_ticks = 0xFFFF; cf_pit_clockevent.min_delta_ns = clockevent_delta2ns(0x3f, &cf_pit_clockevent); + cf_pit_clockevent.min_delta_ticks = 0x3f; clockevents_register_device(&cf_pit_clockevent); setup_irq(MCF_IRQ_PIT1, &pit_irq); diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index d4f9ccbfa85c..82005d2ff717 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -5,6 +5,7 @@ generic-y += device.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += futex.h generic-y += hw_irq.h generic-y += ioctl.h diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h index f5f790c31bf8..77239e81379b 100644 --- a/arch/m68k/include/asm/processor.h +++ b/arch/m68k/include/asm/processor.h @@ -122,16 +122,6 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc, wrusp(usp); } -#ifdef CONFIG_MMU -extern int handle_kernel_fault(struct pt_regs *regs); -#else -static inline int handle_kernel_fault(struct pt_regs *regs) -{ - /* Any fault in kernel is fatal on non-mmu */ - return 0; -} -#endif - /* Forward declaration, a strange C thing */ struct task_struct; diff --git a/arch/m68k/include/asm/uaccess.h b/arch/m68k/include/asm/uaccess.h index 3fadc4a93d97..67b3481d6020 100644 --- a/arch/m68k/include/asm/uaccess.h +++ b/arch/m68k/include/asm/uaccess.h @@ -4,6 +4,7 @@ #include <asm/uaccess_mm.h> #endif +#include <asm/extable.h> #ifdef CONFIG_CPU_HAS_NO_UNALIGNED #include <asm-generic/uaccess-unaligned.h> #else diff --git a/arch/m68k/include/asm/uaccess_mm.h b/arch/m68k/include/asm/uaccess_mm.h index d228601b3afc..ef856ffeffdf 100644 --- a/arch/m68k/include/asm/uaccess_mm.h +++ b/arch/m68k/include/asm/uaccess_mm.h @@ -5,14 +5,9 @@ * User space memory access functions */ #include <linux/compiler.h> -#include <linux/errno.h> #include <linux/types.h> -#include <linux/sched.h> #include <asm/segment.h> -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - /* We let the MMU do all checking */ static inline int access_ok(int type, const void __user *addr, unsigned long size) @@ -36,24 +31,6 @@ static inline int access_ok(int type, const void __user *addr, #define MOVES "move" #endif -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - extern int __put_user_bad(void); extern int __get_user_bad(void); @@ -202,39 +179,55 @@ asm volatile ("\n" \ unsigned long __generic_copy_from_user(void *to, const void __user *from, unsigned long n); unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n); -#define __constant_copy_from_user_asm(res, to, from, tmp, n, s1, s2, s3)\ +#define __suffix0 +#define __suffix1 b +#define __suffix2 w +#define __suffix4 l + +#define ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\ asm volatile ("\n" \ "1: "MOVES"."#s1" (%2)+,%3\n" \ " move."#s1" %3,(%1)+\n" \ + " .ifnc \""#s2"\",\"\"\n" \ "2: "MOVES"."#s2" (%2)+,%3\n" \ " move."#s2" %3,(%1)+\n" \ " .ifnc \""#s3"\",\"\"\n" \ "3: "MOVES"."#s3" (%2)+,%3\n" \ " move."#s3" %3,(%1)+\n" \ " .endif\n" \ + " .endif\n" \ "4:\n" \ " .section __ex_table,\"a\"\n" \ " .align 4\n" \ " .long 1b,10f\n" \ + " .ifnc \""#s2"\",\"\"\n" \ " .long 2b,20f\n" \ " .ifnc \""#s3"\",\"\"\n" \ " .long 3b,30f\n" \ " .endif\n" \ + " .endif\n" \ " .previous\n" \ "\n" \ " .section .fixup,\"ax\"\n" \ " .even\n" \ - "10: clr."#s1" (%1)+\n" \ - "20: clr."#s2" (%1)+\n" \ + "10: addq.l #"#n1",%0\n" \ + " .ifnc \""#s2"\",\"\"\n" \ + "20: addq.l #"#n2",%0\n" \ " .ifnc \""#s3"\",\"\"\n" \ - "30: clr."#s3" (%1)+\n" \ + "30: addq.l #"#n3",%0\n" \ + " .endif\n" \ " .endif\n" \ - " moveq.l #"#n",%0\n" \ " jra 4b\n" \ " .previous\n" \ : "+d" (res), "+&a" (to), "+a" (from), "=&d" (tmp) \ : : "memory") +#define ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3)\ + ____constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, s1, s2, s3) +#define __constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3) \ + ___constant_copy_from_user_asm(res, to, from, tmp, n1, n2, n3, \ + __suffix##n1, __suffix##n2, __suffix##n3) + static __always_inline unsigned long __constant_copy_from_user(void *to, const void __user *from, unsigned long n) { @@ -242,37 +235,37 @@ __constant_copy_from_user(void *to, const void __user *from, unsigned long n) switch (n) { case 1: - __get_user_asm(res, *(u8 *)to, (u8 __user *)from, u8, b, d, 1); + __constant_copy_from_user_asm(res, to, from, tmp, 1, 0, 0); break; case 2: - __get_user_asm(res, *(u16 *)to, (u16 __user *)from, u16, w, r, 2); + __constant_copy_from_user_asm(res, to, from, tmp, 2, 0, 0); break; case 3: - __constant_copy_from_user_asm(res, to, from, tmp, 3, w, b,); + __constant_copy_from_user_asm(res, to, from, tmp, 2, 1, 0); break; case 4: - __get_user_asm(res, *(u32 *)to, (u32 __user *)from, u32, l, r, 4); + __constant_copy_from_user_asm(res, to, from, tmp, 4, 0, 0); break; case 5: - __constant_copy_from_user_asm(res, to, from, tmp, 5, l, b,); + __constant_copy_from_user_asm(res, to, from, tmp, 4, 1, 0); break; case 6: - __constant_copy_from_user_asm(res, to, from, tmp, 6, l, w,); + __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 0); break; case 7: - __constant_copy_from_user_asm(res, to, from, tmp, 7, l, w, b); + __constant_copy_from_user_asm(res, to, from, tmp, 4, 2, 1); break; case 8: - __constant_copy_from_user_asm(res, to, from, tmp, 8, l, l,); + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 0); break; case 9: - __constant_copy_from_user_asm(res, to, from, tmp, 9, l, l, b); + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 1); break; case 10: - __constant_copy_from_user_asm(res, to, from, tmp, 10, l, l, w); + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 2); break; case 12: - __constant_copy_from_user_asm(res, to, from, tmp, 12, l, l, l); + __constant_copy_from_user_asm(res, to, from, tmp, 4, 4, 4); break; default: /* we limit the inlined version to 3 moves */ @@ -363,24 +356,26 @@ __constant_copy_to_user(void __user *to, const void *from, unsigned long n) return res; } -#define __copy_from_user(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_copy_from_user(to, from, n) : \ - __generic_copy_from_user(to, from, n)) - -#define __copy_to_user(to, from, n) \ -(__builtin_constant_p(n) ? \ - __constant_copy_to_user(to, from, n) : \ - __generic_copy_to_user(to, from, n)) - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + if (__builtin_constant_p(n)) + return __constant_copy_from_user(to, from, n); + return __generic_copy_from_user(to, from, n); +} -#define copy_from_user(to, from, n) __copy_from_user(to, from, n) -#define copy_to_user(to, from, n) __copy_to_user(to, from, n) +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + if (__builtin_constant_p(n)) + return __constant_copy_to_user(to, from, n); + return __generic_copy_to_user(to, from, n); +} +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER #define user_addr_max() \ - (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL) + (uaccess_kernel() ? ~0UL : TASK_SIZE) extern long strncpy_from_user(char *dst, const char __user *src, long count); extern __must_check long strlen_user(const char __user *str); diff --git a/arch/m68k/include/asm/uaccess_no.h b/arch/m68k/include/asm/uaccess_no.h index 36deeb36503b..e482c3899ff1 100644 --- a/arch/m68k/include/asm/uaccess_no.h +++ b/arch/m68k/include/asm/uaccess_no.h @@ -4,15 +4,11 @@ /* * User space memory access functions */ -#include <linux/sched.h> #include <linux/mm.h> #include <linux/string.h> #include <asm/segment.h> -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - #define access_ok(type,addr,size) _access_ok((unsigned long)(addr),(size)) /* @@ -27,25 +23,6 @@ static inline int _access_ok(unsigned long addr, unsigned long size) } /* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - - -/* * These are the main single-value transfer routines. They automatically * use the right size if we just have the right pointer type. */ @@ -124,13 +101,21 @@ extern int __get_user_bad(void); : "=d" (x) \ : "m" (*__ptr(ptr))) -#define copy_from_user(to, from, n) (memcpy(to, from, n), 0) -#define copy_to_user(to, from, n) (memcpy(to, from, n), 0) +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + memcpy(to, (__force const void *)from, n); + return 0; +} -#define __copy_from_user(to, from, n) copy_from_user(to, from, n) -#define __copy_to_user(to, from, n) copy_to_user(to, from, n) -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + memcpy((__force void *)to, from, n); + return 0; +} +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER /* * Copy a null terminated string from userspace. diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index 093b7c42fb85..6f945bb5ffbd 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -88,7 +88,7 @@ static inline int frame_extra_sizes(int f) return frame_size_change[f]; } -int handle_kernel_fault(struct pt_regs *regs) +int fixup_exception(struct pt_regs *regs) { const struct exception_table_entry *fixup; struct pt_regs *tregs; diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index a926d2c88898..c1cc4e99aa94 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -1016,8 +1016,13 @@ asmlinkage void trap_c(struct frame *fp) /* traced a trapping instruction on a 68020/30, * real exception will be executed afterwards. */ - } else if (!handle_kernel_fault(&fp->ptregs)) - bad_super_trap(fp); + return; + } +#ifdef CONFIG_MMU + if (fixup_exception(&fp->ptregs)) + return; +#endif + bad_super_trap(fp); return; } diff --git a/arch/m68k/lib/uaccess.c b/arch/m68k/lib/uaccess.c index a76b73abaf64..7646e461aa62 100644 --- a/arch/m68k/lib/uaccess.c +++ b/arch/m68k/lib/uaccess.c @@ -30,19 +30,13 @@ unsigned long __generic_copy_from_user(void *to, const void __user *from, "6:\n" " .section .fixup,\"ax\"\n" " .even\n" - "10: move.l %0,%3\n" - "7: clr.l (%2)+\n" - " subq.l #1,%3\n" - " jne 7b\n" - " lsl.l #2,%0\n" + "10: lsl.l #2,%0\n" " btst #1,%5\n" " jeq 8f\n" - "30: clr.w (%2)+\n" - " addq.l #2,%0\n" + "30: addq.l #2,%0\n" "8: btst #0,%5\n" " jeq 6b\n" - "50: clr.b (%2)+\n" - " addq.l #1,%0\n" + "50: addq.l #1,%0\n" " jra 6b\n" " .previous\n" "\n" diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index bd66a0b20c6b..2795e4ca09d7 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c @@ -32,7 +32,7 @@ int send_fault_sig(struct pt_regs *regs) force_sig_info(siginfo.si_signo, &siginfo, current); } else { - if (handle_kernel_fault(regs)) + if (fixup_exception(regs)) return -1; //if (siginfo.si_signo == SIGBUS) diff --git a/arch/metag/include/asm/Kbuild b/arch/metag/include/asm/Kbuild index f9b9df5d6de9..8f940553a579 100644 --- a/arch/metag/include/asm/Kbuild +++ b/arch/metag/include/asm/Kbuild @@ -8,6 +8,7 @@ generic-y += dma.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += fb.h generic-y += fcntl.h generic-y += futex.h diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h index 273e61225c27..5ebc2850690e 100644 --- a/arch/metag/include/asm/uaccess.h +++ b/arch/metag/include/asm/uaccess.h @@ -4,10 +4,6 @@ /* * User space memory access functions */ -#include <linux/sched.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 /* * The fs value determines whether argument validity checking should be @@ -28,7 +24,7 @@ #define segment_eq(a, b) ((a).seg == (b).seg) -#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) +#define __kernel_ok (uaccess_kernel()) /* * Explicitly allow NULL pointers here. Parts of the kernel such * as readv/writev use access_ok to validate pointers, but want @@ -51,28 +47,7 @@ static inline int __access_ok(unsigned long addr, unsigned long size) #define access_ok(type, addr, size) __access_ok((unsigned long)(addr), \ (unsigned long)(size)) -static inline int verify_area(int type, const void *addr, unsigned long size) -{ - return access_ok(type, addr, size) ? 0 : -EFAULT; -} - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ -struct exception_table_entry { - unsigned long insn, fixup; -}; - -extern int fixup_exception(struct pt_regs *regs); +#include <asm/extable.h> /* * These are the main single-value transfer routines. They automatically @@ -197,36 +172,10 @@ extern long __must_check strnlen_user(const char __user *src, long count); #define strlen_user(str) strnlen_user(str, 32767) -extern unsigned long __must_check __copy_user_zeroing(void *to, - const void __user *from, - unsigned long n); - -static inline unsigned long -copy_from_user(void *to, const void __user *from, unsigned long n) -{ - if (likely(access_ok(VERIFY_READ, from, n))) - return __copy_user_zeroing(to, from, n); - memset(to, 0, n); - return n; -} - -#define __copy_from_user(to, from, n) __copy_user_zeroing(to, from, n) -#define __copy_from_user_inatomic __copy_from_user - -extern unsigned long __must_check __copy_user(void __user *to, - const void *from, - unsigned long n); - -static inline unsigned long copy_to_user(void __user *to, const void *from, - unsigned long n) -{ - if (access_ok(VERIFY_WRITE, to, n)) - return __copy_user(to, from, n); - return n; -} - -#define __copy_to_user(to, from, n) __copy_user(to, from, n) -#define __copy_to_user_inatomic __copy_to_user +extern unsigned long raw_copy_from_user(void *to, const void __user *from, + unsigned long n); +extern unsigned long raw_copy_to_user(void __user *to, const void *from, + unsigned long n); /* * Zero Userspace diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c index b3ebfe9c8e88..e8a4ea83cabb 100644 --- a/arch/metag/lib/usercopy.c +++ b/arch/metag/lib/usercopy.c @@ -29,7 +29,6 @@ COPY \ "1:\n" \ " .section .fixup,\"ax\"\n" \ - " MOV D1Ar1,#0\n" \ FIXUP \ " MOVT D1Ar1,#HI(1b)\n" \ " JUMP D1Ar1,#LO(1b)\n" \ @@ -260,27 +259,31 @@ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ "22:\n" \ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ - "SUB %3, %3, #32\n" \ "23:\n" \ - "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "SUB %3, %3, #32\n" \ "24:\n" \ + "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "25:\n" \ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "26:\n" \ "SUB %3, %3, #32\n" \ "DCACHE [%1+#-64], D0Ar6\n" \ "BR $Lloop"id"\n" \ \ "MOV RAPF, %1\n" \ - "25:\n" \ + "27:\n" \ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "26:\n" \ + "28:\n" \ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "29:\n" \ "SUB %3, %3, #32\n" \ - "27:\n" \ + "30:\n" \ "MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "28:\n" \ + "31:\n" \ "MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "32:\n" \ "SUB %0, %0, #8\n" \ - "29:\n" \ + "33:\n" \ "SETL [%0++], D0.7, D1.7\n" \ "SUB %3, %3, #32\n" \ "1:" \ @@ -312,11 +315,15 @@ " .long 26b,3b\n" \ " .long 27b,3b\n" \ " .long 28b,3b\n" \ - " .long 29b,4b\n" \ + " .long 29b,3b\n" \ + " .long 30b,3b\n" \ + " .long 31b,3b\n" \ + " .long 32b,3b\n" \ + " .long 33b,4b\n" \ " .previous\n" \ : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ : "0" (to), "1" (from), "2" (ret), "3" (n) \ - : "D1Ar1", "D0Ar2", "memory") + : "D1Ar1", "D0Ar2", "cc", "memory") /* rewind 'to' and 'from' pointers when a fault occurs * @@ -342,7 +349,7 @@ #define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\ __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ "LSR D0Ar2, D0Ar2, #8\n" \ - "AND D0Ar2, D0Ar2, #0x7\n" \ + "ANDS D0Ar2, D0Ar2, #0x7\n" \ "ADDZ D0Ar2, D0Ar2, #4\n" \ "SUB D0Ar2, D0Ar2, #1\n" \ "MOV D1Ar1, #4\n" \ @@ -403,47 +410,55 @@ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ "22:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ - "SUB %3, %3, #16\n" \ "23:\n" \ - "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "24:\n" \ - "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ "SUB %3, %3, #16\n" \ - "25:\n" \ + "24:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "26:\n" \ + "25:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "26:\n" \ "SUB %3, %3, #16\n" \ "27:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ "28:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "29:\n" \ + "SUB %3, %3, #16\n" \ + "30:\n" \ + "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ + "31:\n" \ + "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "32:\n" \ "SUB %3, %3, #16\n" \ "DCACHE [%1+#-64], D0Ar6\n" \ "BR $Lloop"id"\n" \ \ "MOV RAPF, %1\n" \ - "29:\n" \ + "33:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "30:\n" \ + "34:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "35:\n" \ "SUB %3, %3, #16\n" \ - "31:\n" \ + "36:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "32:\n" \ + "37:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "38:\n" \ "SUB %3, %3, #16\n" \ - "33:\n" \ + "39:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "34:\n" \ + "40:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "41:\n" \ "SUB %3, %3, #16\n" \ - "35:\n" \ + "42:\n" \ "MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \ - "36:\n" \ + "43:\n" \ "MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \ + "44:\n" \ "SUB %0, %0, #4\n" \ - "37:\n" \ + "45:\n" \ "SETD [%0++], D0.7\n" \ "SUB %3, %3, #16\n" \ "1:" \ @@ -483,11 +498,19 @@ " .long 34b,3b\n" \ " .long 35b,3b\n" \ " .long 36b,3b\n" \ - " .long 37b,4b\n" \ + " .long 37b,3b\n" \ + " .long 38b,3b\n" \ + " .long 39b,3b\n" \ + " .long 40b,3b\n" \ + " .long 41b,3b\n" \ + " .long 42b,3b\n" \ + " .long 43b,3b\n" \ + " .long 44b,3b\n" \ + " .long 45b,4b\n" \ " .previous\n" \ : "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \ : "0" (to), "1" (from), "2" (ret), "3" (n) \ - : "D1Ar1", "D0Ar2", "memory") + : "D1Ar1", "D0Ar2", "cc", "memory") /* rewind 'to' and 'from' pointers when a fault occurs * @@ -513,7 +536,7 @@ #define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\ __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ "LSR D0Ar2, D0Ar2, #8\n" \ - "AND D0Ar2, D0Ar2, #0x7\n" \ + "ANDS D0Ar2, D0Ar2, #0x7\n" \ "ADDZ D0Ar2, D0Ar2, #4\n" \ "SUB D0Ar2, D0Ar2, #1\n" \ "MOV D1Ar1, #4\n" \ @@ -525,8 +548,8 @@ "SUB %1, %1, D0Ar2\n" \ "SUB %3, %3, D1Ar1\n") -unsigned long __copy_user(void __user *pdst, const void *psrc, - unsigned long n) +unsigned long raw_copy_to_user(void __user *pdst, const void *psrc, + unsigned long n) { register char __user *dst asm ("A0.2") = pdst; register const char *src asm ("A1.2") = psrc; @@ -538,23 +561,31 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, if ((unsigned long) src & 1) { __asm_copy_to_user_1(dst, src, retn); n--; + if (retn) + return retn + n; } if ((unsigned long) dst & 1) { /* Worst case - byte copy */ while (n > 0) { __asm_copy_to_user_1(dst, src, retn); n--; + if (retn) + return retn + n; } } if (((unsigned long) src & 2) && n >= 2) { __asm_copy_to_user_2(dst, src, retn); n -= 2; + if (retn) + return retn + n; } if ((unsigned long) dst & 2) { /* Second worst case - word copy */ while (n >= 2) { __asm_copy_to_user_2(dst, src, retn); n -= 2; + if (retn) + return retn + n; } } @@ -569,6 +600,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, while (n >= 8) { __asm_copy_to_user_8x64(dst, src, retn); n -= 8; + if (retn) + return retn + n; } } if (n >= RAPF_MIN_BUF_SIZE) { @@ -581,6 +614,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, while (n >= 8) { __asm_copy_to_user_8x64(dst, src, retn); n -= 8; + if (retn) + return retn + n; } } #endif @@ -588,11 +623,15 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, while (n >= 16) { __asm_copy_to_user_16(dst, src, retn); n -= 16; + if (retn) + return retn + n; } while (n >= 4) { __asm_copy_to_user_4(dst, src, retn); n -= 4; + if (retn) + return retn + n; } switch (n) { @@ -609,24 +648,26 @@ unsigned long __copy_user(void __user *pdst, const void *psrc, break; } + /* + * If we get here, retn correctly reflects the number of failing + * bytes. + */ return retn; } -EXPORT_SYMBOL(__copy_user); +EXPORT_SYMBOL(raw_copy_to_user); #define __asm_copy_from_user_1(to, from, ret) \ __asm_copy_user_cont(to, from, ret, \ " GETB D1Ar1,[%1++]\n" \ "2: SETB [%0++],D1Ar1\n", \ - "3: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ + "3: ADD %2,%2,#1\n", \ " .long 2b,3b\n") #define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ __asm_copy_user_cont(to, from, ret, \ " GETW D1Ar1,[%1++]\n" \ "2: SETW [%0++],D1Ar1\n" COPY, \ - "3: ADD %2,%2,#2\n" \ - " SETW [%0++],D1Ar1\n" FIXUP, \ + "3: ADD %2,%2,#2\n" FIXUP, \ " .long 2b,3b\n" TENTRY) #define __asm_copy_from_user_2(to, from, ret) \ @@ -636,145 +677,26 @@ EXPORT_SYMBOL(__copy_user); __asm_copy_from_user_2x_cont(to, from, ret, \ " GETB D1Ar1,[%1++]\n" \ "4: SETB [%0++],D1Ar1\n", \ - "5: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ + "5: ADD %2,%2,#1\n", \ " .long 4b,5b\n") #define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ __asm_copy_user_cont(to, from, ret, \ " GETD D1Ar1,[%1++]\n" \ "2: SETD [%0++],D1Ar1\n" COPY, \ - "3: ADD %2,%2,#4\n" \ - " SETD [%0++],D1Ar1\n" FIXUP, \ + "3: ADD %2,%2,#4\n" FIXUP, \ " .long 2b,3b\n" TENTRY) #define __asm_copy_from_user_4(to, from, ret) \ __asm_copy_from_user_4x_cont(to, from, ret, "", "", "") -#define __asm_copy_from_user_5(to, from, ret) \ - __asm_copy_from_user_4x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "4: SETB [%0++],D1Ar1\n", \ - "5: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 4b,5b\n") - -#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_4x_cont(to, from, ret, \ - " GETW D1Ar1,[%1++]\n" \ - "4: SETW [%0++],D1Ar1\n" COPY, \ - "5: ADD %2,%2,#2\n" \ - " SETW [%0++],D1Ar1\n" FIXUP, \ - " .long 4b,5b\n" TENTRY) - -#define __asm_copy_from_user_6(to, from, ret) \ - __asm_copy_from_user_6x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_7(to, from, ret) \ - __asm_copy_from_user_6x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "6: SETB [%0++],D1Ar1\n", \ - "7: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 6b,7b\n") - -#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_4x_cont(to, from, ret, \ - " GETD D1Ar1,[%1++]\n" \ - "4: SETD [%0++],D1Ar1\n" COPY, \ - "5: ADD %2,%2,#4\n" \ - " SETD [%0++],D1Ar1\n" FIXUP, \ - " .long 4b,5b\n" TENTRY) - -#define __asm_copy_from_user_8(to, from, ret) \ - __asm_copy_from_user_8x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_9(to, from, ret) \ - __asm_copy_from_user_8x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "6: SETB [%0++],D1Ar1\n", \ - "7: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 6b,7b\n") - -#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_8x_cont(to, from, ret, \ - " GETW D1Ar1,[%1++]\n" \ - "6: SETW [%0++],D1Ar1\n" COPY, \ - "7: ADD %2,%2,#2\n" \ - " SETW [%0++],D1Ar1\n" FIXUP, \ - " .long 6b,7b\n" TENTRY) - -#define __asm_copy_from_user_10(to, from, ret) \ - __asm_copy_from_user_10x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_11(to, from, ret) \ - __asm_copy_from_user_10x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "8: SETB [%0++],D1Ar1\n", \ - "9: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 8b,9b\n") - -#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_8x_cont(to, from, ret, \ - " GETD D1Ar1,[%1++]\n" \ - "6: SETD [%0++],D1Ar1\n" COPY, \ - "7: ADD %2,%2,#4\n" \ - " SETD [%0++],D1Ar1\n" FIXUP, \ - " .long 6b,7b\n" TENTRY) - -#define __asm_copy_from_user_12(to, from, ret) \ - __asm_copy_from_user_12x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_13(to, from, ret) \ - __asm_copy_from_user_12x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "8: SETB [%0++],D1Ar1\n", \ - "9: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 8b,9b\n") - -#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_12x_cont(to, from, ret, \ - " GETW D1Ar1,[%1++]\n" \ - "8: SETW [%0++],D1Ar1\n" COPY, \ - "9: ADD %2,%2,#2\n" \ - " SETW [%0++],D1Ar1\n" FIXUP, \ - " .long 8b,9b\n" TENTRY) - -#define __asm_copy_from_user_14(to, from, ret) \ - __asm_copy_from_user_14x_cont(to, from, ret, "", "", "") - -#define __asm_copy_from_user_15(to, from, ret) \ - __asm_copy_from_user_14x_cont(to, from, ret, \ - " GETB D1Ar1,[%1++]\n" \ - "10: SETB [%0++],D1Ar1\n", \ - "11: ADD %2,%2,#1\n" \ - " SETB [%0++],D1Ar1\n", \ - " .long 10b,11b\n") - -#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \ - __asm_copy_from_user_12x_cont(to, from, ret, \ - " GETD D1Ar1,[%1++]\n" \ - "8: SETD [%0++],D1Ar1\n" COPY, \ - "9: ADD %2,%2,#4\n" \ - " SETD [%0++],D1Ar1\n" FIXUP, \ - " .long 8b,9b\n" TENTRY) - -#define __asm_copy_from_user_16(to, from, ret) \ - __asm_copy_from_user_16x_cont(to, from, ret, "", "", "") - #define __asm_copy_from_user_8x64(to, from, ret) \ asm volatile ( \ " GETL D0Ar2,D1Ar1,[%1++]\n" \ "2: SETL [%0++],D0Ar2,D1Ar1\n" \ "1:\n" \ " .section .fixup,\"ax\"\n" \ - " MOV D1Ar1,#0\n" \ - " MOV D0Ar2,#0\n" \ "3: ADD %2,%2,#8\n" \ - " SETL [%0++],D0Ar2,D1Ar1\n" \ " MOVT D0Ar2,#HI(1b)\n" \ " JUMP D0Ar2,#LO(1b)\n" \ " .previous\n" \ @@ -789,36 +711,57 @@ EXPORT_SYMBOL(__copy_user); * * Rationale: * A fault occurs while reading from user buffer, which is the - * source. Since the fault is at a single address, we only - * need to rewind by 8 bytes. + * source. * Since we don't write to kernel buffer until we read first, * the kernel buffer is at the right state and needn't be - * corrected. + * corrected, but the source must be rewound to the beginning of + * the block, which is LSM_STEP*8 bytes. + * LSM_STEP is bits 10:8 in TXSTATUS which is already read + * and stored in D0Ar2 + * + * NOTE: If a fault occurs at the last operation in M{G,S}ETL + * LSM_STEP will be 0. ie: we do 4 writes in our case, if + * a fault happens at the 4th write, LSM_STEP will be 0 + * instead of 4. The code copes with that. */ #define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id) \ __asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \ - "SUB %1, %1, #8\n") + "LSR D0Ar2, D0Ar2, #5\n" \ + "ANDS D0Ar2, D0Ar2, #0x38\n" \ + "ADDZ D0Ar2, D0Ar2, #32\n" \ + "SUB %1, %1, D0Ar2\n") /* rewind 'from' pointer when a fault occurs * * Rationale: * A fault occurs while reading from user buffer, which is the - * source. Since the fault is at a single address, we only - * need to rewind by 4 bytes. + * source. * Since we don't write to kernel buffer until we read first, * the kernel buffer is at the right state and needn't be - * corrected. + * corrected, but the source must be rewound to the beginning of + * the block, which is LSM_STEP*4 bytes. + * LSM_STEP is bits 10:8 in TXSTATUS which is already read + * and stored in D0Ar2 + * + * NOTE: If a fault occurs at the last operation in M{G,S}ETL + * LSM_STEP will be 0. ie: we do 4 writes in our case, if + * a fault happens at the 4th write, LSM_STEP will be 0 + * instead of 4. The code copes with that. */ #define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id) \ __asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \ - "SUB %1, %1, #4\n") + "LSR D0Ar2, D0Ar2, #6\n" \ + "ANDS D0Ar2, D0Ar2, #0x1c\n" \ + "ADDZ D0Ar2, D0Ar2, #16\n" \ + "SUB %1, %1, D0Ar2\n") -/* Copy from user to kernel, zeroing the bytes that were inaccessible in - userland. The return-value is the number of bytes that were - inaccessible. */ -unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, - unsigned long n) +/* + * Copy from user to kernel. The return-value is the number of bytes that were + * inaccessible. + */ +unsigned long raw_copy_from_user(void *pdst, const void __user *psrc, + unsigned long n) { register char *dst asm ("A0.2") = pdst; register const char __user *src asm ("A1.2") = psrc; @@ -830,6 +773,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, if ((unsigned long) src & 1) { __asm_copy_from_user_1(dst, src, retn); n--; + if (retn) + return retn + n; } if ((unsigned long) dst & 1) { /* Worst case - byte copy */ @@ -837,12 +782,14 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, __asm_copy_from_user_1(dst, src, retn); n--; if (retn) - goto copy_exception_bytes; + return retn + n; } } if (((unsigned long) src & 2) && n >= 2) { __asm_copy_from_user_2(dst, src, retn); n -= 2; + if (retn) + return retn + n; } if ((unsigned long) dst & 2) { /* Second worst case - word copy */ @@ -850,16 +797,10 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, __asm_copy_from_user_2(dst, src, retn); n -= 2; if (retn) - goto copy_exception_bytes; + return retn + n; } } - /* We only need one check after the unalignment-adjustments, - because if both adjustments were done, either both or - neither reference had an exception. */ - if (retn != 0) - goto copy_exception_bytes; - #ifdef USE_RAPF /* 64 bit copy loop */ if (!(((unsigned long) src | (unsigned long) dst) & 7)) { @@ -872,7 +813,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, __asm_copy_from_user_8x64(dst, src, retn); n -= 8; if (retn) - goto copy_exception_bytes; + return retn + n; } } @@ -888,7 +829,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, __asm_copy_from_user_8x64(dst, src, retn); n -= 8; if (retn) - goto copy_exception_bytes; + return retn + n; } } #endif @@ -898,7 +839,7 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, n -= 4; if (retn) - goto copy_exception_bytes; + return retn + n; } /* If we get here, there were no memory read faults. */ @@ -924,21 +865,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc, /* If we get here, retn correctly reflects the number of failing bytes. */ return retn; - - copy_exception_bytes: - /* We already have "retn" bytes cleared, and need to clear the - remaining "n" bytes. A non-optimized simple byte-for-byte in-line - memset is preferred here, since this isn't speed-critical code and - we'd rather have this a leaf-function than calling memset. */ - { - char *endp; - for (endp = dst + n; dst < endp; dst++) - *dst = 0; - } - - return retn + n; } -EXPORT_SYMBOL(__copy_user_zeroing); +EXPORT_SYMBOL(raw_copy_from_user); #define __asm_clear_8x64(to, ret) \ asm volatile ( \ diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index 1732ec13b211..56830ff65333 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -3,6 +3,7 @@ generic-y += barrier.h generic-y += clkdev.h generic-y += device.h generic-y += exec.h +generic-y += extable.h generic-y += irq_work.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h index 253a67e275ad..38f2c9ccef10 100644 --- a/arch/microblaze/include/asm/uaccess.h +++ b/arch/microblaze/include/asm/uaccess.h @@ -11,22 +11,15 @@ #ifndef _ASM_MICROBLAZE_UACCESS_H #define _ASM_MICROBLAZE_UACCESS_H -#ifdef __KERNEL__ -#ifndef __ASSEMBLY__ - #include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/sched.h> /* RLIMIT_FSIZE */ #include <linux/mm.h> #include <asm/mmu.h> #include <asm/page.h> #include <asm/pgtable.h> +#include <asm/extable.h> #include <linux/string.h> -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - /* * On Microblaze the fs value is actually the top of the corresponding * address space. @@ -55,22 +48,6 @@ # define segment_eq(a, b) ((a).seg == (b).seg) -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ -struct exception_table_entry { - unsigned long insn, fixup; -}; - #ifndef CONFIG_MMU /* Check against bounds of physical memory */ @@ -359,39 +336,19 @@ extern long __user_bad(void); __gu_err; \ }) - -/* copy_to_from_user */ -#define __copy_from_user(to, from, n) \ - __copy_tofrom_user((__force void __user *)(to), \ - (void __user *)(from), (n)) -#define __copy_from_user_inatomic(to, from, n) \ - __copy_from_user((to), (from), (n)) - -static inline long copy_from_user(void *to, - const void __user *from, unsigned long n) +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - unsigned long res = n; - might_fault(); - if (likely(access_ok(VERIFY_READ, from, n))) - res = __copy_from_user(to, from, n); - if (unlikely(res)) - memset(to + (n - res), 0, res); - return res; + return __copy_tofrom_user((__force void __user *)to, from, n); } -#define __copy_to_user(to, from, n) \ - __copy_tofrom_user((void __user *)(to), \ - (__force const void __user *)(from), (n)) -#define __copy_to_user_inatomic(to, from, n) __copy_to_user((to), (from), (n)) - -static inline long copy_to_user(void __user *to, - const void *from, unsigned long n) +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - might_fault(); - if (access_ok(VERIFY_WRITE, to, n)) - return __copy_to_user(to, from, n); - return n; + return __copy_tofrom_user(to, (__force const void __user *)from, n); } +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER /* * Copy a null terminated string from userspace. @@ -422,7 +379,4 @@ static inline long strnlen_user(const char __user *src, long n) return __strnlen_user(src, n); } -#endif /* __ASSEMBLY__ */ -#endif /* __KERNEL__ */ - #endif /* _ASM_MICROBLAZE_UACCESS_H */ diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a008a9f03072..d6d545a45118 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -68,7 +68,6 @@ config MIPS select HANDLE_DOMAIN_IRQ select HAVE_EXIT_THREAD select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_ARCH_HARDENED_USERCOPY menu "Machine selection" @@ -1531,7 +1530,7 @@ config CPU_MIPS64_R6 select CPU_SUPPORTS_HIGHMEM select CPU_SUPPORTS_MSA select GENERIC_CSUM - select MIPS_O32_FP64_SUPPORT if MIPS32_O32 + select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32 select HAVE_KVM help Choose this option to build a kernel for release 6 or later of the diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 8ef9c02747fa..02a1787c888c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -489,7 +489,7 @@ $(generic_defconfigs): $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \ -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ \ $(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config) - $(Q)$(MAKE) olddefconfig + $(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig # # Prevent generic merge_config rules attempting to merge single fragments @@ -503,8 +503,8 @@ $(generic_config_dir)/%.config: ; # .PHONY: sead3_defconfig sead3_defconfig: - $(Q)$(MAKE) 32r2el_defconfig BOARDS=sead-3 + $(Q)$(MAKE) -f $(srctree)/Makefile 32r2el_defconfig BOARDS=sead-3 .PHONY: sead3micro_defconfig sead3micro_defconfig: - $(Q)$(MAKE) micro32r2el_defconfig BOARDS=sead-3 + $(Q)$(MAKE) -f $(srctree)/Makefile micro32r2el_defconfig BOARDS=sead-3 diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c index e1bec5a77c39..32d1333bb243 100644 --- a/arch/mips/alchemy/common/time.c +++ b/arch/mips/alchemy/common/time.c @@ -138,7 +138,9 @@ static int __init alchemy_time_init(unsigned int m2int) cd->shift = 32; cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift); cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(9, cd); /* ~0.28ms */ + cd->max_delta_ticks = 0xffffffff; + cd->min_delta_ns = clockevent_delta2ns(9, cd); + cd->min_delta_ticks = 9; /* ~0.28ms */ clockevents_register_device(cd); setup_irq(m2int, &au1x_rtcmatch2_irqaction); diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S index cfd97f6448bb..0a7c9834b81c 100644 --- a/arch/mips/cavium-octeon/octeon-memcpy.S +++ b/arch/mips/cavium-octeon/octeon-memcpy.S @@ -140,15 +140,6 @@ .set noat /* - * t7 is used as a flag to note inatomic mode. - */ -LEAF(__copy_user_inatomic) -EXPORT_SYMBOL(__copy_user_inatomic) - b __copy_user_common - li t7, 1 - END(__copy_user_inatomic) - -/* * A combined memcpy/__copy_user * __copy_user sets len to 0 for success; else to an upper bound of * the number of uncopied bytes. @@ -161,8 +152,6 @@ EXPORT_SYMBOL(memcpy) __memcpy: FEXPORT(__copy_user) EXPORT_SYMBOL(__copy_user) - li t7, 0 /* not inatomic */ -__copy_user_common: /* * Note: dst & src may be unaligned, len may be 0 * Temps @@ -414,25 +403,7 @@ l_exc: LOAD t0, TI_TASK($28) LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address SUB len, AT, t0 # len number of uncopied bytes - bnez t7, 2f /* Skip the zeroing out part if inatomic */ - /* - * Here's where we rely on src and dst being incremented in tandem, - * See (3) above. - * dst += (fault addr - src) to put dst at first byte to clear - */ - ADD dst, t0 # compute start address in a1 - SUB dst, src - /* - * Clear len bytes starting at dst. Can't call __bzero because it - * might modify len. An inefficient loop for these rare times... - */ - beqz len, done - SUB src, len, 1 -1: sb zero, 0(dst) - ADD dst, dst, 1 - bnez src, 1b - SUB src, src, 1 -2: jr ra + jr ra nop diff --git a/arch/mips/include/asm/asm-prototypes.h b/arch/mips/include/asm/asm-prototypes.h index a160cf69bb92..6e28971fe73a 100644 --- a/arch/mips/include/asm/asm-prototypes.h +++ b/arch/mips/include/asm/asm-prototypes.h @@ -3,3 +3,4 @@ #include <asm/fpu.h> #include <asm-generic/asm-prototypes.h> #include <asm/uaccess.h> +#include <asm/ftrace.h> diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h index c8b574f7e0cc..77cad232a1c6 100644 --- a/arch/mips/include/asm/checksum.h +++ b/arch/mips/include/asm/checksum.h @@ -50,7 +50,7 @@ __wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr) { might_fault(); - if (segment_eq(get_fs(), get_ds())) + if (uaccess_kernel()) return __csum_partial_copy_kernel((__force void *)src, dst, len, sum, err_ptr); else @@ -82,7 +82,7 @@ __wsum csum_and_copy_to_user(const void *src, void __user *dst, int len, { might_fault(); if (access_ok(VERIFY_WRITE, dst, len)) { - if (segment_eq(get_fs(), get_ds())) + if (uaccess_kernel()) return __csum_partial_copy_kernel(src, (__force void *)dst, len, sum, err_ptr); diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index f94455f964ec..a2813fe381cf 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h @@ -21,6 +21,7 @@ #include <asm/cpu-features.h> #include <asm/fpu_emulator.h> #include <asm/hazards.h> +#include <asm/ptrace.h> #include <asm/processor.h> #include <asm/current.h> #include <asm/msa.h> diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 956db6e201d1..ddd1c918103b 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -18,9 +18,24 @@ #include <irq.h> #define IRQ_STACK_SIZE THREAD_SIZE +#define IRQ_STACK_START (IRQ_STACK_SIZE - sizeof(unsigned long)) extern void *irq_stack[NR_CPUS]; +/* + * The highest address on the IRQ stack contains a dummy frame put down in + * genex.S (handle_int & except_vec_vi_handler) which is structured as follows: + * + * top ------------ + * | task sp | <- irq_stack[cpu] + IRQ_STACK_START + * ------------ + * | | <- First frame of IRQ context + * ------------ + * + * task sp holds a copy of the task stack pointer where the struct pt_regs + * from exception entry can be found. + */ + static inline bool on_irq_stack(int cpu, unsigned long sp) { unsigned long low = (unsigned long)irq_stack[cpu]; diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index 55fd94e6cd0b..7f12d7e27c94 100644 --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h @@ -20,7 +20,7 @@ #include <asm/cpu-features.h> #include <asm/cpu-type.h> #include <asm/mipsmtregs.h> -#include <linux/uaccess.h> /* for segment_eq() */ +#include <linux/uaccess.h> /* for uaccess_kernel() */ extern void (*r4k_blast_dcache)(void); extern void (*r4k_blast_icache)(void); @@ -714,7 +714,7 @@ static inline void protected_blast_##pfx##cache##_range(unsigned long start,\ \ __##pfx##flush_prologue \ \ - if (segment_eq(get_fs(), USER_DS)) { \ + if (!uaccess_kernel()) { \ while (1) { \ protected_cachee_op(hitop, addr); \ if (addr == aend) \ diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index f485afe51514..a8df44d60607 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -127,7 +127,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) " andi %[ticket], %[ticket], 0xffff \n" " bne %[ticket], %[my_ticket], 4f \n" " subu %[ticket], %[my_ticket], %[ticket] \n" - "2: \n" + "2: .insn \n" " .subsection 2 \n" "4: andi %[ticket], %[ticket], 0xffff \n" " sll %[ticket], 5 \n" @@ -202,7 +202,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) " sc %[ticket], %[ticket_ptr] \n" " beqz %[ticket], 1b \n" " li %[ticket], 1 \n" - "2: \n" + "2: .insn \n" " .subsection 2 \n" "3: b 2b \n" " li %[ticket], 0 \n" @@ -382,7 +382,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) " .set reorder \n" __WEAK_LLSC_MB " li %2, 1 \n" - "2: \n" + "2: .insn \n" : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) : GCC_OFF_SMALL_ASM() (rw->lock) : "memory"); @@ -422,7 +422,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) " lui %1, 0x8000 \n" " sc %1, %0 \n" " li %2, 1 \n" - "2: \n" + "2: .insn \n" : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) : GCC_OFF_SMALL_ASM() (rw->lock) diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 5347cfe15af2..99e629a590a5 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -12,8 +12,6 @@ #define _ASM_UACCESS_H #include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/thread_info.h> #include <linux/string.h> #include <asm/asm-eva.h> #include <asm/extable.h> @@ -71,9 +69,6 @@ extern u64 __ua_limit; #define USER_DS ((mm_segment_t) { __UA_LIMIT }) #endif -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - #define get_ds() (KERNEL_DS) #define get_fs() (current_thread_info()->addr_limit) #define set_fs(x) (current_thread_info()->addr_limit = (x)) @@ -93,7 +88,7 @@ static inline bool eva_kernel_access(void) if (!IS_ENABLED(CONFIG_EVA)) return false; - return segment_eq(get_fs(), get_ds()); + return uaccess_kernel(); } /* @@ -133,23 +128,14 @@ static inline bool eva_kernel_access(void) * this function, memory access functions may still return -EFAULT. */ -#define __access_mask get_fs().seg - -#define __access_ok(addr, size, mask) \ -({ \ - unsigned long __addr = (unsigned long) (addr); \ - unsigned long __size = size; \ - unsigned long __mask = mask; \ - unsigned long __ok; \ - \ - __chk_user_ptr(addr); \ - __ok = (signed long)(__mask & (__addr | (__addr + __size) | \ - __ua_size(__size))); \ - __ok == 0; \ -}) +static inline int __access_ok(const void __user *p, unsigned long size) +{ + unsigned long addr = (unsigned long)p; + return (get_fs().seg & (addr | (addr + size) | __ua_size(size))) == 0; +} #define access_ok(type, addr, size) \ - likely(__access_ok((addr), (size), __access_mask)) + likely(__access_ok((addr), (size))) /* * put_user: - Write a simple value into user space. @@ -811,157 +797,7 @@ extern void __put_user_unaligned_unknown(void); extern size_t __copy_user(void *__to, const void *__from, size_t __n); -#ifndef CONFIG_EVA -#define __invoke_copy_to_user(to, from, n) \ -({ \ - register void __user *__cu_to_r __asm__("$4"); \ - register const void *__cu_from_r __asm__("$5"); \ - register long __cu_len_r __asm__("$6"); \ - \ - __cu_to_r = (to); \ - __cu_from_r = (from); \ - __cu_len_r = (n); \ - __asm__ __volatile__( \ - __MODULE_JAL(__copy_user) \ - : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ - : \ - : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \ - DADDI_SCRATCH, "memory"); \ - __cu_len_r; \ -}) - -#define __invoke_copy_to_kernel(to, from, n) \ - __invoke_copy_to_user(to, from, n) - -#endif - -/* - * __copy_to_user: - Copy a block of data into user space, with less checking. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from kernel space to user space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - */ -#define __copy_to_user(to, from, n) \ -({ \ - void __user *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - \ - check_object_size(__cu_from, __cu_len, true); \ - might_fault(); \ - \ - if (eva_kernel_access()) \ - __cu_len = __invoke_copy_to_kernel(__cu_to, __cu_from, \ - __cu_len); \ - else \ - __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, \ - __cu_len); \ - __cu_len; \ -}) - -extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); - -#define __copy_to_user_inatomic(to, from, n) \ -({ \ - void __user *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - \ - check_object_size(__cu_from, __cu_len, true); \ - \ - if (eva_kernel_access()) \ - __cu_len = __invoke_copy_to_kernel(__cu_to, __cu_from, \ - __cu_len); \ - else \ - __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, \ - __cu_len); \ - __cu_len; \ -}) - -#define __copy_from_user_inatomic(to, from, n) \ -({ \ - void *__cu_to; \ - const void __user *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - \ - check_object_size(__cu_to, __cu_len, false); \ - \ - if (eva_kernel_access()) \ - __cu_len = __invoke_copy_from_kernel_inatomic(__cu_to, \ - __cu_from,\ - __cu_len);\ - else \ - __cu_len = __invoke_copy_from_user_inatomic(__cu_to, \ - __cu_from, \ - __cu_len); \ - __cu_len; \ -}) - -/* - * copy_to_user: - Copy a block of data into user space. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from kernel space to user space. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - */ -#define copy_to_user(to, from, n) \ -({ \ - void __user *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - \ - check_object_size(__cu_from, __cu_len, true); \ - \ - if (eva_kernel_access()) { \ - __cu_len = __invoke_copy_to_kernel(__cu_to, \ - __cu_from, \ - __cu_len); \ - } else { \ - if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) { \ - might_fault(); \ - __cu_len = __invoke_copy_to_user(__cu_to, \ - __cu_from, \ - __cu_len); \ - } \ - } \ - __cu_len; \ -}) - -#ifndef CONFIG_EVA - -#define __invoke_copy_from_user(to, from, n) \ +#define __invoke_copy_from(func, to, from, n) \ ({ \ register void *__cu_to_r __asm__("$4"); \ register const void __user *__cu_from_r __asm__("$5"); \ @@ -972,7 +808,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_len_r = (n); \ __asm__ __volatile__( \ ".set\tnoreorder\n\t" \ - __MODULE_JAL(__copy_user) \ + __MODULE_JAL(func) \ ".set\tnoat\n\t" \ __UA_ADDU "\t$1, %1, %2\n\t" \ ".set\tat\n\t" \ @@ -984,33 +820,17 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_len_r; \ }) -#define __invoke_copy_from_kernel(to, from, n) \ - __invoke_copy_from_user(to, from, n) - -/* For userland <-> userland operations */ -#define ___invoke_copy_in_user(to, from, n) \ - __invoke_copy_from_user(to, from, n) - -/* For kernel <-> kernel operations */ -#define ___invoke_copy_in_kernel(to, from, n) \ - __invoke_copy_from_user(to, from, n) - -#define __invoke_copy_from_user_inatomic(to, from, n) \ +#define __invoke_copy_to(func, to, from, n) \ ({ \ - register void *__cu_to_r __asm__("$4"); \ - register const void __user *__cu_from_r __asm__("$5"); \ + register void __user *__cu_to_r __asm__("$4"); \ + register const void *__cu_from_r __asm__("$5"); \ register long __cu_len_r __asm__("$6"); \ \ __cu_to_r = (to); \ __cu_from_r = (from); \ __cu_len_r = (n); \ __asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - __MODULE_JAL(__copy_user_inatomic) \ - ".set\tnoat\n\t" \ - __UA_ADDU "\t$1, %1, %2\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ + __MODULE_JAL(func) \ : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ : \ : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \ @@ -1018,228 +838,79 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_len_r; \ }) -#define __invoke_copy_from_kernel_inatomic(to, from, n) \ - __invoke_copy_from_user_inatomic(to, from, n) \ +#define __invoke_copy_from_kernel(to, from, n) \ + __invoke_copy_from(__copy_user, to, from, n) + +#define __invoke_copy_to_kernel(to, from, n) \ + __invoke_copy_to(__copy_user, to, from, n) + +#define ___invoke_copy_in_kernel(to, from, n) \ + __invoke_copy_from(__copy_user, to, from, n) + +#ifndef CONFIG_EVA +#define __invoke_copy_from_user(to, from, n) \ + __invoke_copy_from(__copy_user, to, from, n) + +#define __invoke_copy_to_user(to, from, n) \ + __invoke_copy_to(__copy_user, to, from, n) + +#define ___invoke_copy_in_user(to, from, n) \ + __invoke_copy_from(__copy_user, to, from, n) #else /* EVA specific functions */ -extern size_t __copy_user_inatomic_eva(void *__to, const void *__from, - size_t __n); extern size_t __copy_from_user_eva(void *__to, const void *__from, size_t __n); extern size_t __copy_to_user_eva(void *__to, const void *__from, size_t __n); extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n); -#define __invoke_copy_from_user_eva_generic(to, from, n, func_ptr) \ -({ \ - register void *__cu_to_r __asm__("$4"); \ - register const void __user *__cu_from_r __asm__("$5"); \ - register long __cu_len_r __asm__("$6"); \ - \ - __cu_to_r = (to); \ - __cu_from_r = (from); \ - __cu_len_r = (n); \ - __asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - __MODULE_JAL(func_ptr) \ - ".set\tnoat\n\t" \ - __UA_ADDU "\t$1, %1, %2\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ - : \ - : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \ - DADDI_SCRATCH, "memory"); \ - __cu_len_r; \ -}) - -#define __invoke_copy_to_user_eva_generic(to, from, n, func_ptr) \ -({ \ - register void *__cu_to_r __asm__("$4"); \ - register const void __user *__cu_from_r __asm__("$5"); \ - register long __cu_len_r __asm__("$6"); \ - \ - __cu_to_r = (to); \ - __cu_from_r = (from); \ - __cu_len_r = (n); \ - __asm__ __volatile__( \ - __MODULE_JAL(func_ptr) \ - : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ - : \ - : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \ - DADDI_SCRATCH, "memory"); \ - __cu_len_r; \ -}) - /* * Source or destination address is in userland. We need to go through * the TLB */ #define __invoke_copy_from_user(to, from, n) \ - __invoke_copy_from_user_eva_generic(to, from, n, __copy_from_user_eva) - -#define __invoke_copy_from_user_inatomic(to, from, n) \ - __invoke_copy_from_user_eva_generic(to, from, n, \ - __copy_user_inatomic_eva) + __invoke_copy_from(__copy_from_user_eva, to, from, n) #define __invoke_copy_to_user(to, from, n) \ - __invoke_copy_to_user_eva_generic(to, from, n, __copy_to_user_eva) + __invoke_copy_to(__copy_to_user_eva, to, from, n) #define ___invoke_copy_in_user(to, from, n) \ - __invoke_copy_from_user_eva_generic(to, from, n, __copy_in_user_eva) - -/* - * Source or destination address in the kernel. We are not going through - * the TLB - */ -#define __invoke_copy_from_kernel(to, from, n) \ - __invoke_copy_from_user_eva_generic(to, from, n, __copy_user) - -#define __invoke_copy_from_kernel_inatomic(to, from, n) \ - __invoke_copy_from_user_eva_generic(to, from, n, __copy_user_inatomic) - -#define __invoke_copy_to_kernel(to, from, n) \ - __invoke_copy_to_user_eva_generic(to, from, n, __copy_user) - -#define ___invoke_copy_in_kernel(to, from, n) \ - __invoke_copy_from_user_eva_generic(to, from, n, __copy_user) + __invoke_copy_from(__copy_in_user_eva, to, from, n) #endif /* CONFIG_EVA */ -/* - * __copy_from_user: - Copy a block of data from user space, with less checking. - * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from user space to kernel space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - */ -#define __copy_from_user(to, from, n) \ -({ \ - void *__cu_to; \ - const void __user *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - \ - check_object_size(__cu_to, __cu_len, false); \ - \ - if (eva_kernel_access()) { \ - __cu_len = __invoke_copy_from_kernel(__cu_to, \ - __cu_from, \ - __cu_len); \ - } else { \ - might_fault(); \ - __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \ - __cu_len); \ - } \ - __cu_len; \ -}) +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + if (eva_kernel_access()) + return __invoke_copy_to_kernel(to, from, n); + else + return __invoke_copy_to_user(to, from, n); +} -/* - * copy_from_user: - Copy a block of data from user space. - * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from user space to kernel space. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - */ -#define copy_from_user(to, from, n) \ -({ \ - void *__cu_to; \ - const void __user *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - \ - check_object_size(__cu_to, __cu_len, false); \ - \ - if (eva_kernel_access()) { \ - __cu_len = __invoke_copy_from_kernel(__cu_to, \ - __cu_from, \ - __cu_len); \ - } else { \ - if (access_ok(VERIFY_READ, __cu_from, __cu_len)) { \ - might_fault(); \ - __cu_len = __invoke_copy_from_user(__cu_to, \ - __cu_from, \ - __cu_len); \ - } else { \ - memset(__cu_to, 0, __cu_len); \ - } \ - } \ - __cu_len; \ -}) +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + if (eva_kernel_access()) + return __invoke_copy_from_kernel(to, from, n); + else + return __invoke_copy_from_user(to, from, n); +} -#define __copy_in_user(to, from, n) \ -({ \ - void __user *__cu_to; \ - const void __user *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - if (eva_kernel_access()) { \ - __cu_len = ___invoke_copy_in_kernel(__cu_to, __cu_from, \ - __cu_len); \ - } else { \ - might_fault(); \ - __cu_len = ___invoke_copy_in_user(__cu_to, __cu_from, \ - __cu_len); \ - } \ - __cu_len; \ -}) +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER -#define copy_in_user(to, from, n) \ -({ \ - void __user *__cu_to; \ - const void __user *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - if (eva_kernel_access()) { \ - __cu_len = ___invoke_copy_in_kernel(__cu_to,__cu_from, \ - __cu_len); \ - } else { \ - if (likely(access_ok(VERIFY_READ, __cu_from, __cu_len) &&\ - access_ok(VERIFY_WRITE, __cu_to, __cu_len))) {\ - might_fault(); \ - __cu_len = ___invoke_copy_in_user(__cu_to, \ - __cu_from, \ - __cu_len); \ - } \ - } \ - __cu_len; \ -}) +static inline unsigned long +raw_copy_in_user(void __user*to, const void __user *from, unsigned long n) +{ + if (eva_kernel_access()) + return ___invoke_copy_in_kernel(to, from, n); + else + return ___invoke_copy_in_user(to, from, n); +} extern __kernel_size_t __bzero_kernel(void __user *addr, __kernel_size_t size); extern __kernel_size_t __bzero(void __user *addr, __kernel_size_t size); diff --git a/arch/mips/include/uapi/asm/unistd.h b/arch/mips/include/uapi/asm/unistd.h index 3e940dbe0262..78faf4292e90 100644 --- a/arch/mips/include/uapi/asm/unistd.h +++ b/arch/mips/include/uapi/asm/unistd.h @@ -386,17 +386,18 @@ #define __NR_pkey_mprotect (__NR_Linux + 363) #define __NR_pkey_alloc (__NR_Linux + 364) #define __NR_pkey_free (__NR_Linux + 365) +#define __NR_statx (__NR_Linux + 366) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 365 +#define __NR_Linux_syscalls 366 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 365 +#define __NR_O32_Linux_syscalls 366 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -730,16 +731,17 @@ #define __NR_pkey_mprotect (__NR_Linux + 323) #define __NR_pkey_alloc (__NR_Linux + 324) #define __NR_pkey_free (__NR_Linux + 325) +#define __NR_statx (__NR_Linux + 326) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 325 +#define __NR_Linux_syscalls 326 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 325 +#define __NR_64_Linux_syscalls 326 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -1077,15 +1079,16 @@ #define __NR_pkey_mprotect (__NR_Linux + 327) #define __NR_pkey_alloc (__NR_Linux + 328) #define __NR_pkey_free (__NR_Linux + 329) +#define __NR_statx (__NR_Linux + 330) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 329 +#define __NR_Linux_syscalls 330 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 329 +#define __NR_N32_Linux_syscalls 330 #endif /* _UAPI_ASM_UNISTD_H */ diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c index bcf8f8c62737..bb1ad5119da4 100644 --- a/arch/mips/jz4740/time.c +++ b/arch/mips/jz4740/time.c @@ -145,7 +145,9 @@ void __init plat_time_init(void) clockevent_set_clock(&jz4740_clockevent, clk_rate); jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent); + jz4740_clockevent.min_delta_ticks = 100; jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent); + jz4740_clockevent.max_delta_ticks = 0xffff; jz4740_clockevent.cpumask = cpumask_of(0); clockevents_register_device(&jz4740_clockevent); diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index bb5c5d34ba81..a670c0c11875 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -102,6 +102,7 @@ void output_thread_info_defines(void) DEFINE(_THREAD_SIZE, THREAD_SIZE); DEFINE(_THREAD_MASK, THREAD_MASK); DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE); + DEFINE(_IRQ_STACK_START, IRQ_STACK_START); BLANK(); } diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c index 940ac00e9129..8f9f2daf06a3 100644 --- a/arch/mips/kernel/cevt-bcm1480.c +++ b/arch/mips/kernel/cevt-bcm1480.c @@ -123,7 +123,9 @@ void sb1480_clockevent_init(void) CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, V_SCD_TIMER_FREQ); cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); + cd->max_delta_ticks = 0x7fffff; cd->min_delta_ns = clockevent_delta2ns(2, cd); + cd->min_delta_ticks = 2; cd->rating = 200; cd->irq = irq; cd->cpumask = cpumask_of(cpu); diff --git a/arch/mips/kernel/cevt-ds1287.c b/arch/mips/kernel/cevt-ds1287.c index 77a5ddf53f57..61ad9079fa16 100644 --- a/arch/mips/kernel/cevt-ds1287.c +++ b/arch/mips/kernel/cevt-ds1287.c @@ -128,7 +128,9 @@ int __init ds1287_clockevent_init(int irq) cd->irq = irq; clockevent_set_clock(cd, 32768); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->max_delta_ticks = 0x7fffffff; cd->min_delta_ns = clockevent_delta2ns(0x300, cd); + cd->min_delta_ticks = 0x300; cd->cpumask = cpumask_of(0); clockevents_register_device(&ds1287_clockevent); diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c index 66040051151d..fd90c82dc17d 100644 --- a/arch/mips/kernel/cevt-gt641xx.c +++ b/arch/mips/kernel/cevt-gt641xx.c @@ -152,7 +152,9 @@ static int __init gt641xx_timer0_clockevent_init(void) cd->rating = 200 + gt641xx_base_clock / 10000000; clockevent_set_clock(cd, gt641xx_base_clock); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->max_delta_ticks = 0x7fffffff; cd->min_delta_ns = clockevent_delta2ns(0x300, cd); + cd->min_delta_ticks = 0x300; cd->cpumask = cpumask_of(0); clockevents_register_device(>641xx_timer0_clockevent); diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 804d2a2a19fe..dd6a18bc10ab 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -80,7 +80,7 @@ static unsigned int calculate_min_delta(void) } /* Sorted insert of 75th percentile into buf2 */ - for (k = 0; k < i; ++k) { + for (k = 0; k < i && k < ARRAY_SIZE(buf2); ++k) { if (buf1[ARRAY_SIZE(buf1) - 1] < buf2[k]) { l = min_t(unsigned int, i, ARRAY_SIZE(buf2) - 1); diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c index 3d860efd63b9..9d1edb5938b8 100644 --- a/arch/mips/kernel/cevt-sb1250.c +++ b/arch/mips/kernel/cevt-sb1250.c @@ -123,7 +123,9 @@ void sb1250_clockevent_init(void) CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, V_SCD_TIMER_FREQ); cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); + cd->max_delta_ticks = 0x7fffff; cd->min_delta_ns = clockevent_delta2ns(2, cd); + cd->min_delta_ticks = 2; cd->rating = 200; cd->irq = irq; cd->cpumask = cpumask_of(cpu); diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c index aaca60d6ffc3..7b17c8f5009d 100644 --- a/arch/mips/kernel/cevt-txx9.c +++ b/arch/mips/kernel/cevt-txx9.c @@ -196,7 +196,9 @@ void __init txx9_clockevent_init(unsigned long baseaddr, int irq, clockevent_set_clock(cd, TIMER_CLK(imbusclk)); cd->max_delta_ns = clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd); + cd->max_delta_ticks = 0xffffffff >> (32 - TXX9_TIMER_BITS); cd->min_delta_ns = clockevent_delta2ns(0xf, cd); + cd->min_delta_ticks = 0xf; cd->irq = irq; cd->cpumask = cpumask_of(0), clockevents_register_device(cd); diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S index 59476a607add..a00e87b0256d 100644 --- a/arch/mips/kernel/cps-vec.S +++ b/arch/mips/kernel/cps-vec.S @@ -361,7 +361,7 @@ LEAF(mips_cps_get_bootcfg) END(mips_cps_get_bootcfg) LEAF(mips_cps_boot_vpes) - PTR_L ta2, COREBOOTCFG_VPEMASK(a0) + lw ta2, COREBOOTCFG_VPEMASK(a0) PTR_L ta3, COREBOOTCFG_VPECONFIG(a0) #if defined(CONFIG_CPU_MIPSR6) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 07718bb5fc9d..12422fd4af23 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1824,7 +1824,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) } decode_configs(c); - c->options |= MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; + c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; c->writecombine = _CACHE_UNCACHED_ACCELERATED; break; default: diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index 6430bff21fff..5c429d70e17f 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c @@ -257,7 +257,7 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr, else if ((prog_req.fr1 && prog_req.frdefault) || (prog_req.single && !prog_req.frdefault)) /* Make sure 64-bit MIPS III/IV/64R1 will not pick FR1 */ - state->overall_fp_mode = ((current_cpu_data.fpu_id & MIPS_FPIR_F64) && + state->overall_fp_mode = ((raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) && cpu_has_mips_r2_r6) ? FP_FR1 : FP_FR0; else if (prog_req.fr1) diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 7ec9612cb007..ae810da4d499 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -215,9 +215,11 @@ NESTED(handle_int, PT_SIZE, sp) beq t0, t1, 2f /* Switch to IRQ stack */ - li t1, _IRQ_STACK_SIZE + li t1, _IRQ_STACK_START PTR_ADD sp, t0, t1 + /* Save task's sp on IRQ stack so that unwinding can follow it */ + LONG_S s1, 0(sp) 2: jal plat_irq_dispatch @@ -325,9 +327,11 @@ NESTED(except_vec_vi_handler, 0, sp) beq t0, t1, 2f /* Switch to IRQ stack */ - li t1, _IRQ_STACK_SIZE + li t1, _IRQ_STACK_START PTR_ADD sp, t0, t1 + /* Save task's sp on IRQ stack so that unwinding can follow it */ + LONG_S s1, 0(sp) 2: jalr v0 @@ -519,7 +523,7 @@ NESTED(nmi_handler, PT_SIZE, sp) BUILD_HANDLER reserved reserved sti verbose /* others */ .align 5 - LEAF(handle_ri_rdhwr_vivt) + LEAF(handle_ri_rdhwr_tlbp) .set push .set noat .set noreorder @@ -538,7 +542,7 @@ NESTED(nmi_handler, PT_SIZE, sp) .set pop bltz k1, handle_ri /* slow path */ /* fall thru */ - END(handle_ri_rdhwr_vivt) + END(handle_ri_rdhwr_tlbp) LEAF(handle_ri_rdhwr) .set push diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 1f4bd222ba76..eb6c0d582626 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c @@ -244,9 +244,6 @@ static int compute_signal(int tt) void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) { int reg; - struct thread_info *ti = task_thread_info(p); - unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32; - struct pt_regs *regs = (struct pt_regs *)ksp - 1; #if (KGDB_GDB_REG_SIZE == 32) u32 *ptr = (u32 *)gdb_regs; #else @@ -254,25 +251,46 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) #endif for (reg = 0; reg < 16; reg++) - *(ptr++) = regs->regs[reg]; + *(ptr++) = 0; /* S0 - S7 */ - for (reg = 16; reg < 24; reg++) - *(ptr++) = regs->regs[reg]; + *(ptr++) = p->thread.reg16; + *(ptr++) = p->thread.reg17; + *(ptr++) = p->thread.reg18; + *(ptr++) = p->thread.reg19; + *(ptr++) = p->thread.reg20; + *(ptr++) = p->thread.reg21; + *(ptr++) = p->thread.reg22; + *(ptr++) = p->thread.reg23; for (reg = 24; reg < 28; reg++) *(ptr++) = 0; /* GP, SP, FP, RA */ - for (reg = 28; reg < 32; reg++) - *(ptr++) = regs->regs[reg]; - - *(ptr++) = regs->cp0_status; - *(ptr++) = regs->lo; - *(ptr++) = regs->hi; - *(ptr++) = regs->cp0_badvaddr; - *(ptr++) = regs->cp0_cause; - *(ptr++) = regs->cp0_epc; + *(ptr++) = (long)p; + *(ptr++) = p->thread.reg29; + *(ptr++) = p->thread.reg30; + *(ptr++) = p->thread.reg31; + + *(ptr++) = p->thread.cp0_status; + + /* lo, hi */ + *(ptr++) = 0; + *(ptr++) = 0; + + /* + * BadVAddr, Cause + * Ideally these would come from the last exception frame up the stack + * but that requires unwinding, otherwise we can't know much for sure. + */ + *(ptr++) = 0; + *(ptr++) = 0; + + /* + * PC + * use return address (RA), i.e. the moment after return from resume() + */ + *(ptr++) = p->thread.reg31; } void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index d8f1cf1ec370..550e7d03090a 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c @@ -1200,7 +1200,7 @@ fpu_emul: case lwl_op: rt = regs->regs[MIPSInst_RT(inst)]; vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst); - if (!access_ok(VERIFY_READ, vaddr, 4)) { + if (!access_ok(VERIFY_READ, (void __user *)vaddr, 4)) { current->thread.cp0_baduaddr = vaddr; err = SIGSEGV; break; @@ -1273,7 +1273,7 @@ fpu_emul: case lwr_op: rt = regs->regs[MIPSInst_RT(inst)]; vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst); - if (!access_ok(VERIFY_READ, vaddr, 4)) { + if (!access_ok(VERIFY_READ, (void __user *)vaddr, 4)) { current->thread.cp0_baduaddr = vaddr; err = SIGSEGV; break; @@ -1347,7 +1347,7 @@ fpu_emul: case swl_op: rt = regs->regs[MIPSInst_RT(inst)]; vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst); - if (!access_ok(VERIFY_WRITE, vaddr, 4)) { + if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 4)) { current->thread.cp0_baduaddr = vaddr; err = SIGSEGV; break; @@ -1417,7 +1417,7 @@ fpu_emul: case swr_op: rt = regs->regs[MIPSInst_RT(inst)]; vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst); - if (!access_ok(VERIFY_WRITE, vaddr, 4)) { + if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 4)) { current->thread.cp0_baduaddr = vaddr; err = SIGSEGV; break; @@ -1492,7 +1492,7 @@ fpu_emul: rt = regs->regs[MIPSInst_RT(inst)]; vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst); - if (!access_ok(VERIFY_READ, vaddr, 8)) { + if (!access_ok(VERIFY_READ, (void __user *)vaddr, 8)) { current->thread.cp0_baduaddr = vaddr; err = SIGSEGV; break; @@ -1611,7 +1611,7 @@ fpu_emul: rt = regs->regs[MIPSInst_RT(inst)]; vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst); - if (!access_ok(VERIFY_READ, vaddr, 8)) { + if (!access_ok(VERIFY_READ, (void __user *)vaddr, 8)) { current->thread.cp0_baduaddr = vaddr; err = SIGSEGV; break; @@ -1730,7 +1730,7 @@ fpu_emul: rt = regs->regs[MIPSInst_RT(inst)]; vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst); - if (!access_ok(VERIFY_WRITE, vaddr, 8)) { + if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 8)) { current->thread.cp0_baduaddr = vaddr; err = SIGSEGV; break; @@ -1848,7 +1848,7 @@ fpu_emul: rt = regs->regs[MIPSInst_RT(inst)]; vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst); - if (!access_ok(VERIFY_WRITE, vaddr, 8)) { + if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 8)) { current->thread.cp0_baduaddr = vaddr; err = SIGSEGV; break; @@ -1965,7 +1965,7 @@ fpu_emul: err = SIGBUS; break; } - if (!access_ok(VERIFY_READ, vaddr, 4)) { + if (!access_ok(VERIFY_READ, (void __user *)vaddr, 4)) { current->thread.cp0_baduaddr = vaddr; err = SIGBUS; break; @@ -2021,7 +2021,7 @@ fpu_emul: err = SIGBUS; break; } - if (!access_ok(VERIFY_WRITE, vaddr, 4)) { + if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 4)) { current->thread.cp0_baduaddr = vaddr; err = SIGBUS; break; @@ -2084,7 +2084,7 @@ fpu_emul: err = SIGBUS; break; } - if (!access_ok(VERIFY_READ, vaddr, 8)) { + if (!access_ok(VERIFY_READ, (void __user *)vaddr, 8)) { current->thread.cp0_baduaddr = vaddr; err = SIGBUS; break; @@ -2145,7 +2145,7 @@ fpu_emul: err = SIGBUS; break; } - if (!access_ok(VERIFY_WRITE, vaddr, 8)) { + if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 8)) { current->thread.cp0_baduaddr = vaddr; err = SIGBUS; break; diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 8c35b3152e1e..9452b02ce079 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -1446,6 +1446,11 @@ static int mipsxx_pmu_handle_shared_irq(void) HANDLE_COUNTER(0) } +#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS + read_unlock(&pmuint_rwlock); +#endif + resume_local_counters(); + /* * Do all the work for the pending perf events. We can do this * in here because the performance counter interrupt is a regular @@ -1454,10 +1459,6 @@ static int mipsxx_pmu_handle_shared_irq(void) if (handled == IRQ_HANDLED) irq_work_run(); -#ifdef CONFIG_MIPS_PERF_SHARED_TC_COUNTERS - read_unlock(&pmuint_rwlock); -#endif - resume_local_counters(); return handled; } diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index fb6b6b650719..b68e10fc453d 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -488,31 +488,52 @@ unsigned long notrace unwind_stack_by_address(unsigned long stack_page, unsigned long pc, unsigned long *ra) { + unsigned long low, high, irq_stack_high; struct mips_frame_info info; unsigned long size, ofs; + struct pt_regs *regs; int leaf; - extern void ret_from_irq(void); - extern void ret_from_exception(void); if (!stack_page) return 0; /* - * If we reached the bottom of interrupt context, - * return saved pc in pt_regs. + * IRQ stacks start at IRQ_STACK_START + * task stacks at THREAD_SIZE - 32 */ - if (pc == (unsigned long)ret_from_irq || - pc == (unsigned long)ret_from_exception) { - struct pt_regs *regs; - if (*sp >= stack_page && - *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { - regs = (struct pt_regs *)*sp; - pc = regs->cp0_epc; - if (!user_mode(regs) && __kernel_text_address(pc)) { - *sp = regs->regs[29]; - *ra = regs->regs[31]; - return pc; - } + low = stack_page; + if (!preemptible() && on_irq_stack(raw_smp_processor_id(), *sp)) { + high = stack_page + IRQ_STACK_START; + irq_stack_high = high; + } else { + high = stack_page + THREAD_SIZE - 32; + irq_stack_high = 0; + } + + /* + * If we reached the top of the interrupt stack, start unwinding + * the interrupted task stack. + */ + if (unlikely(*sp == irq_stack_high)) { + unsigned long task_sp = *(unsigned long *)*sp; + + /* + * Check that the pointer saved in the IRQ stack head points to + * something within the stack of the current task + */ + if (!object_is_on_stack((void *)task_sp)) + return 0; + + /* + * Follow pointer to tasks kernel stack frame where interrupted + * state was saved. + */ + regs = (struct pt_regs *)task_sp; + pc = regs->cp0_epc; + if (!user_mode(regs) && __kernel_text_address(pc)) { + *sp = regs->regs[29]; + *ra = regs->regs[31]; + return pc; } return 0; } @@ -533,8 +554,7 @@ unsigned long notrace unwind_stack_by_address(unsigned long stack_page, if (leaf < 0) return 0; - if (*sp < stack_page || - *sp + info.frame_size > stack_page + THREAD_SIZE - 32) + if (*sp < low || *sp + info.frame_size > high) return 0; if (leaf) diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c index 9103bebc9a8e..2d1a0c438771 100644 --- a/arch/mips/kernel/relocate.c +++ b/arch/mips/kernel/relocate.c @@ -18,7 +18,7 @@ #include <linux/kernel.h> #include <linux/libfdt.h> #include <linux/of_fdt.h> -#include <linux/sched.h> +#include <linux/sched/task.h> #include <linux/start_kernel.h> #include <linux/string.h> #include <linux/printk.h> diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index c29d397eee86..80ed68b2c95e 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -600,3 +600,4 @@ EXPORT(sys_call_table) PTR sys_pkey_mprotect PTR sys_pkey_alloc PTR sys_pkey_free /* 4365 */ + PTR sys_statx diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 0687f96ee912..49765b44aa9b 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -438,4 +438,5 @@ EXPORT(sys_call_table) PTR sys_pkey_mprotect PTR sys_pkey_alloc PTR sys_pkey_free /* 5325 */ + PTR sys_statx .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 0331ba39a065..90bad2d1b2d3 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -433,4 +433,5 @@ EXPORT(sysn32_call_table) PTR sys_pkey_mprotect PTR sys_pkey_alloc PTR sys_pkey_free + PTR sys_statx /* 6330 */ .size sysn32_call_table,.-sysn32_call_table diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 5a47042dd25f..2dd70bd104e1 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -588,4 +588,5 @@ EXPORT(sys32_call_table) PTR sys_pkey_mprotect PTR sys_pkey_alloc PTR sys_pkey_free /* 4365 */ + PTR sys_statx .size sys32_call_table,.-sys32_call_table diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index 6d45f05538c8..795b4aaf8927 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -422,13 +422,12 @@ void play_dead(void) local_irq_disable(); idle_task_exit(); cpu = smp_processor_id(); + core = cpu_data[cpu].core; cpu_death = CPU_DEATH_POWER; pr_debug("CPU%d going offline\n", cpu); if (cpu_has_mipsmt || cpu_has_vp) { - core = cpu_data[cpu].core; - /* Look for another online VPE within the core */ for_each_online_cpu(cpu_death_sibling) { if (cpu_data[cpu_death_sibling].core != core) diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index f1d17ece4181..1dfa7f5796c7 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -98,7 +98,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) if (unlikely(addr & 3)) return -EINVAL; - if (unlikely(!access_ok(VERIFY_WRITE, addr, 4))) + if (unlikely(!access_ok(VERIFY_WRITE, (const void __user *)addr, 4))) return -EINVAL; if (cpu_has_llsc && R10000_LLSC_WAR) { diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index c7d17cfb32f6..b49e7bf9f950 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -83,7 +83,7 @@ extern asmlinkage void handle_dbe(void); extern asmlinkage void handle_sys(void); extern asmlinkage void handle_bp(void); extern asmlinkage void handle_ri(void); -extern asmlinkage void handle_ri_rdhwr_vivt(void); +extern asmlinkage void handle_ri_rdhwr_tlbp(void); extern asmlinkage void handle_ri_rdhwr(void); extern asmlinkage void handle_cpu(void); extern asmlinkage void handle_ov(void); @@ -2408,9 +2408,18 @@ void __init trap_init(void) set_except_vector(EXCCODE_SYS, handle_sys); set_except_vector(EXCCODE_BP, handle_bp); - set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri : - (cpu_has_vtag_icache ? - handle_ri_rdhwr_vivt : handle_ri_rdhwr)); + + if (rdhwr_noopt) + set_except_vector(EXCCODE_RI, handle_ri); + else { + if (cpu_has_vtag_icache) + set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp); + else if (current_cpu_type() == CPU_LOONGSON3) + set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp); + else + set_except_vector(EXCCODE_RI, handle_ri_rdhwr); + } + set_except_vector(EXCCODE_CPU, handle_cpu); set_except_vector(EXCCODE_OV, handle_ov); set_except_vector(EXCCODE_TR, handle_tr); diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 7ed98354fe9d..f806ee56e639 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -1026,7 +1026,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, goto sigbus; if (IS_ENABLED(CONFIG_EVA)) { - if (segment_eq(get_fs(), get_ds())) + if (uaccess_kernel()) LoadHW(addr, value, res); else LoadHWE(addr, value, res); @@ -1045,7 +1045,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, goto sigbus; if (IS_ENABLED(CONFIG_EVA)) { - if (segment_eq(get_fs(), get_ds())) + if (uaccess_kernel()) LoadW(addr, value, res); else LoadWE(addr, value, res); @@ -1064,7 +1064,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, goto sigbus; if (IS_ENABLED(CONFIG_EVA)) { - if (segment_eq(get_fs(), get_ds())) + if (uaccess_kernel()) LoadHWU(addr, value, res); else LoadHWUE(addr, value, res); @@ -1132,7 +1132,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, value = regs->regs[insn.i_format.rt]; if (IS_ENABLED(CONFIG_EVA)) { - if (segment_eq(get_fs(), get_ds())) + if (uaccess_kernel()) StoreHW(addr, value, res); else StoreHWE(addr, value, res); @@ -1152,7 +1152,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, value = regs->regs[insn.i_format.rt]; if (IS_ENABLED(CONFIG_EVA)) { - if (segment_eq(get_fs(), get_ds())) + if (uaccess_kernel()) StoreW(addr, value, res); else StoreWE(addr, value, res); diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index f0a0e6d62be3..8ca2371aa684 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -97,6 +97,7 @@ SECTIONS DATA_DATA CONSTRUCTORS } + BUG_TABLE _gp = . + 0x8000; .lit8 : { *(.lit8) diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index 3c3aa05891dd..95bec460b651 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -467,7 +467,7 @@ void __init ltq_soc_init(void) if (!np_xbar) panic("Failed to load xbar nodes from devicetree"); - if (of_address_to_resource(np_pmu, 0, &res_xbar)) + if (of_address_to_resource(np_xbar, 0, &res_xbar)) panic("Failed to get xbar resources"); if (!request_mem_region(res_xbar.start, resource_size(&res_xbar), res_xbar.name)) diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S index c3031f18c572..3114a2ed1f4e 100644 --- a/arch/mips/lib/memcpy.S +++ b/arch/mips/lib/memcpy.S @@ -562,39 +562,9 @@ LOADK t0, THREAD_BUADDR(t0) # t0 is just past last good address nop SUB len, AT, t0 # len number of uncopied bytes - bnez t6, .Ldone\@ /* Skip the zeroing part if inatomic */ - /* - * Here's where we rely on src and dst being incremented in tandem, - * See (3) above. - * dst += (fault addr - src) to put dst at first byte to clear - */ - ADD dst, t0 # compute start address in a1 - SUB dst, src - /* - * Clear len bytes starting at dst. Can't call __bzero because it - * might modify len. An inefficient loop for these rare times... - */ - .set reorder /* DADDI_WAR */ - SUB src, len, 1 - beqz len, .Ldone\@ - .set noreorder -1: sb zero, 0(dst) - ADD dst, dst, 1 -#ifndef CONFIG_CPU_DADDI_WORKAROUNDS - bnez src, 1b - SUB src, src, 1 -#else - .set push - .set noat - li v1, 1 - bnez src, 1b - SUB src, src, v1 - .set pop -#endif jr ra nop - #define SEXC(n) \ .set reorder; /* DADDI_WAR */ \ .Ls_exc_p ## n ## u\@: \ @@ -673,15 +643,6 @@ LEAF(__rmemcpy) /* a0=dst a1=src a2=len */ END(__rmemcpy) /* - * t6 is used as a flag to note inatomic mode. - */ -LEAF(__copy_user_inatomic) -EXPORT_SYMBOL(__copy_user_inatomic) - b __copy_user_common - li t6, 1 - END(__copy_user_inatomic) - -/* * A combined memcpy/__copy_user * __copy_user sets len to 0 for success; else to an upper bound of * the number of uncopied bytes. @@ -694,8 +655,6 @@ EXPORT_SYMBOL(memcpy) .L__memcpy: FEXPORT(__copy_user) EXPORT_SYMBOL(__copy_user) - li t6, 0 /* not inatomic */ -__copy_user_common: /* Legacy Mode, user <-> user */ __BUILD_COPY_USER LEGACY_MODE USEROP USEROP @@ -708,20 +667,12 @@ __copy_user_common: * space */ -LEAF(__copy_user_inatomic_eva) -EXPORT_SYMBOL(__copy_user_inatomic_eva) - b __copy_from_user_common - li t6, 1 - END(__copy_user_inatomic_eva) - /* * __copy_from_user (EVA) */ LEAF(__copy_from_user_eva) EXPORT_SYMBOL(__copy_from_user_eva) - li t6, 0 /* not inatomic */ -__copy_from_user_common: __BUILD_COPY_USER EVA_MODE USEROP KERNELOP END(__copy_from_user_eva) diff --git a/arch/mips/loongson32/common/time.c b/arch/mips/loongson32/common/time.c index e6f972d35252..1c4332a26cf1 100644 --- a/arch/mips/loongson32/common/time.c +++ b/arch/mips/loongson32/common/time.c @@ -199,7 +199,9 @@ static void __init ls1x_time_init(void) clockevent_set_clock(cd, mips_hpt_frequency); cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd); + cd->max_delta_ticks = 0xffffff; cd->min_delta_ns = clockevent_delta2ns(0x000300, cd); + cd->min_delta_ticks = 0x000300; cd->cpumask = cpumask_of(smp_processor_id()); clockevents_register_device(cd); diff --git a/arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c index b817d6d3a060..a6adcc4f8960 100644 --- a/arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c +++ b/arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c @@ -123,7 +123,9 @@ void __init setup_mfgpt0_timer(void) cd->cpumask = cpumask_of(cpu); clockevent_set_clock(cd, MFGPT_TICK_RATE); cd->max_delta_ns = clockevent_delta2ns(0xffff, cd); + cd->max_delta_ticks = 0xffff; cd->min_delta_ns = clockevent_delta2ns(0xf, cd); + cd->min_delta_ticks = 0xf; /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */ _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100); diff --git a/arch/mips/loongson64/loongson-3/hpet.c b/arch/mips/loongson64/loongson-3/hpet.c index 24afe364637b..4df9d4b7356a 100644 --- a/arch/mips/loongson64/loongson-3/hpet.c +++ b/arch/mips/loongson64/loongson-3/hpet.c @@ -241,7 +241,9 @@ void __init setup_hpet_timer(void) cd->cpumask = cpumask_of(cpu); clockevent_set_clock(cd, HPET_FREQ); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->max_delta_ticks = 0x7fffffff; cd->min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, cd); + cd->min_delta_ticks = HPET_MIN_PROG_DELTA; clockevents_register_device(cd); setup_irq(HPET_T0_IRQ, &hpet_irq); diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index e7f798d55fbc..3fe99cb271a9 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1562,6 +1562,7 @@ static void probe_vcache(void) vcache_size = c->vcache.sets * c->vcache.ways * c->vcache.linesz; c->vcache.waybit = 0; + c->vcache.waysize = vcache_size / c->vcache.ways; pr_info("Unified victim cache %ldkB %s, linesize %d bytes.\n", vcache_size >> 10, way_string[c->vcache.ways], c->vcache.linesz); @@ -1664,6 +1665,7 @@ static void __init loongson3_sc_init(void) /* Loongson-3 has 4 cores, 1MB scache for each. scaches are shared */ scache_size *= 4; c->scache.waybit = 0; + c->scache.waysize = scache_size / c->scache.ways; pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n", scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); if (scache_size) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 9bfee8988eaf..4f642e07c2b1 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -760,7 +760,8 @@ static void build_huge_update_entries(u32 **p, unsigned int pte, static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, struct uasm_label **l, unsigned int pte, - unsigned int ptr) + unsigned int ptr, + unsigned int flush) { #ifdef CONFIG_SMP UASM_i_SC(p, pte, 0, ptr); @@ -769,6 +770,22 @@ static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r, #else UASM_i_SW(p, pte, 0, ptr); #endif + if (cpu_has_ftlb && flush) { + BUG_ON(!cpu_has_tlbinv); + + UASM_i_MFC0(p, ptr, C0_ENTRYHI); + uasm_i_ori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); + UASM_i_MTC0(p, ptr, C0_ENTRYHI); + build_tlb_write_entry(p, l, r, tlb_indexed); + + uasm_i_xori(p, ptr, ptr, MIPS_ENTRYHI_EHINV); + UASM_i_MTC0(p, ptr, C0_ENTRYHI); + build_huge_update_entries(p, pte, ptr); + build_huge_tlb_write_entry(p, l, r, pte, tlb_random, 0); + + return; + } + build_huge_update_entries(p, pte, ptr); build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0); } @@ -2199,7 +2216,7 @@ static void build_r4000_tlb_load_handler(void) uasm_l_tlbl_goaround2(&l, p); } uasm_i_ori(&p, wr.r1, wr.r1, (_PAGE_ACCESSED | _PAGE_VALID)); - build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); + build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); #endif uasm_l_nopage_tlbl(&l, p); @@ -2254,7 +2271,7 @@ static void build_r4000_tlb_store_handler(void) build_tlb_probe_entry(&p); uasm_i_ori(&p, wr.r1, wr.r1, _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); - build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); + build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 1); #endif uasm_l_nopage_tlbs(&l, p); @@ -2310,7 +2327,7 @@ static void build_r4000_tlb_modify_handler(void) build_tlb_probe_entry(&p); uasm_i_ori(&p, wr.r1, wr.r1, _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); - build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2); + build_huge_handler_tail(&p, &r, &l, wr.r1, wr.r2, 0); #endif uasm_l_nopage_tlbm(&l, p); diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index cb675ec6f283..54f56d5a96c4 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -232,6 +232,17 @@ void __init arch_init_irq(void) { int corehi_irq; + /* + * Preallocate the i8259's expected virq's here. Since irqchip_init() + * will probe the irqchips in hierarchial order, i8259 is probed last. + * If anything allocates a virq before the i8259 is probed, it will + * be given one of the i8259's expected range and consequently setup + * of the i8259 will fail. + */ + WARN(irq_alloc_descs(I8259A_IRQ_BASE, I8259A_IRQ_BASE, + 16, numa_node_id()) < 0, + "Cannot reserve i8259 virqs at IRQ%d\n", I8259A_IRQ_BASE); + i8259_set_poll(mips_pcibios_iack); irqchip_init(); diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 1829a9031eec..289edcfadd7c 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -21,6 +21,7 @@ #include <linux/i8253.h> #include <linux/init.h> #include <linux/kernel_stat.h> +#include <linux/libfdt.h> #include <linux/math64.h> #include <linux/sched.h> #include <linux/spinlock.h> @@ -207,6 +208,33 @@ static void __init init_rtc(void) CMOS_WRITE(ctrl & ~RTC_SET, RTC_CONTROL); } +#ifdef CONFIG_CLKSRC_MIPS_GIC +static u32 gic_frequency_dt; + +static struct property gic_frequency_prop = { + .name = "clock-frequency", + .length = sizeof(u32), + .value = &gic_frequency_dt, +}; + +static void update_gic_frequency_dt(void) +{ + struct device_node *node; + + gic_frequency_dt = cpu_to_be32(gic_frequency); + + node = of_find_compatible_node(NULL, NULL, "mti,gic-timer"); + if (!node) { + pr_err("mti,gic-timer device node not found\n"); + return; + } + + if (of_update_property(node, &gic_frequency_prop) < 0) + pr_err("error updating gic frequency property\n"); +} + +#endif + void __init plat_time_init(void) { unsigned int prid = read_c0_prid() & (PRID_COMP_MASK | PRID_IMP_MASK); @@ -236,7 +264,8 @@ void __init plat_time_init(void) printk("GIC frequency %d.%02d MHz\n", freq/1000000, (freq%1000000)*100/1000000); #ifdef CONFIG_CLKSRC_MIPS_GIC - gic_clocksource_init(gic_frequency); + update_gic_frequency_dt(); + clocksource_probe(); #endif } #endif diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c index 5e645c9a3162..16ace558cd9d 100644 --- a/arch/mips/oprofile/backtrace.c +++ b/arch/mips/oprofile/backtrace.c @@ -18,7 +18,7 @@ struct stackframe { static inline int get_mem(unsigned long addr, unsigned long *result) { unsigned long *address = (unsigned long *) addr; - if (!access_ok(VERIFY_READ, addr, sizeof(unsigned long))) + if (!access_ok(VERIFY_READ, address, sizeof(unsigned long))) return -1; if (__copy_from_user_inatomic(result, address, sizeof(unsigned long))) return -3; diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c index 014649be158d..3a84f6c0c840 100644 --- a/arch/mips/pci/pci-legacy.c +++ b/arch/mips/pci/pci-legacy.c @@ -190,7 +190,7 @@ void register_pci_controller(struct pci_controller *hose) } INIT_LIST_HEAD(&hose->list); - list_add(&hose->list, &controllers); + list_add_tail(&hose->list, &controllers); /* * Do not panic here but later - this might happen before console init. diff --git a/arch/mips/ralink/cevt-rt3352.c b/arch/mips/ralink/cevt-rt3352.c index f24eee04e16a..b8a1376165b0 100644 --- a/arch/mips/ralink/cevt-rt3352.c +++ b/arch/mips/ralink/cevt-rt3352.c @@ -129,7 +129,9 @@ static int __init ralink_systick_init(struct device_node *np) systick.dev.name = np->name; clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60); systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev); + systick.dev.max_delta_ticks = 0x7fff; systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev); + systick.dev.min_delta_ticks = 0x3; systick.dev.irq = irq_of_parse_and_map(np, 0); if (!systick.dev.irq) { pr_err("%s: request_irq failed", np->name); diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c index c4ffd43d3996..48ce701557a4 100644 --- a/arch/mips/ralink/rt3883.c +++ b/arch/mips/ralink/rt3883.c @@ -35,7 +35,7 @@ static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) }; -static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) }; +static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna g", 0, 35, 3) }; static struct rt2880_pmx_func pci_func[] = { FUNC("pci-dev", 0, 40, 32), FUNC("pci-host2", 1, 40, 32), @@ -43,7 +43,7 @@ static struct rt2880_pmx_func pci_func[] = { FUNC("pci-fnc", 3, 40, 32) }; static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) }; -static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) }; +static struct rt2880_pmx_func ge2_func[] = { FUNC("ge2", 0, 84, 12) }; static struct rt2880_pmx_group rt3883_pinmux_data[] = { GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C), diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 695c51bdd7dc..a53f0c8c901e 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -113,7 +113,9 @@ void hub_rt_clock_event_init(void) cd->features = CLOCK_EVT_FEAT_ONESHOT; clockevent_set_clock(cd, CYCLES_PER_SEC); cd->max_delta_ns = clockevent_delta2ns(0xfffffffffffff, cd); + cd->max_delta_ticks = 0xfffffffffffff; cd->min_delta_ns = clockevent_delta2ns(0x300, cd); + cd->min_delta_ticks = 0x300; cd->rating = 200; cd->irq = irq; cd->cpumask = cpumask_of(cpu); diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild index 97f64c723a0c..ed810e7206e8 100644 --- a/arch/mn10300/include/asm/Kbuild +++ b/arch/mn10300/include/asm/Kbuild @@ -2,6 +2,7 @@ generic-y += barrier.h generic-y += clkdev.h generic-y += exec.h +generic-y += extable.h generic-y += irq_work.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h index 2eedf6f46a57..c6966474827f 100644 --- a/arch/mn10300/include/asm/uaccess.h +++ b/arch/mn10300/include/asm/uaccess.h @@ -14,13 +14,8 @@ /* * User space memory access functions */ -#include <linux/thread_info.h> #include <linux/kernel.h> #include <asm/page.h> -#include <asm/errno.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 /* * The fs value determines whether argument validity checking should be @@ -71,26 +66,7 @@ static inline int ___range_ok(unsigned long addr, unsigned int size) #define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0) #define __access_ok(addr, size) (__range_ok((addr), (size)) == 0) -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -/* Returns 0 if exception not found and fixup otherwise. */ -extern int fixup_exception(struct pt_regs *regs); +#include <asm/extable.h> #define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr))) #define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr))) @@ -299,170 +275,19 @@ do { \ } \ } while (0) -#define __copy_user_zeroing(to, from, size) \ -do { \ - if (size) { \ - void *__to = to; \ - const void *__from = from; \ - int w; \ - asm volatile( \ - "0: movbu (%0),%3;\n" \ - "1: movbu %3,(%1);\n" \ - " inc %0;\n" \ - " inc %1;\n" \ - " add -1,%2;\n" \ - " bne 0b;\n" \ - "2:\n" \ - " .section .fixup,\"ax\"\n" \ - "3:\n" \ - " mov %2,%0\n" \ - " clr %3\n" \ - "4: movbu %3,(%1);\n" \ - " inc %1;\n" \ - " add -1,%2;\n" \ - " bne 4b;\n" \ - " mov %0,%2\n" \ - " jmp 2b\n" \ - " .previous\n" \ - " .section __ex_table,\"a\"\n" \ - " .balign 4\n" \ - " .long 0b,3b\n" \ - " .long 1b,3b\n" \ - " .previous\n" \ - : "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\ - : "0"(__from), "1"(__to), "2"(size) \ - : "cc", "memory"); \ - } \ -} while (0) - -/* We let the __ versions of copy_from/to_user inline, because they're often - * used in fast paths and have only a small space overhead. - */ -static inline -unsigned long __generic_copy_from_user_nocheck(void *to, const void *from, - unsigned long n) -{ - __copy_user_zeroing(to, from, n); - return n; -} - -static inline -unsigned long __generic_copy_to_user_nocheck(void *to, const void *from, - unsigned long n) +static inline unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { __copy_user(to, from, n); return n; } - -#if 0 -#error "don't use - these macros don't increment to & from pointers" -/* Optimize just a little bit when we know the size of the move. */ -#define __constant_copy_user(to, from, size) \ -do { \ - asm volatile( \ - " mov %0,a0;\n" \ - "0: movbu (%1),d3;\n" \ - "1: movbu d3,(%2);\n" \ - " add -1,a0;\n" \ - " bne 0b;\n" \ - "2:;" \ - ".section .fixup,\"ax\"\n" \ - "3: jmp 2b\n" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n" \ - " .balign 4\n" \ - " .long 0b,3b\n" \ - " .long 1b,3b\n" \ - ".previous" \ - : \ - : "d"(size), "d"(to), "d"(from) \ - : "d3", "a0"); \ -} while (0) - -/* Optimize just a little bit when we know the size of the move. */ -#define __constant_copy_user_zeroing(to, from, size) \ -do { \ - asm volatile( \ - " mov %0,a0;\n" \ - "0: movbu (%1),d3;\n" \ - "1: movbu d3,(%2);\n" \ - " add -1,a0;\n" \ - " bne 0b;\n" \ - "2:;" \ - ".section .fixup,\"ax\"\n" \ - "3: jmp 2b\n" \ - ".previous\n" \ - ".section __ex_table,\"a\"\n" \ - " .balign 4\n" \ - " .long 0b,3b\n" \ - " .long 1b,3b\n" \ - ".previous" \ - : \ - : "d"(size), "d"(to), "d"(from) \ - : "d3", "a0"); \ -} while (0) - -static inline -unsigned long __constant_copy_to_user(void *to, const void *from, - unsigned long n) -{ - if (access_ok(VERIFY_WRITE, to, n)) - __constant_copy_user(to, from, n); - return n; -} - -static inline -unsigned long __constant_copy_from_user(void *to, const void *from, - unsigned long n) +static inline unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - if (access_ok(VERIFY_READ, from, n)) - __constant_copy_user_zeroing(to, from, n); - return n; -} - -static inline -unsigned long __constant_copy_to_user_nocheck(void *to, const void *from, - unsigned long n) -{ - __constant_copy_user(to, from, n); - return n; -} - -static inline -unsigned long __constant_copy_from_user_nocheck(void *to, const void *from, - unsigned long n) -{ - __constant_copy_user_zeroing(to, from, n); + __copy_user(to, from, n); return n; } -#endif - -extern unsigned long __generic_copy_to_user(void __user *, const void *, - unsigned long); -extern unsigned long __generic_copy_from_user(void *, const void __user *, - unsigned long); - -#define __copy_to_user_inatomic(to, from, n) \ - __generic_copy_to_user_nocheck((to), (from), (n)) -#define __copy_from_user_inatomic(to, from, n) \ - __generic_copy_from_user_nocheck((to), (from), (n)) - -#define __copy_to_user(to, from, n) \ -({ \ - might_fault(); \ - __copy_to_user_inatomic((to), (from), (n)); \ -}) - -#define __copy_from_user(to, from, n) \ -({ \ - might_fault(); \ - __copy_from_user_inatomic((to), (from), (n)); \ -}) - - -#define copy_to_user(to, from, n) __generic_copy_to_user((to), (from), (n)) -#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n)) extern long strncpy_from_user(char *dst, const char __user *src, long count); extern long __strncpy_from_user(char *dst, const char __user *src, long count); diff --git a/arch/mn10300/kernel/cevt-mn10300.c b/arch/mn10300/kernel/cevt-mn10300.c index d9b34dd44f04..2b21bbc9efa4 100644 --- a/arch/mn10300/kernel/cevt-mn10300.c +++ b/arch/mn10300/kernel/cevt-mn10300.c @@ -98,7 +98,9 @@ int __init init_clockevents(void) /* Calculate the min / max delta */ cd->max_delta_ns = clockevent_delta2ns(TMJCBR_MAX, cd); + cd->max_delta_ticks = TMJCBR_MAX; cd->min_delta_ns = clockevent_delta2ns(100, cd); + cd->min_delta_ticks = 100; cd->rating = 200; cd->cpumask = cpumask_of(smp_processor_id()); diff --git a/arch/mn10300/kernel/mn10300_ksyms.c b/arch/mn10300/kernel/mn10300_ksyms.c index ec6c4f8f93a6..5e9f919635f0 100644 --- a/arch/mn10300/kernel/mn10300_ksyms.c +++ b/arch/mn10300/kernel/mn10300_ksyms.c @@ -26,8 +26,6 @@ EXPORT_SYMBOL(strncpy_from_user); EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(clear_user); EXPORT_SYMBOL(__clear_user); -EXPORT_SYMBOL(__generic_copy_from_user); -EXPORT_SYMBOL(__generic_copy_to_user); EXPORT_SYMBOL(strnlen_user); extern u64 __ashrdi3(u64, unsigned); diff --git a/arch/mn10300/lib/usercopy.c b/arch/mn10300/lib/usercopy.c index ce8899e5e171..cece1799cc32 100644 --- a/arch/mn10300/lib/usercopy.c +++ b/arch/mn10300/lib/usercopy.c @@ -11,24 +11,6 @@ */ #include <linux/uaccess.h> -unsigned long -__generic_copy_to_user(void *to, const void *from, unsigned long n) -{ - if (access_ok(VERIFY_WRITE, to, n)) - __copy_user(to, from, n); - return n; -} - -unsigned long -__generic_copy_from_user(void *to, const void *from, unsigned long n) -{ - if (access_ok(VERIFY_READ, from, n)) - __copy_user_zeroing(to, from, n); - else - memset(to, 0, n); - return n; -} - /* * Copy a null terminated string from userspace. */ diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild index aaa3c218b56c..87e70f2b463f 100644 --- a/arch/nios2/include/asm/Kbuild +++ b/arch/nios2/include/asm/Kbuild @@ -13,6 +13,7 @@ generic-y += dma.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += fb.h generic-y += fcntl.h generic-y += ftrace.h diff --git a/arch/nios2/include/asm/uaccess.h b/arch/nios2/include/asm/uaccess.h index 0ab82324c817..727bd9504899 100644 --- a/arch/nios2/include/asm/uaccess.h +++ b/arch/nios2/include/asm/uaccess.h @@ -13,33 +13,11 @@ #ifndef _ASM_NIOS2_UACCESS_H #define _ASM_NIOS2_UACCESS_H -#include <linux/errno.h> -#include <linux/thread_info.h> #include <linux/string.h> #include <asm/page.h> -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ -struct exception_table_entry { - unsigned long insn; - unsigned long fixup; -}; - -extern int fixup_exception(struct pt_regs *regs); +#include <asm/extable.h> /* * Segment stuff @@ -95,36 +73,17 @@ static inline unsigned long __must_check clear_user(void __user *to, return __clear_user(to, n); } -extern long __copy_from_user(void *to, const void __user *from, - unsigned long n); -extern long __copy_to_user(void __user *to, const void *from, unsigned long n); - -static inline long copy_from_user(void *to, const void __user *from, - unsigned long n) -{ - unsigned long res = n; - if (access_ok(VERIFY_READ, from, n)) - res = __copy_from_user(to, from, n); - if (unlikely(res)) - memset(to + (n - res), 0, res); - return res; -} - -static inline long copy_to_user(void __user *to, const void *from, - unsigned long n) -{ - if (!access_ok(VERIFY_WRITE, to, n)) - return n; - return __copy_to_user(to, from, n); -} +extern unsigned long +raw_copy_from_user(void *to, const void __user *from, unsigned long n); +extern unsigned long +raw_copy_to_user(void __user *to, const void *from, unsigned long n); +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER extern long strncpy_from_user(char *__to, const char __user *__from, long __len); extern long strnlen_user(const char __user *s, long n); -#define __copy_from_user_inatomic __copy_from_user -#define __copy_to_user_inatomic __copy_to_user - /* Optimized macros */ #define __get_user_asm(val, insn, addr, err) \ { \ diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c index 367c5426157b..3901b80d4420 100644 --- a/arch/nios2/kernel/prom.c +++ b/arch/nios2/kernel/prom.c @@ -48,6 +48,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) return alloc_bootmem_align(size, align); } +int __init early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size, + bool nomap) +{ + reserve_bootmem(base, size, BOOTMEM_DEFAULT); + return 0; +} + void __init early_init_devtree(void *params) { __be32 *dtb = (u32 *)__dtb_start; diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c index 6e57ffa5db27..6044d9be28b4 100644 --- a/arch/nios2/kernel/setup.c +++ b/arch/nios2/kernel/setup.c @@ -201,6 +201,9 @@ void __init setup_arch(char **cmdline_p) } #endif /* CONFIG_BLK_DEV_INITRD */ + early_init_fdt_reserve_self(); + early_init_fdt_scan_reserved_mem(); + unflatten_and_copy_device_tree(); setup_cpuinfo(); diff --git a/arch/nios2/mm/uaccess.c b/arch/nios2/mm/uaccess.c index 7663e156ff4f..804983317766 100644 --- a/arch/nios2/mm/uaccess.c +++ b/arch/nios2/mm/uaccess.c @@ -10,9 +10,9 @@ #include <linux/export.h> #include <linux/uaccess.h> -asm(".global __copy_from_user\n" - " .type __copy_from_user, @function\n" - "__copy_from_user:\n" +asm(".global raw_copy_from_user\n" + " .type raw_copy_from_user, @function\n" + "raw_copy_from_user:\n" " movi r2,7\n" " mov r3,r4\n" " bge r2,r6,1f\n" @@ -65,12 +65,12 @@ asm(".global __copy_from_user\n" ".word 7b,13b\n" ".previous\n" ); -EXPORT_SYMBOL(__copy_from_user); +EXPORT_SYMBOL(raw_copy_from_user); asm( - " .global __copy_to_user\n" - " .type __copy_to_user, @function\n" - "__copy_to_user:\n" + " .global raw_copy_to_user\n" + " .type raw_copy_to_user, @function\n" + "raw_copy_to_user:\n" " movi r2,7\n" " mov r3,r4\n" " bge r2,r6,1f\n" @@ -127,7 +127,7 @@ asm( ".word 11b,13b\n" ".word 12b,13b\n" ".previous\n"); -EXPORT_SYMBOL(__copy_to_user); +EXPORT_SYMBOL(raw_copy_to_user); long strncpy_from_user(char *__to, const char __user *__from, long __len) { diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild index fb01873a5aad..df8e2f7bc7dd 100644 --- a/arch/openrisc/include/asm/Kbuild +++ b/arch/openrisc/include/asm/Kbuild @@ -16,6 +16,7 @@ generic-y += dma.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += fb.h generic-y += fcntl.h generic-y += ftrace.h diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h index 1311e6b13991..a557a7cd0232 100644 --- a/arch/openrisc/include/asm/uaccess.h +++ b/arch/openrisc/include/asm/uaccess.h @@ -22,14 +22,10 @@ /* * User space memory access functions */ -#include <linux/errno.h> -#include <linux/thread_info.h> #include <linux/prefetch.h> #include <linux/string.h> #include <asm/page.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 +#include <asm/extable.h> /* * The fs value determines whether argument validity checking should be @@ -66,23 +62,6 @@ __range_ok((unsigned long)addr, (unsigned long)size) /* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry { - unsigned long insn, fixup; -}; - -/* * These are the main single-value transfer routines. They automatically * use the right size if we just have the right pointer type. * @@ -257,34 +236,18 @@ do { \ extern unsigned long __must_check __copy_tofrom_user(void *to, const void *from, unsigned long size); - -#define __copy_from_user(to, from, size) \ - __copy_tofrom_user(to, from, size) -#define __copy_to_user(to, from, size) \ - __copy_tofrom_user(to, from, size) - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - static inline unsigned long -copy_from_user(void *to, const void *from, unsigned long n) +raw_copy_from_user(void *to, const void __user *from, unsigned long size) { - unsigned long res = n; - - if (likely(access_ok(VERIFY_READ, from, n))) - res = __copy_tofrom_user(to, from, n); - if (unlikely(res)) - memset(to + (n - res), 0, res); - return res; + return __copy_tofrom_user(to, (__force const void *)from, size); } - static inline unsigned long -copy_to_user(void *to, const void *from, unsigned long n) +raw_copy_to_user(void *to, const void __user *from, unsigned long size) { - if (likely(access_ok(VERIFY_WRITE, to, n))) - n = __copy_tofrom_user(to, from, n); - return n; + return __copy_tofrom_user((__force void *)to, from, size); } +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER extern unsigned long __clear_user(void *addr, unsigned long size); @@ -297,7 +260,7 @@ clear_user(void *addr, unsigned long size) } #define user_addr_max() \ - (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL) + (uaccess_kernel() ? ~0UL : TASK_SIZE) extern long strncpy_from_user(char *dest, const char __user *src, long count); diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index ad294b3fb90b..531da9eb8f43 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -26,7 +26,6 @@ config PARISC select SYSCTL_ARCH_UNALIGN_ALLOW select SYSCTL_EXCEPTION_TRACE select HAVE_MOD_ARCH_SPECIFIC - select HAVE_ARCH_HARDENED_USERCOPY select VIRT_TO_BUS select MODULES_USE_ELF_RELA select CLONE_BACKWARDS diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h index 62a33338549c..d2742273a685 100644 --- a/arch/parisc/include/asm/bug.h +++ b/arch/parisc/include/asm/bug.h @@ -46,7 +46,7 @@ #endif #ifdef CONFIG_DEBUG_BUGVERBOSE -#define __WARN_TAINT(taint) \ +#define __WARN_FLAGS(flags) \ do { \ asm volatile("\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \ @@ -56,11 +56,11 @@ "\t.org 2b+%c3\n" \ "\t.popsection" \ : : "i" (__FILE__), "i" (__LINE__), \ - "i" (BUGFLAG_TAINT(taint)), \ + "i" (BUGFLAG_WARNING|(flags)), \ "i" (sizeof(struct bug_entry)) ); \ } while(0) #else -#define __WARN_TAINT(taint) \ +#define __WARN_FLAGS(flags) \ do { \ asm volatile("\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \ @@ -69,7 +69,7 @@ "\t.short %c0\n" \ "\t.org 2b+%c1\n" \ "\t.popsection" \ - : : "i" (BUGFLAG_TAINT(taint)), \ + : : "i" (BUGFLAG_WARNING|(flags)), \ "i" (sizeof(struct bug_entry)) ); \ } while(0) #endif diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index ac8bd586ace8..0ba14300cd8e 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -109,7 +109,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is * our gateway page, and causes no end of trouble... */ - if (segment_eq(KERNEL_DS, get_fs()) && !uaddr) + if (uaccess_kernel() && !uaddr) return -EFAULT; if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index edfbf9d6a6dd..6b113f39f30c 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -6,15 +6,10 @@ */ #include <asm/page.h> #include <asm/cache.h> -#include <asm/errno.h> #include <asm-generic/uaccess-unaligned.h> #include <linux/bug.h> #include <linux/string.h> -#include <linux/thread_info.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 #define KERNEL_DS ((mm_segment_t){0}) #define USER_DS ((mm_segment_t){1}) @@ -39,10 +34,10 @@ #define get_user __get_user #if !defined(CONFIG_64BIT) -#define LDD_USER(ptr) __get_user_asm64(ptr) +#define LDD_USER(val, ptr) __get_user_asm64(val, ptr) #define STD_USER(x, ptr) __put_user_asm64(x, ptr) #else -#define LDD_USER(ptr) __get_user_asm("ldd", ptr) +#define LDD_USER(val, ptr) __get_user_asm(val, "ldd", ptr) #define STD_USER(x, ptr) __put_user_asm("std", x, ptr) #endif @@ -65,6 +60,15 @@ struct exception_table_entry { ".previous\n" /* + * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() creates a special exception table entry + * (with lowest bit set) for which the fault handler in fixup_exception() will + * load -EFAULT into %r8 for a read or write fault, and zeroes the target + * register in case of a read fault in get_user(). + */ +#define ASM_EXCEPTIONTABLE_ENTRY_EFAULT( fault_addr, except_addr )\ + ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr + 1) + +/* * The page fault handler stores, in a per-cpu area, the following information * if a fixup routine is available. */ @@ -88,92 +92,116 @@ struct exception_data { " mtsp %0,%%sr2\n\t" \ : : "r"(get_fs()) : ) -#define __get_user(x, ptr) \ -({ \ - register long __gu_err __asm__ ("r8") = 0; \ - register long __gu_val __asm__ ("r9") = 0; \ - \ - load_sr2(); \ - switch (sizeof(*(ptr))) { \ - case 1: __get_user_asm("ldb", ptr); break; \ - case 2: __get_user_asm("ldh", ptr); break; \ - case 4: __get_user_asm("ldw", ptr); break; \ - case 8: LDD_USER(ptr); break; \ - default: BUILD_BUG(); break; \ - } \ - \ - (x) = (__force __typeof__(*(ptr))) __gu_val; \ - __gu_err; \ +#define __get_user_internal(val, ptr) \ +({ \ + register long __gu_err __asm__ ("r8") = 0; \ + \ + switch (sizeof(*(ptr))) { \ + case 1: __get_user_asm(val, "ldb", ptr); break; \ + case 2: __get_user_asm(val, "ldh", ptr); break; \ + case 4: __get_user_asm(val, "ldw", ptr); break; \ + case 8: LDD_USER(val, ptr); break; \ + default: BUILD_BUG(); \ + } \ + \ + __gu_err; \ +}) + +#define __get_user(val, ptr) \ +({ \ + load_sr2(); \ + __get_user_internal(val, ptr); \ }) -#define __get_user_asm(ldx, ptr) \ - __asm__("\n1:\t" ldx "\t0(%%sr2,%2),%0\n\t" \ - ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_get_user_skip_1)\ +#define __get_user_asm(val, ldx, ptr) \ +{ \ + register long __gu_val; \ + \ + __asm__("1: " ldx " 0(%%sr2,%2),%0\n" \ + "9:\n" \ + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ : "=r"(__gu_val), "=r"(__gu_err) \ - : "r"(ptr), "1"(__gu_err) \ - : "r1"); + : "r"(ptr), "1"(__gu_err)); \ + \ + (val) = (__force __typeof__(*(ptr))) __gu_val; \ +} #if !defined(CONFIG_64BIT) -#define __get_user_asm64(ptr) \ - __asm__("\n1:\tldw 0(%%sr2,%2),%0" \ - "\n2:\tldw 4(%%sr2,%2),%R0\n\t" \ - ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_get_user_skip_2)\ - ASM_EXCEPTIONTABLE_ENTRY(2b, fixup_get_user_skip_1)\ - : "=r"(__gu_val), "=r"(__gu_err) \ - : "r"(ptr), "1"(__gu_err) \ - : "r1"); +#define __get_user_asm64(val, ptr) \ +{ \ + union { \ + unsigned long long l; \ + __typeof__(*(ptr)) t; \ + } __gu_tmp; \ + \ + __asm__(" copy %%r0,%R0\n" \ + "1: ldw 0(%%sr2,%2),%0\n" \ + "2: ldw 4(%%sr2,%2),%R0\n" \ + "9:\n" \ + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \ + : "=&r"(__gu_tmp.l), "=r"(__gu_err) \ + : "r"(ptr), "1"(__gu_err)); \ + \ + (val) = __gu_tmp.t; \ +} #endif /* !defined(CONFIG_64BIT) */ -#define __put_user(x, ptr) \ +#define __put_user_internal(x, ptr) \ ({ \ register long __pu_err __asm__ ("r8") = 0; \ __typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \ \ - load_sr2(); \ switch (sizeof(*(ptr))) { \ - case 1: __put_user_asm("stb", __x, ptr); break; \ - case 2: __put_user_asm("sth", __x, ptr); break; \ - case 4: __put_user_asm("stw", __x, ptr); break; \ - case 8: STD_USER(__x, ptr); break; \ - default: BUILD_BUG(); break; \ - } \ + case 1: __put_user_asm("stb", __x, ptr); break; \ + case 2: __put_user_asm("sth", __x, ptr); break; \ + case 4: __put_user_asm("stw", __x, ptr); break; \ + case 8: STD_USER(__x, ptr); break; \ + default: BUILD_BUG(); \ + } \ \ __pu_err; \ }) +#define __put_user(x, ptr) \ +({ \ + load_sr2(); \ + __put_user_internal(x, ptr); \ +}) + + /* * The "__put_user/kernel_asm()" macros tell gcc they read from memory * instead of writing. This is because they do not write to any memory * gcc knows about, so there are no aliasing issues. These macros must - * also be aware that "fixup_put_user_skip_[12]" are executed in the - * context of the fault, and any registers used there must be listed - * as clobbers. In this case only "r1" is used by the current routines. - * r8/r9 are already listed as err/val. + * also be aware that fixups are executed in the context of the fault, + * and any registers used there must be listed as clobbers. + * r8 is already listed as err. */ #define __put_user_asm(stx, x, ptr) \ __asm__ __volatile__ ( \ - "\n1:\t" stx "\t%2,0(%%sr2,%1)\n\t" \ - ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_put_user_skip_1)\ + "1: " stx " %2,0(%%sr2,%1)\n" \ + "9:\n" \ + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ : "=r"(__pu_err) \ - : "r"(ptr), "r"(x), "0"(__pu_err) \ - : "r1") + : "r"(ptr), "r"(x), "0"(__pu_err)) #if !defined(CONFIG_64BIT) #define __put_user_asm64(__val, ptr) do { \ __asm__ __volatile__ ( \ - "\n1:\tstw %2,0(%%sr2,%1)" \ - "\n2:\tstw %R2,4(%%sr2,%1)\n\t" \ - ASM_EXCEPTIONTABLE_ENTRY(1b, fixup_put_user_skip_2)\ - ASM_EXCEPTIONTABLE_ENTRY(2b, fixup_put_user_skip_1)\ + "1: stw %2,0(%%sr2,%1)\n" \ + "2: stw %R2,4(%%sr2,%1)\n" \ + "9:\n" \ + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \ + ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \ : "=r"(__pu_err) \ - : "r"(ptr), "r"(__val), "0"(__pu_err) \ - : "r1"); \ + : "r"(ptr), "r"(__val), "0"(__pu_err)); \ } while (0) #endif /* !defined(CONFIG_64BIT) */ @@ -183,9 +211,6 @@ struct exception_data { * Complex access routines -- external declarations */ -extern unsigned long lcopy_to_user(void __user *, const void *, unsigned long); -extern unsigned long lcopy_from_user(void *, const void __user *, unsigned long); -extern unsigned long lcopy_in_user(void __user *, const void __user *, unsigned long); extern long strncpy_from_user(char *, const char __user *, long); extern unsigned lclear_user(void __user *, unsigned long); extern long lstrnlen_user(const char __user *, long); @@ -199,59 +224,14 @@ extern long lstrnlen_user(const char __user *, long); #define clear_user lclear_user #define __clear_user lclear_user -unsigned long __must_check __copy_to_user(void __user *dst, const void *src, - unsigned long len); -unsigned long __must_check __copy_from_user(void *dst, const void __user *src, - unsigned long len); -unsigned long copy_in_user(void __user *dst, const void __user *src, - unsigned long len); -#define __copy_in_user copy_in_user -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - -extern void __compiletime_error("usercopy buffer size is too small") -__bad_copy_user(void); - -static inline void copy_user_overflow(int size, unsigned long count) -{ - WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); -} - -static __always_inline unsigned long __must_check -copy_from_user(void *to, const void __user *from, unsigned long n) -{ - int sz = __compiletime_object_size(to); - unsigned long ret = n; - - if (likely(sz < 0 || sz >= n)) { - check_object_size(to, n, false); - ret = __copy_from_user(to, from, n); - } else if (!__builtin_constant_p(n)) - copy_user_overflow(sz, n); - else - __bad_copy_user(); - - if (unlikely(ret)) - memset(to + (n - ret), 0, ret); - - return ret; -} - -static __always_inline unsigned long __must_check -copy_to_user(void __user *to, const void *from, unsigned long n) -{ - int sz = __compiletime_object_size(from); - - if (likely(sz < 0 || sz >= n)) { - check_object_size(from, n, true); - n = __copy_to_user(to, from, n); - } else if (!__builtin_constant_p(n)) - copy_user_overflow(sz, n); - else - __bad_copy_user(); - - return n; -} +unsigned long __must_check raw_copy_to_user(void __user *dst, const void *src, + unsigned long len); +unsigned long __must_check raw_copy_from_user(void *dst, const void __user *src, + unsigned long len); +unsigned long __must_check raw_copy_in_user(void __user *dst, const void __user *src, + unsigned long len); +#define INLINE_COPY_TO_USER +#define INLINE_COPY_FROM_USER struct pt_regs; int fixup_exception(struct pt_regs *regs); diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 7484b3d11e0d..c6d6272a934f 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -47,16 +47,6 @@ EXPORT_SYMBOL(__cmpxchg_u64); EXPORT_SYMBOL(lclear_user); EXPORT_SYMBOL(lstrnlen_user); -/* Global fixups - defined as int to avoid creation of function pointers */ -extern int fixup_get_user_skip_1; -extern int fixup_get_user_skip_2; -extern int fixup_put_user_skip_1; -extern int fixup_put_user_skip_2; -EXPORT_SYMBOL(fixup_get_user_skip_1); -EXPORT_SYMBOL(fixup_get_user_skip_2); -EXPORT_SYMBOL(fixup_put_user_skip_1); -EXPORT_SYMBOL(fixup_put_user_skip_2); - #ifndef CONFIG_64BIT /* Needed so insmod can set dp value */ extern int $global$; diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index b76f503eee4a..4516a5b53f38 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -143,6 +143,8 @@ void machine_power_off(void) printk(KERN_EMERG "System shut down completed.\n" "Please power this system off now."); + /* prevent soft lockup/stalled CPU messages for endless loop. */ + rcu_sysrq_start(); for (;;); } diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile index 8fa92b8d839a..f2dac4d73b1b 100644 --- a/arch/parisc/lib/Makefile +++ b/arch/parisc/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for parisc-specific library files # -lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o \ +lib-y := lusercopy.o bitops.o checksum.o io.o memset.o memcpy.o \ ucmpdi2.o delay.o obj-y := iomap.o diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S deleted file mode 100644 index a5b72f22c7a6..000000000000 --- a/arch/parisc/lib/fixup.S +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Linux/PA-RISC Project (http://www.parisc-linux.org/) - * - * Copyright (C) 2004 Randolph Chung <tausq@debian.org> - * - * 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, or (at your option) - * any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Fixup routines for kernel exception handling. - */ -#include <asm/asm-offsets.h> -#include <asm/assembly.h> -#include <asm/errno.h> -#include <linux/linkage.h> - -#ifdef CONFIG_SMP - .macro get_fault_ip t1 t2 - loadgp - addil LT%__per_cpu_offset,%r27 - LDREG RT%__per_cpu_offset(%r1),\t1 - /* t2 = smp_processor_id() */ - mfctl 30,\t2 - ldw TI_CPU(\t2),\t2 -#ifdef CONFIG_64BIT - extrd,u \t2,63,32,\t2 -#endif - /* t2 = &__per_cpu_offset[smp_processor_id()]; */ - LDREGX \t2(\t1),\t2 - addil LT%exception_data,%r27 - LDREG RT%exception_data(%r1),\t1 - /* t1 = this_cpu_ptr(&exception_data) */ - add,l \t1,\t2,\t1 - /* %r27 = t1->fault_gp - restore gp */ - LDREG EXCDATA_GP(\t1), %r27 - /* t1 = t1->fault_ip */ - LDREG EXCDATA_IP(\t1), \t1 - .endm -#else - .macro get_fault_ip t1 t2 - loadgp - /* t1 = this_cpu_ptr(&exception_data) */ - addil LT%exception_data,%r27 - LDREG RT%exception_data(%r1),\t2 - /* %r27 = t2->fault_gp - restore gp */ - LDREG EXCDATA_GP(\t2), %r27 - /* t1 = t2->fault_ip */ - LDREG EXCDATA_IP(\t2), \t1 - .endm -#endif - - .level LEVEL - - .text - .section .fixup, "ax" - - /* get_user() fixups, store -EFAULT in r8, and 0 in r9 */ -ENTRY_CFI(fixup_get_user_skip_1) - get_fault_ip %r1,%r8 - ldo 4(%r1), %r1 - ldi -EFAULT, %r8 - bv %r0(%r1) - copy %r0, %r9 -ENDPROC_CFI(fixup_get_user_skip_1) - -ENTRY_CFI(fixup_get_user_skip_2) - get_fault_ip %r1,%r8 - ldo 8(%r1), %r1 - ldi -EFAULT, %r8 - bv %r0(%r1) - copy %r0, %r9 -ENDPROC_CFI(fixup_get_user_skip_2) - - /* put_user() fixups, store -EFAULT in r8 */ -ENTRY_CFI(fixup_put_user_skip_1) - get_fault_ip %r1,%r8 - ldo 4(%r1), %r1 - bv %r0(%r1) - ldi -EFAULT, %r8 -ENDPROC_CFI(fixup_put_user_skip_1) - -ENTRY_CFI(fixup_put_user_skip_2) - get_fault_ip %r1,%r8 - ldo 8(%r1), %r1 - bv %r0(%r1) - ldi -EFAULT, %r8 -ENDPROC_CFI(fixup_put_user_skip_2) - diff --git a/arch/parisc/lib/lusercopy.S b/arch/parisc/lib/lusercopy.S index 56845de6b5df..85c28bb80fb7 100644 --- a/arch/parisc/lib/lusercopy.S +++ b/arch/parisc/lib/lusercopy.S @@ -5,6 +5,8 @@ * Copyright (C) 2000 Richard Hirst <rhirst with parisc-linux.org> * Copyright (C) 2001 Matthieu Delahaye <delahaym at esiee.fr> * Copyright (C) 2003 Randolph Chung <tausq with parisc-linux.org> + * Copyright (C) 2017 Helge Deller <deller@gmx.de> + * Copyright (C) 2017 John David Anglin <dave.anglin@bell.net> * * * This program is free software; you can redistribute it and/or modify @@ -132,4 +134,321 @@ ENDPROC_CFI(lstrnlen_user) .procend + + +/* + * unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len) + * + * Inputs: + * - sr1 already contains space of source region + * - sr2 already contains space of destination region + * + * Returns: + * - number of bytes that could not be copied. + * On success, this will be zero. + * + * This code is based on a C-implementation of a copy routine written by + * Randolph Chung, which in turn was derived from the glibc. + * + * Several strategies are tried to try to get the best performance for various + * conditions. In the optimal case, we copy by loops that copy 32- or 16-bytes + * at a time using general registers. Unaligned copies are handled either by + * aligning the destination and then using shift-and-write method, or in a few + * cases by falling back to a byte-at-a-time copy. + * + * Testing with various alignments and buffer sizes shows that this code is + * often >10x faster than a simple byte-at-a-time copy, even for strangely + * aligned operands. It is interesting to note that the glibc version of memcpy + * (written in C) is actually quite fast already. This routine is able to beat + * it by 30-40% for aligned copies because of the loop unrolling, but in some + * cases the glibc version is still slightly faster. This lends more + * credibility that gcc can generate very good code as long as we are careful. + * + * Possible optimizations: + * - add cache prefetching + * - try not to use the post-increment address modifiers; they may create + * additional interlocks. Assumption is that those were only efficient on old + * machines (pre PA8000 processors) + */ + + dst = arg0 + src = arg1 + len = arg2 + end = arg3 + t1 = r19 + t2 = r20 + t3 = r21 + t4 = r22 + srcspc = sr1 + dstspc = sr2 + + t0 = r1 + a1 = t1 + a2 = t2 + a3 = t3 + a0 = t4 + + save_src = ret0 + save_dst = ret1 + save_len = r31 + +ENTRY_CFI(pa_memcpy) + .proc + .callinfo NO_CALLS + .entry + + /* Last destination address */ + add dst,len,end + + /* short copy with less than 16 bytes? */ + cmpib,COND(>>=),n 15,len,.Lbyte_loop + + /* same alignment? */ + xor src,dst,t0 + extru t0,31,2,t1 + cmpib,<>,n 0,t1,.Lunaligned_copy + +#ifdef CONFIG_64BIT + /* only do 64-bit copies if we can get aligned. */ + extru t0,31,3,t1 + cmpib,<>,n 0,t1,.Lalign_loop32 + + /* loop until we are 64-bit aligned */ +.Lalign_loop64: + extru dst,31,3,t1 + cmpib,=,n 0,t1,.Lcopy_loop_16_start +20: ldb,ma 1(srcspc,src),t1 +21: stb,ma t1,1(dstspc,dst) + b .Lalign_loop64 + ldo -1(len),len + + ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done) + +.Lcopy_loop_16_start: + ldi 31,t0 +.Lcopy_loop_16: + cmpb,COND(>>=),n t0,len,.Lword_loop + +10: ldd 0(srcspc,src),t1 +11: ldd 8(srcspc,src),t2 + ldo 16(src),src +12: std,ma t1,8(dstspc,dst) +13: std,ma t2,8(dstspc,dst) +14: ldd 0(srcspc,src),t1 +15: ldd 8(srcspc,src),t2 + ldo 16(src),src +16: std,ma t1,8(dstspc,dst) +17: std,ma t2,8(dstspc,dst) + + ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(11b,.Lcopy16_fault) + ASM_EXCEPTIONTABLE_ENTRY(12b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(13b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(14b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(15b,.Lcopy16_fault) + ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done) + + b .Lcopy_loop_16 + ldo -32(len),len + +.Lword_loop: + cmpib,COND(>>=),n 3,len,.Lbyte_loop +20: ldw,ma 4(srcspc,src),t1 +21: stw,ma t1,4(dstspc,dst) + b .Lword_loop + ldo -4(len),len + + ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done) + +#endif /* CONFIG_64BIT */ + + /* loop until we are 32-bit aligned */ +.Lalign_loop32: + extru dst,31,2,t1 + cmpib,=,n 0,t1,.Lcopy_loop_8 +20: ldb,ma 1(srcspc,src),t1 +21: stb,ma t1,1(dstspc,dst) + b .Lalign_loop32 + ldo -1(len),len + + ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done) + + +.Lcopy_loop_8: + cmpib,COND(>>=),n 15,len,.Lbyte_loop + +10: ldw 0(srcspc,src),t1 +11: ldw 4(srcspc,src),t2 +12: stw,ma t1,4(dstspc,dst) +13: stw,ma t2,4(dstspc,dst) +14: ldw 8(srcspc,src),t1 +15: ldw 12(srcspc,src),t2 + ldo 16(src),src +16: stw,ma t1,4(dstspc,dst) +17: stw,ma t2,4(dstspc,dst) + + ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(11b,.Lcopy8_fault) + ASM_EXCEPTIONTABLE_ENTRY(12b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(13b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(14b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(15b,.Lcopy8_fault) + ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done) + + b .Lcopy_loop_8 + ldo -16(len),len + +.Lbyte_loop: + cmpclr,COND(<>) len,%r0,%r0 + b,n .Lcopy_done +20: ldb 0(srcspc,src),t1 + ldo 1(src),src +21: stb,ma t1,1(dstspc,dst) + b .Lbyte_loop + ldo -1(len),len + + ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done) + +.Lcopy_done: + bv %r0(%r2) + sub end,dst,ret0 + + + /* src and dst are not aligned the same way. */ + /* need to go the hard way */ +.Lunaligned_copy: + /* align until dst is 32bit-word-aligned */ + extru dst,31,2,t1 + cmpib,=,n 0,t1,.Lcopy_dstaligned +20: ldb 0(srcspc,src),t1 + ldo 1(src),src +21: stb,ma t1,1(dstspc,dst) + b .Lunaligned_copy + ldo -1(len),len + + ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done) + ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done) + +.Lcopy_dstaligned: + + /* store src, dst and len in safe place */ + copy src,save_src + copy dst,save_dst + copy len,save_len + + /* len now needs give number of words to copy */ + SHRREG len,2,len + + /* + * Copy from a not-aligned src to an aligned dst using shifts. + * Handles 4 words per loop. + */ + + depw,z src,28,2,t0 + subi 32,t0,t0 + mtsar t0 + extru len,31,2,t0 + cmpib,= 2,t0,.Lcase2 + /* Make src aligned by rounding it down. */ + depi 0,31,2,src + + cmpiclr,<> 3,t0,%r0 + b,n .Lcase3 + cmpiclr,<> 1,t0,%r0 + b,n .Lcase1 +.Lcase0: + cmpb,COND(=) %r0,len,.Lcda_finish + nop + +1: ldw,ma 4(srcspc,src), a3 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) +1: ldw,ma 4(srcspc,src), a0 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) + b,n .Ldo3 +.Lcase1: +1: ldw,ma 4(srcspc,src), a2 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) +1: ldw,ma 4(srcspc,src), a3 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) + ldo -1(len),len + cmpb,COND(=),n %r0,len,.Ldo0 +.Ldo4: +1: ldw,ma 4(srcspc,src), a0 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) + shrpw a2, a3, %sar, t0 +1: stw,ma t0, 4(dstspc,dst) + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done) +.Ldo3: +1: ldw,ma 4(srcspc,src), a1 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) + shrpw a3, a0, %sar, t0 +1: stw,ma t0, 4(dstspc,dst) + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done) +.Ldo2: +1: ldw,ma 4(srcspc,src), a2 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) + shrpw a0, a1, %sar, t0 +1: stw,ma t0, 4(dstspc,dst) + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done) +.Ldo1: +1: ldw,ma 4(srcspc,src), a3 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) + shrpw a1, a2, %sar, t0 +1: stw,ma t0, 4(dstspc,dst) + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done) + ldo -4(len),len + cmpb,COND(<>) %r0,len,.Ldo4 + nop +.Ldo0: + shrpw a2, a3, %sar, t0 +1: stw,ma t0, 4(dstspc,dst) + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done) + +.Lcda_rdfault: +.Lcda_finish: + /* calculate new src, dst and len and jump to byte-copy loop */ + sub dst,save_dst,t0 + add save_src,t0,src + b .Lbyte_loop + sub save_len,t0,len + +.Lcase3: +1: ldw,ma 4(srcspc,src), a0 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) +1: ldw,ma 4(srcspc,src), a1 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) + b .Ldo2 + ldo 1(len),len +.Lcase2: +1: ldw,ma 4(srcspc,src), a1 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) +1: ldw,ma 4(srcspc,src), a2 + ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault) + b .Ldo1 + ldo 2(len),len + + + /* fault exception fixup handlers: */ +#ifdef CONFIG_64BIT +.Lcopy16_fault: + b .Lcopy_done +10: std,ma t1,8(dstspc,dst) + ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done) +#endif + +.Lcopy8_fault: + b .Lcopy_done +10: stw,ma t1,4(dstspc,dst) + ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done) + + .exit +ENDPROC_CFI(pa_memcpy) + .procend + .end diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index f82ff10ed974..99115cd9e790 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c @@ -2,7 +2,7 @@ * Optimized memory copy routines. * * Copyright (C) 2004 Randolph Chung <tausq@debian.org> - * Copyright (C) 2013 Helge Deller <deller@gmx.de> + * Copyright (C) 2013-2017 Helge Deller <deller@gmx.de> * * 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 @@ -21,493 +21,40 @@ * Portions derived from the GNU C Library * Copyright (C) 1991, 1997, 2003 Free Software Foundation, Inc. * - * Several strategies are tried to try to get the best performance for various - * conditions. In the optimal case, we copy 64-bytes in an unrolled loop using - * fp regs. This is followed by loops that copy 32- or 16-bytes at a time using - * general registers. Unaligned copies are handled either by aligning the - * destination and then using shift-and-write method, or in a few cases by - * falling back to a byte-at-a-time copy. - * - * I chose to implement this in C because it is easier to maintain and debug, - * and in my experiments it appears that the C code generated by gcc (3.3/3.4 - * at the time of writing) is fairly optimal. Unfortunately some of the - * semantics of the copy routine (exception handling) is difficult to express - * in C, so we have to play some tricks to get it to work. - * - * All the loads and stores are done via explicit asm() code in order to use - * the right space registers. - * - * Testing with various alignments and buffer sizes shows that this code is - * often >10x faster than a simple byte-at-a-time copy, even for strangely - * aligned operands. It is interesting to note that the glibc version - * of memcpy (written in C) is actually quite fast already. This routine is - * able to beat it by 30-40% for aligned copies because of the loop unrolling, - * but in some cases the glibc version is still slightly faster. This lends - * more credibility that gcc can generate very good code as long as we are - * careful. - * - * TODO: - * - cache prefetching needs more experimentation to get optimal settings - * - try not to use the post-increment address modifiers; they create additional - * interlocks - * - replace byte-copy loops with stybs sequences */ -#ifdef __KERNEL__ #include <linux/module.h> #include <linux/compiler.h> #include <linux/uaccess.h> -#define s_space "%%sr1" -#define d_space "%%sr2" -#else -#include "memcpy.h" -#define s_space "%%sr0" -#define d_space "%%sr0" -#define pa_memcpy new2_copy -#endif DECLARE_PER_CPU(struct exception_data, exception_data); -#define preserve_branch(label) do { \ - volatile int dummy = 0; \ - /* The following branch is never taken, it's just here to */ \ - /* prevent gcc from optimizing away our exception code. */ \ - if (unlikely(dummy != dummy)) \ - goto label; \ -} while (0) - -#define get_user_space() (segment_eq(get_fs(), KERNEL_DS) ? 0 : mfsp(3)) +#define get_user_space() (uaccess_kernel() ? 0 : mfsp(3)) #define get_kernel_space() (0) -#define MERGE(w0, sh_1, w1, sh_2) ({ \ - unsigned int _r; \ - asm volatile ( \ - "mtsar %3\n" \ - "shrpw %1, %2, %%sar, %0\n" \ - : "=r"(_r) \ - : "r"(w0), "r"(w1), "r"(sh_2) \ - ); \ - _r; \ -}) -#define THRESHOLD 16 - -#ifdef DEBUG_MEMCPY -#define DPRINTF(fmt, args...) do { printk(KERN_DEBUG "%s:%d:%s ", __FILE__, __LINE__, __func__ ); printk(KERN_DEBUG fmt, ##args ); } while (0) -#else -#define DPRINTF(fmt, args...) -#endif - -#define def_load_ai_insn(_insn,_sz,_tt,_s,_a,_t,_e) \ - __asm__ __volatile__ ( \ - "1:\t" #_insn ",ma " #_sz "(" _s ",%1), %0\n\t" \ - ASM_EXCEPTIONTABLE_ENTRY(1b,_e) \ - : _tt(_t), "+r"(_a) \ - : \ - : "r8") - -#define def_store_ai_insn(_insn,_sz,_tt,_s,_a,_t,_e) \ - __asm__ __volatile__ ( \ - "1:\t" #_insn ",ma %1, " #_sz "(" _s ",%0)\n\t" \ - ASM_EXCEPTIONTABLE_ENTRY(1b,_e) \ - : "+r"(_a) \ - : _tt(_t) \ - : "r8") - -#define ldbma(_s, _a, _t, _e) def_load_ai_insn(ldbs,1,"=r",_s,_a,_t,_e) -#define stbma(_s, _t, _a, _e) def_store_ai_insn(stbs,1,"r",_s,_a,_t,_e) -#define ldwma(_s, _a, _t, _e) def_load_ai_insn(ldw,4,"=r",_s,_a,_t,_e) -#define stwma(_s, _t, _a, _e) def_store_ai_insn(stw,4,"r",_s,_a,_t,_e) -#define flddma(_s, _a, _t, _e) def_load_ai_insn(fldd,8,"=f",_s,_a,_t,_e) -#define fstdma(_s, _t, _a, _e) def_store_ai_insn(fstd,8,"f",_s,_a,_t,_e) - -#define def_load_insn(_insn,_tt,_s,_o,_a,_t,_e) \ - __asm__ __volatile__ ( \ - "1:\t" #_insn " " #_o "(" _s ",%1), %0\n\t" \ - ASM_EXCEPTIONTABLE_ENTRY(1b,_e) \ - : _tt(_t) \ - : "r"(_a) \ - : "r8") - -#define def_store_insn(_insn,_tt,_s,_t,_o,_a,_e) \ - __asm__ __volatile__ ( \ - "1:\t" #_insn " %0, " #_o "(" _s ",%1)\n\t" \ - ASM_EXCEPTIONTABLE_ENTRY(1b,_e) \ - : \ - : _tt(_t), "r"(_a) \ - : "r8") - -#define ldw(_s,_o,_a,_t,_e) def_load_insn(ldw,"=r",_s,_o,_a,_t,_e) -#define stw(_s,_t,_o,_a,_e) def_store_insn(stw,"r",_s,_t,_o,_a,_e) - -#ifdef CONFIG_PREFETCH -static inline void prefetch_src(const void *addr) -{ - __asm__("ldw 0(" s_space ",%0), %%r0" : : "r" (addr)); -} - -static inline void prefetch_dst(const void *addr) -{ - __asm__("ldd 0(" d_space ",%0), %%r0" : : "r" (addr)); -} -#else -#define prefetch_src(addr) do { } while(0) -#define prefetch_dst(addr) do { } while(0) -#endif - -#define PA_MEMCPY_OK 0 -#define PA_MEMCPY_LOAD_ERROR 1 -#define PA_MEMCPY_STORE_ERROR 2 - -/* Copy from a not-aligned src to an aligned dst, using shifts. Handles 4 words - * per loop. This code is derived from glibc. - */ -static noinline unsigned long copy_dstaligned(unsigned long dst, - unsigned long src, unsigned long len) -{ - /* gcc complains that a2 and a3 may be uninitialized, but actually - * they cannot be. Initialize a2/a3 to shut gcc up. - */ - register unsigned int a0, a1, a2 = 0, a3 = 0; - int sh_1, sh_2; - - /* prefetch_src((const void *)src); */ - - /* Calculate how to shift a word read at the memory operation - aligned srcp to make it aligned for copy. */ - sh_1 = 8 * (src % sizeof(unsigned int)); - sh_2 = 8 * sizeof(unsigned int) - sh_1; - - /* Make src aligned by rounding it down. */ - src &= -sizeof(unsigned int); - - switch (len % 4) - { - case 2: - /* a1 = ((unsigned int *) src)[0]; - a2 = ((unsigned int *) src)[1]; */ - ldw(s_space, 0, src, a1, cda_ldw_exc); - ldw(s_space, 4, src, a2, cda_ldw_exc); - src -= 1 * sizeof(unsigned int); - dst -= 3 * sizeof(unsigned int); - len += 2; - goto do1; - case 3: - /* a0 = ((unsigned int *) src)[0]; - a1 = ((unsigned int *) src)[1]; */ - ldw(s_space, 0, src, a0, cda_ldw_exc); - ldw(s_space, 4, src, a1, cda_ldw_exc); - src -= 0 * sizeof(unsigned int); - dst -= 2 * sizeof(unsigned int); - len += 1; - goto do2; - case 0: - if (len == 0) - return PA_MEMCPY_OK; - /* a3 = ((unsigned int *) src)[0]; - a0 = ((unsigned int *) src)[1]; */ - ldw(s_space, 0, src, a3, cda_ldw_exc); - ldw(s_space, 4, src, a0, cda_ldw_exc); - src -=-1 * sizeof(unsigned int); - dst -= 1 * sizeof(unsigned int); - len += 0; - goto do3; - case 1: - /* a2 = ((unsigned int *) src)[0]; - a3 = ((unsigned int *) src)[1]; */ - ldw(s_space, 0, src, a2, cda_ldw_exc); - ldw(s_space, 4, src, a3, cda_ldw_exc); - src -=-2 * sizeof(unsigned int); - dst -= 0 * sizeof(unsigned int); - len -= 1; - if (len == 0) - goto do0; - goto do4; /* No-op. */ - } - - do - { - /* prefetch_src((const void *)(src + 4 * sizeof(unsigned int))); */ -do4: - /* a0 = ((unsigned int *) src)[0]; */ - ldw(s_space, 0, src, a0, cda_ldw_exc); - /* ((unsigned int *) dst)[0] = MERGE (a2, sh_1, a3, sh_2); */ - stw(d_space, MERGE (a2, sh_1, a3, sh_2), 0, dst, cda_stw_exc); -do3: - /* a1 = ((unsigned int *) src)[1]; */ - ldw(s_space, 4, src, a1, cda_ldw_exc); - /* ((unsigned int *) dst)[1] = MERGE (a3, sh_1, a0, sh_2); */ - stw(d_space, MERGE (a3, sh_1, a0, sh_2), 4, dst, cda_stw_exc); -do2: - /* a2 = ((unsigned int *) src)[2]; */ - ldw(s_space, 8, src, a2, cda_ldw_exc); - /* ((unsigned int *) dst)[2] = MERGE (a0, sh_1, a1, sh_2); */ - stw(d_space, MERGE (a0, sh_1, a1, sh_2), 8, dst, cda_stw_exc); -do1: - /* a3 = ((unsigned int *) src)[3]; */ - ldw(s_space, 12, src, a3, cda_ldw_exc); - /* ((unsigned int *) dst)[3] = MERGE (a1, sh_1, a2, sh_2); */ - stw(d_space, MERGE (a1, sh_1, a2, sh_2), 12, dst, cda_stw_exc); - - src += 4 * sizeof(unsigned int); - dst += 4 * sizeof(unsigned int); - len -= 4; - } - while (len != 0); - -do0: - /* ((unsigned int *) dst)[0] = MERGE (a2, sh_1, a3, sh_2); */ - stw(d_space, MERGE (a2, sh_1, a3, sh_2), 0, dst, cda_stw_exc); - - preserve_branch(handle_load_error); - preserve_branch(handle_store_error); - - return PA_MEMCPY_OK; - -handle_load_error: - __asm__ __volatile__ ("cda_ldw_exc:\n"); - return PA_MEMCPY_LOAD_ERROR; - -handle_store_error: - __asm__ __volatile__ ("cda_stw_exc:\n"); - return PA_MEMCPY_STORE_ERROR; -} - - -/* Returns PA_MEMCPY_OK, PA_MEMCPY_LOAD_ERROR or PA_MEMCPY_STORE_ERROR. - * In case of an access fault the faulty address can be read from the per_cpu - * exception data struct. */ -static noinline unsigned long pa_memcpy_internal(void *dstp, const void *srcp, - unsigned long len) -{ - register unsigned long src, dst, t1, t2, t3; - register unsigned char *pcs, *pcd; - register unsigned int *pws, *pwd; - register double *pds, *pdd; - unsigned long ret; - - src = (unsigned long)srcp; - dst = (unsigned long)dstp; - pcs = (unsigned char *)srcp; - pcd = (unsigned char *)dstp; - - /* prefetch_src((const void *)srcp); */ - - if (len < THRESHOLD) - goto byte_copy; - - /* Check alignment */ - t1 = (src ^ dst); - if (unlikely(t1 & (sizeof(double)-1))) - goto unaligned_copy; - - /* src and dst have same alignment. */ - - /* Copy bytes till we are double-aligned. */ - t2 = src & (sizeof(double) - 1); - if (unlikely(t2 != 0)) { - t2 = sizeof(double) - t2; - while (t2 && len) { - /* *pcd++ = *pcs++; */ - ldbma(s_space, pcs, t3, pmc_load_exc); - len--; - stbma(d_space, t3, pcd, pmc_store_exc); - t2--; - } - } - - pds = (double *)pcs; - pdd = (double *)pcd; - -#if 0 - /* Copy 8 doubles at a time */ - while (len >= 8*sizeof(double)) { - register double r1, r2, r3, r4, r5, r6, r7, r8; - /* prefetch_src((char *)pds + L1_CACHE_BYTES); */ - flddma(s_space, pds, r1, pmc_load_exc); - flddma(s_space, pds, r2, pmc_load_exc); - flddma(s_space, pds, r3, pmc_load_exc); - flddma(s_space, pds, r4, pmc_load_exc); - fstdma(d_space, r1, pdd, pmc_store_exc); - fstdma(d_space, r2, pdd, pmc_store_exc); - fstdma(d_space, r3, pdd, pmc_store_exc); - fstdma(d_space, r4, pdd, pmc_store_exc); - -#if 0 - if (L1_CACHE_BYTES <= 32) - prefetch_src((char *)pds + L1_CACHE_BYTES); -#endif - flddma(s_space, pds, r5, pmc_load_exc); - flddma(s_space, pds, r6, pmc_load_exc); - flddma(s_space, pds, r7, pmc_load_exc); - flddma(s_space, pds, r8, pmc_load_exc); - fstdma(d_space, r5, pdd, pmc_store_exc); - fstdma(d_space, r6, pdd, pmc_store_exc); - fstdma(d_space, r7, pdd, pmc_store_exc); - fstdma(d_space, r8, pdd, pmc_store_exc); - len -= 8*sizeof(double); - } -#endif - - pws = (unsigned int *)pds; - pwd = (unsigned int *)pdd; - -word_copy: - while (len >= 8*sizeof(unsigned int)) { - register unsigned int r1,r2,r3,r4,r5,r6,r7,r8; - /* prefetch_src((char *)pws + L1_CACHE_BYTES); */ - ldwma(s_space, pws, r1, pmc_load_exc); - ldwma(s_space, pws, r2, pmc_load_exc); - ldwma(s_space, pws, r3, pmc_load_exc); - ldwma(s_space, pws, r4, pmc_load_exc); - stwma(d_space, r1, pwd, pmc_store_exc); - stwma(d_space, r2, pwd, pmc_store_exc); - stwma(d_space, r3, pwd, pmc_store_exc); - stwma(d_space, r4, pwd, pmc_store_exc); - - ldwma(s_space, pws, r5, pmc_load_exc); - ldwma(s_space, pws, r6, pmc_load_exc); - ldwma(s_space, pws, r7, pmc_load_exc); - ldwma(s_space, pws, r8, pmc_load_exc); - stwma(d_space, r5, pwd, pmc_store_exc); - stwma(d_space, r6, pwd, pmc_store_exc); - stwma(d_space, r7, pwd, pmc_store_exc); - stwma(d_space, r8, pwd, pmc_store_exc); - len -= 8*sizeof(unsigned int); - } - - while (len >= 4*sizeof(unsigned int)) { - register unsigned int r1,r2,r3,r4; - ldwma(s_space, pws, r1, pmc_load_exc); - ldwma(s_space, pws, r2, pmc_load_exc); - ldwma(s_space, pws, r3, pmc_load_exc); - ldwma(s_space, pws, r4, pmc_load_exc); - stwma(d_space, r1, pwd, pmc_store_exc); - stwma(d_space, r2, pwd, pmc_store_exc); - stwma(d_space, r3, pwd, pmc_store_exc); - stwma(d_space, r4, pwd, pmc_store_exc); - len -= 4*sizeof(unsigned int); - } - - pcs = (unsigned char *)pws; - pcd = (unsigned char *)pwd; - -byte_copy: - while (len) { - /* *pcd++ = *pcs++; */ - ldbma(s_space, pcs, t3, pmc_load_exc); - stbma(d_space, t3, pcd, pmc_store_exc); - len--; - } - - return PA_MEMCPY_OK; - -unaligned_copy: - /* possibly we are aligned on a word, but not on a double... */ - if (likely((t1 & (sizeof(unsigned int)-1)) == 0)) { - t2 = src & (sizeof(unsigned int) - 1); - - if (unlikely(t2 != 0)) { - t2 = sizeof(unsigned int) - t2; - while (t2) { - /* *pcd++ = *pcs++; */ - ldbma(s_space, pcs, t3, pmc_load_exc); - stbma(d_space, t3, pcd, pmc_store_exc); - len--; - t2--; - } - } - - pws = (unsigned int *)pcs; - pwd = (unsigned int *)pcd; - goto word_copy; - } - - /* Align the destination. */ - if (unlikely((dst & (sizeof(unsigned int) - 1)) != 0)) { - t2 = sizeof(unsigned int) - (dst & (sizeof(unsigned int) - 1)); - while (t2) { - /* *pcd++ = *pcs++; */ - ldbma(s_space, pcs, t3, pmc_load_exc); - stbma(d_space, t3, pcd, pmc_store_exc); - len--; - t2--; - } - dst = (unsigned long)pcd; - src = (unsigned long)pcs; - } - - ret = copy_dstaligned(dst, src, len / sizeof(unsigned int)); - if (ret) - return ret; - - pcs += (len & -sizeof(unsigned int)); - pcd += (len & -sizeof(unsigned int)); - len %= sizeof(unsigned int); - - preserve_branch(handle_load_error); - preserve_branch(handle_store_error); - - goto byte_copy; - -handle_load_error: - __asm__ __volatile__ ("pmc_load_exc:\n"); - return PA_MEMCPY_LOAD_ERROR; - -handle_store_error: - __asm__ __volatile__ ("pmc_store_exc:\n"); - return PA_MEMCPY_STORE_ERROR; -} - - /* Returns 0 for success, otherwise, returns number of bytes not transferred. */ -static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len) -{ - unsigned long ret, fault_addr, reference; - struct exception_data *d; - - ret = pa_memcpy_internal(dstp, srcp, len); - if (likely(ret == PA_MEMCPY_OK)) - return 0; - - /* if a load or store fault occured we can get the faulty addr */ - d = this_cpu_ptr(&exception_data); - fault_addr = d->fault_addr; - - /* error in load or store? */ - if (ret == PA_MEMCPY_LOAD_ERROR) - reference = (unsigned long) srcp; - else - reference = (unsigned long) dstp; - - DPRINTF("pa_memcpy: fault type = %lu, len=%lu fault_addr=%lu ref=%lu\n", - ret, len, fault_addr, reference); +extern unsigned long pa_memcpy(void *dst, const void *src, + unsigned long len); - if (fault_addr >= reference) - return len - (fault_addr - reference); - else - return len; -} - -#ifdef __KERNEL__ -unsigned long __copy_to_user(void __user *dst, const void *src, - unsigned long len) +unsigned long raw_copy_to_user(void __user *dst, const void *src, + unsigned long len) { mtsp(get_kernel_space(), 1); mtsp(get_user_space(), 2); return pa_memcpy((void __force *)dst, src, len); } -EXPORT_SYMBOL(__copy_to_user); +EXPORT_SYMBOL(raw_copy_to_user); -unsigned long __copy_from_user(void *dst, const void __user *src, +unsigned long raw_copy_from_user(void *dst, const void __user *src, unsigned long len) { mtsp(get_user_space(), 1); mtsp(get_kernel_space(), 2); return pa_memcpy(dst, (void __force *)src, len); } -EXPORT_SYMBOL(__copy_from_user); +EXPORT_SYMBOL(raw_copy_from_user); -unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len) +unsigned long raw_copy_in_user(void __user *dst, const void __user *src, unsigned long len) { mtsp(get_user_space(), 1); mtsp(get_user_space(), 2); @@ -523,7 +70,7 @@ void * memcpy(void * dst,const void *src, size_t count) return dst; } -EXPORT_SYMBOL(copy_in_user); +EXPORT_SYMBOL(raw_copy_in_user); EXPORT_SYMBOL(memcpy); long probe_kernel_read(void *dst, const void *src, size_t size) @@ -537,5 +84,3 @@ long probe_kernel_read(void *dst, const void *src, size_t size) return __probe_kernel_read(dst, src, size); } - -#endif diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index deab89a8915a..32ec22146141 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -150,6 +150,23 @@ int fixup_exception(struct pt_regs *regs) d->fault_space = regs->isr; d->fault_addr = regs->ior; + /* + * Fix up get_user() and put_user(). + * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant + * bit in the relative address of the fixup routine to indicate + * that %r8 should be loaded with -EFAULT to report a userspace + * access error. + */ + if (fix->fixup & 1) { + regs->gr[8] = -EFAULT; + + /* zero target register for get_user() */ + if (parisc_acctyp(0, regs->iir) == VM_READ) { + int treg = regs->iir & 0x1f; + regs->gr[treg] = 0; + } + } + regs->iaoq[0] = (unsigned long)&fix->fixup + fix->fixup; regs->iaoq[0] &= ~3; /* diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 97a8bc8a095c..053382616533 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -117,7 +117,6 @@ config PPC select GENERIC_STRNLEN_USER select GENERIC_TIME_VSYSCALL_OLD select HAVE_ARCH_AUDITSYSCALL - select HAVE_ARCH_HARDENED_USERCOPY select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KGDB select HAVE_ARCH_SECCOMP_FILTER diff --git a/arch/powerpc/configs/85xx-hw.config b/arch/powerpc/configs/85xx-hw.config index 528ff0e714e6..c03d0fb16665 100644 --- a/arch/powerpc/configs/85xx-hw.config +++ b/arch/powerpc/configs/85xx-hw.config @@ -16,9 +16,8 @@ CONFIG_DAVICOM_PHY=y CONFIG_DMADEVICES=y CONFIG_E1000E=y CONFIG_E1000=y -CONFIG_EDAC_MM_EDAC=y -CONFIG_EDAC_MPC85XX=y CONFIG_EDAC=y +CONFIG_EDAC_MPC85XX=y CONFIG_EEPROM_AT24=y CONFIG_EEPROM_LEGACY=y CONFIG_FB_FSL_DIU=y diff --git a/arch/powerpc/configs/85xx/ge_imp3a_defconfig b/arch/powerpc/configs/85xx/ge_imp3a_defconfig index c79283be5680..a917f7afb4f9 100644 --- a/arch/powerpc/configs/85xx/ge_imp3a_defconfig +++ b/arch/powerpc/configs/85xx/ge_imp3a_defconfig @@ -155,7 +155,6 @@ CONFIG_USB_OHCI_HCD_PPC_OF_BE=y CONFIG_USB_OHCI_HCD_PPC_OF_LE=y CONFIG_USB_STORAGE=y CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y CONFIG_EDAC_MPC85XX=y CONFIG_RTC_CLASS=y # CONFIG_RTC_INTF_PROC is not set diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig index dbd961de251e..72900b84d3e0 100644 --- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig +++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig @@ -116,7 +116,6 @@ CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y CONFIG_RTC_DRV_CMOS=y diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index 2d7fcbe047ac..aa564599e368 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -179,7 +179,6 @@ CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y CONFIG_EDAC_CELL=y CONFIG_UIO=m CONFIG_EXT2_FS=y diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index 5553c5ce4274..fe43ff47bd2f 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig @@ -142,7 +142,6 @@ CONFIG_USB_UHCI_HCD=y CONFIG_USB_SL811_HCD=y CONFIG_USB_STORAGE=y CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y CONFIG_EDAC_PASEMI=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 4f1288b04303..f2e03f032041 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -262,7 +262,6 @@ CONFIG_INFINIBAND_IPOIB_CM=y CONFIG_INFINIBAND_SRP=m CONFIG_INFINIBAND_ISER=m CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y CONFIG_EDAC_PASEMI=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index 11a3473f9e2e..6340e6c53c54 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig @@ -173,7 +173,6 @@ CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_ISER=m CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y CONFIG_FS_DAX=y diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 1d2d69dd6409..18d0d60dadbf 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -988,8 +988,7 @@ CONFIG_LEDS_TRIGGER_BACKLIGHT=m CONFIG_LEDS_TRIGGER_DEFAULT_ON=m CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y -CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC=m CONFIG_RTC_CLASS=y # CONFIG_RTC_HCTOSYS is not set CONFIG_RTC_DRV_DS1307=m diff --git a/arch/powerpc/crypto/crc32c-vpmsum_glue.c b/arch/powerpc/crypto/crc32c-vpmsum_glue.c index 411994551afc..f058e0c3e4d4 100644 --- a/arch/powerpc/crypto/crc32c-vpmsum_glue.c +++ b/arch/powerpc/crypto/crc32c-vpmsum_glue.c @@ -33,10 +33,13 @@ static u32 crc32c_vpmsum(u32 crc, unsigned char const *p, size_t len) } if (len & ~VMX_ALIGN_MASK) { + preempt_disable(); pagefault_disable(); enable_kernel_altivec(); crc = __crc32c_vpmsum(crc, p, len & ~VMX_ALIGN_MASK); + disable_kernel_altivec(); pagefault_enable(); + preempt_enable(); } tail = len & VMX_ALIGN_MASK; diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index 3a39283333c3..f2c562a0a427 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -85,12 +85,12 @@ } \ } while (0) -#define __WARN_TAINT(taint) do { \ +#define __WARN_FLAGS(flags) do { \ __asm__ __volatile__( \ "1: twi 31,0,0\n" \ _EMIT_BUG_ENTRY \ : : "i" (__FILE__), "i" (__LINE__), \ - "i" (BUGFLAG_TAINT(taint)), \ + "i" (BUGFLAG_WARNING|(flags)), \ "i" (sizeof(struct bug_entry))); \ } while (0) diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 14752eee3d0c..ed3beadd2cc5 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -236,9 +236,9 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) mtctr reg; \ bctr -#define BRANCH_LINK_TO_FAR(reg, label) \ - __LOAD_FAR_HANDLER(reg, label); \ - mtctr reg; \ +#define BRANCH_LINK_TO_FAR(label) \ + __LOAD_FAR_HANDLER(r12, label); \ + mtctr r12; \ bctrl /* @@ -265,7 +265,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define BRANCH_TO_COMMON(reg, label) \ b label -#define BRANCH_LINK_TO_FAR(reg, label) \ +#define BRANCH_LINK_TO_FAR(label) \ bl label #define BRANCH_TO_KVM(reg, label) \ diff --git a/arch/powerpc/include/asm/extable.h b/arch/powerpc/include/asm/extable.h new file mode 100644 index 000000000000..07cc45cd86d9 --- /dev/null +++ b/arch/powerpc/include/asm/extable.h @@ -0,0 +1,29 @@ +#ifndef _ARCH_POWERPC_EXTABLE_H +#define _ARCH_POWERPC_EXTABLE_H + +/* + * The exception table consists of pairs of relative addresses: the first is + * the address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out what + * to do. + * + * All the routines below use bits of fixup code that are out of line with the + * main instruction path. This means when everything is well, we don't even + * have to jump over them. Further, they do not intrude on our cache or tlb + * entries. + */ + +#define ARCH_HAS_RELATIVE_EXTABLE + +struct exception_table_entry { + int insn; + int fixup; +}; + +static inline unsigned long extable_fixup(const struct exception_table_entry *x) +{ + return (unsigned long)&x->fixup + x->fixup; +} + +#endif diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h index 0e6add3187bc..5c0d8a8cdae5 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -1,18 +1,11 @@ #ifndef _ARCH_POWERPC_UACCESS_H #define _ARCH_POWERPC_UACCESS_H -#ifdef __KERNEL__ -#ifndef __ASSEMBLY__ - -#include <linux/sched.h> -#include <linux/errno.h> #include <asm/asm-compat.h> #include <asm/ppc_asm.h> #include <asm/processor.h> #include <asm/page.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 +#include <asm/extable.h> /* * The fs value determines whether argument validity checking should be @@ -64,31 +57,6 @@ __access_ok((__force unsigned long)(addr), (size), get_fs())) /* - * The exception table consists of pairs of relative addresses: the first is - * the address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out what - * to do. - * - * All the routines below use bits of fixup code that are out of line with the - * main instruction path. This means when everything is well, we don't even - * have to jump over them. Further, they do not intrude on our cache or tlb - * entries. - */ - -#define ARCH_HAS_RELATIVE_EXTABLE - -struct exception_table_entry { - int insn; - int fixup; -}; - -static inline unsigned long extable_fixup(const struct exception_table_entry *x) -{ - return (unsigned long)&x->fixup + x->fixup; -} - -/* * These are the main single-value transfer routines. They automatically * use the right size if we just have the right pointer type. * @@ -301,42 +269,19 @@ extern unsigned long __copy_tofrom_user(void __user *to, #ifndef __powerpc64__ -static inline unsigned long copy_from_user(void *to, - const void __user *from, unsigned long n) -{ - if (likely(access_ok(VERIFY_READ, from, n))) { - check_object_size(to, n, false); - return __copy_tofrom_user((__force void __user *)to, from, n); - } - memset(to, 0, n); - return n; -} - -static inline unsigned long copy_to_user(void __user *to, - const void *from, unsigned long n) -{ - if (access_ok(VERIFY_WRITE, to, n)) { - check_object_size(from, n, true); - return __copy_tofrom_user(to, (__force void __user *)from, n); - } - return n; -} +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER #else /* __powerpc64__ */ -#define __copy_in_user(to, from, size) \ - __copy_tofrom_user((to), (from), (size)) - -extern unsigned long copy_from_user(void *to, const void __user *from, - unsigned long n); -extern unsigned long copy_to_user(void __user *to, const void *from, - unsigned long n); -extern unsigned long copy_in_user(void __user *to, const void __user *from, - unsigned long n); - +static inline unsigned long +raw_copy_in_user(void __user *to, const void __user *from, unsigned long n) +{ + return __copy_tofrom_user(to, from, n); +} #endif /* __powerpc64__ */ -static inline unsigned long __copy_from_user_inatomic(void *to, +static inline unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) { if (__builtin_constant_p(n) && (n <= 8)) { @@ -360,12 +305,10 @@ static inline unsigned long __copy_from_user_inatomic(void *to, return 0; } - check_object_size(to, n, false); - return __copy_tofrom_user((__force void __user *)to, from, n); } -static inline unsigned long __copy_to_user_inatomic(void __user *to, +static inline unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) { if (__builtin_constant_p(n) && (n <= 8)) { @@ -389,25 +332,9 @@ static inline unsigned long __copy_to_user_inatomic(void __user *to, return 0; } - check_object_size(from, n, true); - return __copy_tofrom_user(to, (__force const void __user *)from, n); } -static inline unsigned long __copy_from_user(void *to, - const void __user *from, unsigned long size) -{ - might_fault(); - return __copy_from_user_inatomic(to, from, size); -} - -static inline unsigned long __copy_to_user(void __user *to, - const void *from, unsigned long size) -{ - might_fault(); - return __copy_to_user_inatomic(to, from, size); -} - extern unsigned long __clear_user(void __user *addr, unsigned long size); static inline unsigned long clear_user(void __user *addr, unsigned long size) @@ -422,7 +349,4 @@ extern long strncpy_from_user(char *dst, const char __user *src, long count); extern __must_check long strlen_user(const char __user *str); extern __must_check long strnlen_user(const char __user *str, long n); -#endif /* __ASSEMBLY__ */ -#endif /* __KERNEL__ */ - #endif /* _ARCH_POWERPC_UACCESS_H */ diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index cbc7c42cdb74..ec7a8b099dd9 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -807,14 +807,25 @@ int fix_alignment(struct pt_regs *regs) nb = aligninfo[instr].len; flags = aligninfo[instr].flags; - /* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */ - if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) { - nb = 8; - flags = LD+SW; - } else if (IS_XFORM(instruction) && - ((instruction >> 1) & 0x3ff) == 660) { - nb = 8; - flags = ST+SW; + /* + * Handle some cases which give overlaps in the DSISR values. + */ + if (IS_XFORM(instruction)) { + switch (get_xop(instruction)) { + case 532: /* ldbrx */ + nb = 8; + flags = LD+SW; + break; + case 660: /* stdbrx */ + nb = 8; + flags = ST+SW; + break; + case 20: /* lwarx */ + case 84: /* ldarx */ + case 116: /* lharx */ + case 276: /* lqarx */ + return 0; /* not emulated ever */ + } } /* Byteswap little endian loads and stores */ diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 6432d4bf08c8..767ef6d68c9e 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -689,7 +689,7 @@ resume_kernel: addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ - lwz r3,GPR1(r1) + ld r3,GPR1(r1) subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */ mr r4,r1 /* src: current exception frame */ mr r1,r3 /* Reroute the trampoline frame to r1 */ @@ -703,8 +703,8 @@ resume_kernel: addi r6,r6,8 bdnz 2b - /* Do real store operation to complete stwu */ - lwz r5,GPR1(r1) + /* Do real store operation to complete stdu */ + ld r5,GPR1(r1) std r8,0(r5) /* Clear _TIF_EMULATE_STACK_STORE flag */ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 857bf7c5b946..6353019966e6 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -982,7 +982,7 @@ TRAMP_REAL_BEGIN(hmi_exception_early) EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN) EXCEPTION_PROLOG_COMMON_3(0xe60) addi r3,r1,STACK_FRAME_OVERHEAD - BRANCH_LINK_TO_FAR(r4, hmi_exception_realmode) + BRANCH_LINK_TO_FAR(hmi_exception_realmode) /* Function call ABI */ /* Windup the stack. */ /* Move original HSRR0 and HSRR1 into the respective regs */ ld r9,_MSR(r1) diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index ae179cb1bb3c..c119044cad0d 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -67,7 +67,7 @@ PPC64_CACHES: * flush all bytes from start through stop-1 inclusive */ -_GLOBAL(flush_icache_range) +_GLOBAL_TOC(flush_icache_range) BEGIN_FTR_SECTION PURGE_PREFETCHED_INS blr @@ -120,7 +120,7 @@ EXPORT_SYMBOL(flush_icache_range) * * flush all bytes from start to stop-1 inclusive */ -_GLOBAL(flush_dcache_range) +_GLOBAL_TOC(flush_dcache_range) /* * Flush the data cache to memory diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 9cfaa8b69b5f..f997154dfc41 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -236,6 +236,15 @@ static void cpu_ready_for_interrupts(void) mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); } + /* + * Fixup HFSCR:TM based on CPU features. The bit is set by our + * early asm init because at that point we haven't updated our + * CPU features from firmware and device-tree. Here we have, + * so let's do it. + */ + if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP)) + mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM); + /* Set IR and DR in PACA MSR */ get_paca()->kernel_msr = MSR_KERNEL; } diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 46f89e66a273..d68ed1f004a3 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -787,24 +787,21 @@ static struct sched_domain_topology_level powerpc_topology[] = { { NULL, }, }; -void __init smp_cpus_done(unsigned int max_cpus) +static __init long smp_setup_cpu_workfn(void *data __always_unused) { - cpumask_var_t old_mask; + smp_ops->setup_cpu(boot_cpuid); + return 0; +} - /* We want the setup_cpu() here to be called from CPU 0, but our - * init thread may have been "borrowed" by another CPU in the meantime - * se we pin us down to CPU 0 for a short while +void __init smp_cpus_done(unsigned int max_cpus) +{ + /* + * We want the setup_cpu() here to be called on the boot CPU, but + * init might run on any CPU, so make sure it's invoked on the boot + * CPU. */ - alloc_cpumask_var(&old_mask, GFP_NOWAIT); - cpumask_copy(old_mask, ¤t->cpus_allowed); - set_cpus_allowed_ptr(current, cpumask_of(boot_cpuid)); - if (smp_ops && smp_ops->setup_cpu) - smp_ops->setup_cpu(boot_cpuid); - - set_cpus_allowed_ptr(current, old_mask); - - free_cpumask_var(old_mask); + work_on_cpu_safe(boot_cpuid, smp_setup_cpu_workfn, NULL); if (smp_ops && smp_ops->bringup_done) smp_ops->bringup_done(); @@ -812,7 +809,6 @@ void __init smp_cpus_done(unsigned int max_cpus) dump_numa_cpu_topology(); set_sched_topology(powerpc_topology); - } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 07b90725855e..2b33cfaac7b8 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -995,8 +995,10 @@ static void __init init_decrementer_clockevent(void) decrementer_clockevent.max_delta_ns = clockevent_delta2ns(decrementer_max, &decrementer_clockevent); + decrementer_clockevent.max_delta_ticks = decrementer_max; decrementer_clockevent.min_delta_ns = clockevent_delta2ns(2, &decrementer_clockevent); + decrementer_clockevent.min_delta_ticks = 2; register_decrementer_clockevent(cpu); } diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 7394b770ae1f..1c24c894c908 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -312,6 +312,8 @@ SECTIONS NOSAVE_DATA } + BUG_TABLE + . = ALIGN(PAGE_SIZE); _edata = .; PROVIDE32 (edata = .); diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 8c68145ba1bd..710e491206ed 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -1487,6 +1487,10 @@ long kvm_vm_ioctl_resize_hpt_prepare(struct kvm *kvm, /* start new resize */ resize = kzalloc(sizeof(*resize), GFP_KERNEL); + if (!resize) { + ret = -ENOMEM; + goto out; + } resize->order = shift; resize->kvm = kvm; INIT_WORK(&resize->work, resize_hpt_prepare_work); diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 2b5e09020cfe..ed7dfce331e0 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -14,7 +14,7 @@ obj-y += string.o alloc.o crtsavres.o code-patching.o \ obj-$(CONFIG_PPC32) += div64.o copy_32.o -obj64-y += copypage_64.o copyuser_64.o usercopy_64.o mem_64.o hweight_64.o \ +obj64-y += copypage_64.o copyuser_64.o mem_64.o hweight_64.o \ copyuser_power7.o string_64.o copypage_power7.o memcpy_power7.o \ memcpy_64.o memcmp_64.o diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S index ff0d894d7ff9..8aedbb5f4b86 100644 --- a/arch/powerpc/lib/copy_32.S +++ b/arch/powerpc/lib/copy_32.S @@ -477,18 +477,6 @@ _GLOBAL(__copy_tofrom_user) bdnz 130b /* then clear out the destination: r3 bytes starting at 4(r6) */ 132: mfctr r3 - srwi. r0,r3,2 - li r9,0 - mtctr r0 - beq 113f -112: stwu r9,4(r6) - bdnz 112b -113: andi. r0,r3,3 - mtctr r0 - beq 120f -114: stb r9,4(r6) - addi r6,r6,1 - bdnz 114b 120: blr EX_TABLE(30b,108b) @@ -497,7 +485,5 @@ _GLOBAL(__copy_tofrom_user) EX_TABLE(41b,111b) EX_TABLE(130b,132b) EX_TABLE(131b,120b) - EX_TABLE(112b,120b) - EX_TABLE(114b,120b) EXPORT_SYMBOL(__copy_tofrom_user) diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S index aee6e24e81ab..08da06e1bd72 100644 --- a/arch/powerpc/lib/copyuser_64.S +++ b/arch/powerpc/lib/copyuser_64.S @@ -319,32 +319,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) blr /* - * here we have trapped again, need to clear ctr bytes starting at r3 + * here we have trapped again, amount remaining is in ctr. */ -143: mfctr r5 - li r0,0 - mr r4,r3 - mr r3,r5 /* return the number of bytes not copied */ -1: andi. r9,r4,7 - beq 3f -90: stb r0,0(r4) - addic. r5,r5,-1 - addi r4,r4,1 - bne 1b - blr -3: cmpldi cr1,r5,8 - srdi r9,r5,3 - andi. r5,r5,7 - blt cr1,93f - mtctr r9 -91: std r0,0(r4) - addi r4,r4,8 - bdnz 91b -93: beqlr - mtctr r5 -92: stb r0,0(r4) - addi r4,r4,1 - bdnz 92b +143: mfctr r3 blr /* @@ -389,10 +366,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) ld r5,-8(r1) add r6,r6,r5 subf r3,r3,r6 /* #bytes not copied */ -190: -191: -192: - blr /* #bytes not copied in r3 */ + blr EX_TABLE(20b,120b) EX_TABLE(220b,320b) @@ -451,9 +425,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD) EX_TABLE(88b,188b) EX_TABLE(43b,143b) EX_TABLE(89b,189b) - EX_TABLE(90b,190b) - EX_TABLE(91b,191b) - EX_TABLE(92b,192b) /* * Routine to copy a whole page of data, optimized for POWER4. diff --git a/arch/powerpc/lib/usercopy_64.c b/arch/powerpc/lib/usercopy_64.c deleted file mode 100644 index 9bd3a3dad78d..000000000000 --- a/arch/powerpc/lib/usercopy_64.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Functions which are too large to be inlined. - * - * 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 <linux/module.h> -#include <linux/uaccess.h> - -unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) -{ - if (likely(access_ok(VERIFY_READ, from, n))) - n = __copy_from_user(to, from, n); - else - memset(to, 0, n); - return n; -} - -unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) -{ - if (likely(access_ok(VERIFY_WRITE, to, n))) - n = __copy_to_user(to, from, n); - return n; -} - -unsigned long copy_in_user(void __user *to, const void __user *from, - unsigned long n) -{ - might_sleep(); - if (likely(access_ok(VERIFY_READ, from, n) && - access_ok(VERIFY_WRITE, to, n))) - n =__copy_tofrom_user(to, from, n); - return n; -} - -EXPORT_SYMBOL(copy_from_user); -EXPORT_SYMBOL(copy_to_user); -EXPORT_SYMBOL(copy_in_user); - diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index cc332608e656..65bb8f33b399 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -638,6 +638,10 @@ static void native_flush_hash_range(unsigned long number, int local) unsigned long psize = batch->psize; int ssize = batch->ssize; int i; + unsigned int use_local; + + use_local = local && mmu_has_feature(MMU_FTR_TLBIEL) && + mmu_psize_defs[psize].tlbiel && !cxl_ctx_in_use(); local_irq_save(flags); @@ -667,8 +671,7 @@ static void native_flush_hash_range(unsigned long number, int local) } pte_iterate_hashed_end(); } - if (mmu_has_feature(MMU_FTR_TLBIEL) && - mmu_psize_defs[psize].tlbiel && local) { + if (use_local) { asm volatile("ptesync":::"memory"); for (i = 0; i < number; i++) { vpn = batch->vpn[i]; diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index a2dcef0aacc7..b8b143432381 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -124,7 +124,6 @@ config S390 select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_EARLY_PFN_TO_NID - select HAVE_ARCH_HARDENED_USERCOPY select HAVE_ARCH_JUMP_LABEL select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES select HAVE_ARCH_SECCOMP_FILTER diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c index fa95041fa9f6..33ca29333e18 100644 --- a/arch/s390/boot/compressed/misc.c +++ b/arch/s390/boot/compressed/misc.c @@ -141,31 +141,34 @@ static void check_ipl_parmblock(void *start, unsigned long size) unsigned long decompress_kernel(void) { - unsigned long output_addr; - unsigned char *output; + void *output, *kernel_end; - output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL; - check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start); - memset(&_bss, 0, &_ebss - &_bss); - free_mem_ptr = (unsigned long)&_end; - free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; - output = (unsigned char *) output_addr; + output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE); + kernel_end = output + SZ__bss_start; + check_ipl_parmblock((void *) 0, (unsigned long) kernel_end); #ifdef CONFIG_BLK_DEV_INITRD /* * Move the initrd right behind the end of the decompressed - * kernel image. + * kernel image. This also prevents initrd corruption caused by + * bss clearing since kernel_end will always be located behind the + * current bss section.. */ - if (INITRD_START && INITRD_SIZE && - INITRD_START < (unsigned long) output + SZ__bss_start) { - check_ipl_parmblock(output + SZ__bss_start, - INITRD_START + INITRD_SIZE); - memmove(output + SZ__bss_start, - (void *) INITRD_START, INITRD_SIZE); - INITRD_START = (unsigned long) output + SZ__bss_start; + if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) { + check_ipl_parmblock(kernel_end, INITRD_SIZE); + memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE); + INITRD_START = (unsigned long) kernel_end; } #endif + /* + * Clear bss section. free_mem_ptr and free_mem_end_ptr need to be + * initialized afterwards since they reside in bss. + */ + memset(&_bss, 0, &_ebss - &_bss); + free_mem_ptr = (unsigned long) &_end; + free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; + puts("Uncompressing Linux... "); __decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error); puts("Ok, booting the kernel.\n"); diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h index bf90d1fd97a5..1bbd9dbfe4e0 100644 --- a/arch/s390/include/asm/bug.h +++ b/arch/s390/include/asm/bug.h @@ -46,8 +46,8 @@ unreachable(); \ } while (0) -#define __WARN_TAINT(taint) do { \ - __EMIT_BUG(BUGFLAG_TAINT(taint)); \ +#define __WARN_FLAGS(flags) do { \ + __EMIT_BUG(BUGFLAG_WARNING|(flags)); \ } while (0) #define WARN_ON(x) ({ \ diff --git a/arch/s390/include/asm/extable.h b/arch/s390/include/asm/extable.h new file mode 100644 index 000000000000..16cfe2d62eeb --- /dev/null +++ b/arch/s390/include/asm/extable.h @@ -0,0 +1,28 @@ +#ifndef __S390_EXTABLE_H +#define __S390_EXTABLE_H +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + int insn, fixup; +}; + +static inline unsigned long extable_fixup(const struct exception_table_entry *x) +{ + return (unsigned long)&x->fixup + x->fixup; +} + +#define ARCH_HAS_RELATIVE_EXTABLE + +#endif diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 93e37b12e882..ecec682bb516 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1051,6 +1051,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, { if (!MACHINE_HAS_NX) pte_val(entry) &= ~_PAGE_NOEXEC; + if (pte_present(entry)) + pte_val(entry) &= ~_PAGE_UNUSED; if (mm_has_pgste(mm)) ptep_set_pte_at(mm, addr, ptep, entry); else diff --git a/arch/s390/include/asm/sections.h b/arch/s390/include/asm/sections.h index 5ce29fe100ba..fbd9116eb17b 100644 --- a/arch/s390/include/asm/sections.h +++ b/arch/s390/include/asm/sections.h @@ -4,6 +4,5 @@ #include <asm-generic/sections.h> extern char _eshared[], _ehead[]; -extern char __start_ro_after_init[], __end_ro_after_init[]; #endif diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 136932ff4250..78f3f093d143 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -12,13 +12,9 @@ /* * User space memory access functions */ -#include <linux/sched.h> -#include <linux/errno.h> #include <asm/processor.h> #include <asm/ctl_reg.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 +#include <asm/extable.h> /* @@ -42,7 +38,7 @@ static inline void set_fs(mm_segment_t fs) { current->thread.mm_segment = fs; - if (segment_eq(fs, KERNEL_DS)) { + if (uaccess_kernel()) { set_cpu_flag(CIF_ASCE_SECONDARY); __ctl_load(S390_lowcore.kernel_asce, 7, 7); } else { @@ -64,72 +60,14 @@ static inline int __range_ok(unsigned long addr, unsigned long size) #define access_ok(type, addr, size) __access_ok(addr, size) -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - int insn, fixup; -}; - -static inline unsigned long extable_fixup(const struct exception_table_entry *x) -{ - return (unsigned long)&x->fixup + x->fixup; -} - -#define ARCH_HAS_RELATIVE_EXTABLE - -/** - * __copy_from_user: - Copy a block of data from user space, with less checking. - * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from user space to kernel space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - */ -unsigned long __must_check __copy_from_user(void *to, const void __user *from, - unsigned long n); +unsigned long __must_check +raw_copy_from_user(void *to, const void __user *from, unsigned long n); -/** - * __copy_to_user: - Copy a block of data into user space, with less checking. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from kernel space to user space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - */ -unsigned long __must_check __copy_to_user(void __user *to, const void *from, - unsigned long n); +unsigned long __must_check +raw_copy_to_user(void __user *to, const void *from, unsigned long n); -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES @@ -147,7 +85,7 @@ unsigned long __must_check __copy_to_user(void __user *to, const void *from, " jg 2b\n" \ ".popsection\n" \ EX_TABLE(0b,3b) EX_TABLE(1b,3b) \ - : "=d" (__rc), "=Q" (*(to)) \ + : "=d" (__rc), "+Q" (*(to)) \ : "d" (size), "Q" (*(from)), \ "d" (__reg0), "K" (-EFAULT) \ : "cc"); \ @@ -218,13 +156,13 @@ static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long s static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size) { - size = __copy_to_user(ptr, x, size); + size = raw_copy_to_user(ptr, x, size); return size ? -EFAULT : 0; } static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size) { - size = __copy_from_user(x, ptr, size); + size = raw_copy_from_user(x, ptr, size); return size ? -EFAULT : 0; } @@ -314,77 +252,8 @@ int __get_user_bad(void) __attribute__((noreturn)); #define __put_user_unaligned __put_user #define __get_user_unaligned __get_user -extern void __compiletime_error("usercopy buffer size is too small") -__bad_copy_user(void); - -static inline void copy_user_overflow(int size, unsigned long count) -{ - WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); -} - -/** - * copy_to_user: - Copy a block of data into user space. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from kernel space to user space. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - */ -static inline unsigned long __must_check -copy_to_user(void __user *to, const void *from, unsigned long n) -{ - might_fault(); - return __copy_to_user(to, from, n); -} - -/** - * copy_from_user: - Copy a block of data from user space. - * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from user space to kernel space. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - */ -static inline unsigned long __must_check -copy_from_user(void *to, const void __user *from, unsigned long n) -{ - unsigned int sz = __compiletime_object_size(to); - - might_fault(); - if (unlikely(sz != -1 && sz < n)) { - if (!__builtin_constant_p(n)) - copy_user_overflow(sz, n); - else - __bad_copy_user(); - return n; - } - return __copy_from_user(to, from, n); -} - unsigned long __must_check -__copy_in_user(void __user *to, const void __user *from, unsigned long n); - -static inline unsigned long __must_check -copy_in_user(void __user *to, const void __user *from, unsigned long n) -{ - might_fault(); - return __copy_in_user(to, from, n); -} +raw_copy_in_user(void __user *to, const void __user *from, unsigned long n); /* * Copy a null terminated string from userspace. diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 47a973b5b4f1..5dab859b0d54 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -909,13 +909,11 @@ void __init smp_prepare_boot_cpu(void) { struct pcpu *pcpu = pcpu_devices; + WARN_ON(!cpu_present(0) || !cpu_online(0)); pcpu->state = CPU_STATE_CONFIGURED; - pcpu->address = stap(); pcpu->lowcore = (struct lowcore *)(unsigned long) store_prefix(); S390_lowcore.percpu_offset = __per_cpu_offset[0]; smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); - set_cpu_present(0, true); - set_cpu_online(0, true); } void __init smp_cpus_done(unsigned int max_cpus) @@ -924,6 +922,7 @@ void __init smp_cpus_done(unsigned int max_cpus) void __init smp_setup_processor_id(void) { + pcpu_devices[0].address = stap(); S390_lowcore.cpu_nr = 0; S390_lowcore.spinlock_lockval = arch_spin_lockval(0); } diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index c31da46bc037..c3a52f9a69a0 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -158,7 +158,9 @@ void init_cpu_timer(void) cd->mult = 16777; cd->shift = 12; cd->min_delta_ns = 1; + cd->min_delta_ticks = 1; cd->max_delta_ns = LONG_MAX; + cd->max_delta_ticks = ULONG_MAX; cd->rating = 400; cd->cpumask = cpumask_of(cpu); cd->set_next_event = s390_next_event; diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 5ccf95396251..72307f108c40 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -63,11 +63,9 @@ SECTIONS . = ALIGN(PAGE_SIZE); __start_ro_after_init = .; - __start_data_ro_after_init = .; .data..ro_after_init : { *(.data..ro_after_init) } - __end_data_ro_after_init = .; EXCEPTION_TABLE(16) . = ALIGN(PAGE_SIZE); __end_ro_after_init = .; diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index d55c829a5944..ddbffb715b40 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -168,8 +168,7 @@ union page_table_entry { unsigned long z : 1; /* Zero Bit */ unsigned long i : 1; /* Page-Invalid Bit */ unsigned long p : 1; /* DAT-Protection Bit */ - unsigned long co : 1; /* Change-Recording Override */ - unsigned long : 8; + unsigned long : 9; }; }; @@ -745,8 +744,6 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, return PGM_PAGE_TRANSLATION; if (pte.z) return PGM_TRANSLATION_SPEC; - if (pte.co && !edat1) - return PGM_TRANSLATION_SPEC; dat_protection |= pte.p; raddr.pfra = pte.pfra; real_address: @@ -1182,7 +1179,7 @@ int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg, rc = gmap_read_table(sg->parent, pgt + vaddr.px * 8, &pte.val); if (!rc && pte.i) rc = PGM_PAGE_TRANSLATION; - if (!rc && (pte.z || (pte.co && sg->edat_level < 1))) + if (!rc && pte.z) rc = PGM_TRANSLATION_SPEC; shadow_page: pte.p |= dat_protection; diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c index f481fcde067b..1e5bb2b86c42 100644 --- a/arch/s390/lib/uaccess.c +++ b/arch/s390/lib/uaccess.c @@ -26,7 +26,7 @@ static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr tmp1 = -4096UL; asm volatile( "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" - "9: jz 7f\n" + "6: jz 4f\n" "1: algr %0,%3\n" " slgr %1,%3\n" " slgr %2,%3\n" @@ -35,23 +35,13 @@ static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */ " slgr %4,%1\n" " clgr %0,%4\n" /* copy crosses next page boundary? */ - " jnh 4f\n" + " jnh 5f\n" "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" - "10:slgr %0,%4\n" - " algr %2,%4\n" - "4: lghi %4,-1\n" - " algr %4,%0\n" /* copy remaining size, subtract 1 */ - " bras %3,6f\n" /* memset loop */ - " xc 0(1,%2),0(%2)\n" - "5: xc 0(256,%2),0(%2)\n" - " la %2,256(%2)\n" - "6: aghi %4,-256\n" - " jnm 5b\n" - " ex %4,0(%3)\n" - " j 8f\n" - "7: slgr %0,%0\n" - "8:\n" - EX_TABLE(0b,2b) EX_TABLE(3b,4b) EX_TABLE(9b,2b) EX_TABLE(10b,4b) + "7: slgr %0,%4\n" + " j 5f\n" + "4: slgr %0,%0\n" + "5:\n" + EX_TABLE(0b,2b) EX_TABLE(3b,5b) EX_TABLE(6b,2b) EX_TABLE(7b,5b) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) : "d" (reg0) : "cc", "memory"); return size; @@ -67,49 +57,38 @@ static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr, asm volatile( " sacf 0\n" "0: mvcp 0(%0,%2),0(%1),%3\n" - "10:jz 8f\n" + "7: jz 5f\n" "1: algr %0,%3\n" " la %1,256(%1)\n" " la %2,256(%2)\n" "2: mvcp 0(%0,%2),0(%1),%3\n" - "11:jnz 1b\n" - " j 8f\n" + "8: jnz 1b\n" + " j 5f\n" "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ " lghi %3,-4096\n" " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ " slgr %4,%1\n" " clgr %0,%4\n" /* copy crosses next page boundary? */ - " jnh 5f\n" + " jnh 6f\n" "4: mvcp 0(%4,%2),0(%1),%3\n" - "12:slgr %0,%4\n" - " algr %2,%4\n" - "5: lghi %4,-1\n" - " algr %4,%0\n" /* copy remaining size, subtract 1 */ - " bras %3,7f\n" /* memset loop */ - " xc 0(1,%2),0(%2)\n" - "6: xc 0(256,%2),0(%2)\n" - " la %2,256(%2)\n" - "7: aghi %4,-256\n" - " jnm 6b\n" - " ex %4,0(%3)\n" - " j 9f\n" - "8: slgr %0,%0\n" - "9: sacf 768\n" - EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b) - EX_TABLE(10b,3b) EX_TABLE(11b,3b) EX_TABLE(12b,5b) + "9: slgr %0,%4\n" + " j 6f\n" + "5: slgr %0,%0\n" + "6: sacf 768\n" + EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) + EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) : : "cc", "memory"); return size; } -unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) +unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - check_object_size(to, n, false); if (static_branch_likely(&have_mvcos)) return copy_from_user_mvcos(to, from, n); return copy_from_user_mvcp(to, from, n); } -EXPORT_SYMBOL(__copy_from_user); +EXPORT_SYMBOL(raw_copy_from_user); static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x, unsigned long size) @@ -176,14 +155,13 @@ static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x, return size; } -unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) +unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - check_object_size(from, n, true); if (static_branch_likely(&have_mvcos)) return copy_to_user_mvcos(to, from, n); return copy_to_user_mvcs(to, from, n); } -EXPORT_SYMBOL(__copy_to_user); +EXPORT_SYMBOL(raw_copy_to_user); static inline unsigned long copy_in_user_mvcos(void __user *to, const void __user *from, unsigned long size) @@ -240,13 +218,13 @@ static inline unsigned long copy_in_user_mvc(void __user *to, const void __user return size; } -unsigned long __copy_in_user(void __user *to, const void __user *from, unsigned long n) +unsigned long raw_copy_in_user(void __user *to, const void __user *from, unsigned long n) { if (static_branch_likely(&have_mvcos)) return copy_in_user_mvcos(to, from, n); return copy_in_user_mvc(to, from, n); } -EXPORT_SYMBOL(__copy_in_user); +EXPORT_SYMBOL(raw_copy_in_user); static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size) { diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild index 926943a49ea5..e3a8d0f96652 100644 --- a/arch/score/include/asm/Kbuild +++ b/arch/score/include/asm/Kbuild @@ -4,6 +4,7 @@ header-y += generic-y += barrier.h generic-y += clkdev.h generic-y += current.h +generic-y += extable.h generic-y += irq_work.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/score/include/asm/extable.h b/arch/score/include/asm/extable.h deleted file mode 100644 index c4423ccf830d..000000000000 --- a/arch/score/include/asm/extable.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _ASM_SCORE_EXTABLE_H -#define _ASM_SCORE_EXTABLE_H - -struct exception_table_entry { - unsigned long insn; - unsigned long fixup; -}; - -struct pt_regs; -extern int fixup_exception(struct pt_regs *regs); -#endif diff --git a/arch/score/include/asm/uaccess.h b/arch/score/include/asm/uaccess.h index db58ab98ec4b..916e5dbf0bfd 100644 --- a/arch/score/include/asm/uaccess.h +++ b/arch/score/include/asm/uaccess.h @@ -2,13 +2,8 @@ #define __SCORE_UACCESS_H #include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/thread_info.h> #include <asm/extable.h> -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - #define get_ds() (KERNEL_DS) #define get_fs() (current_thread_info()->addr_limit) #define segment_eq(a, b) ((a).seg == (b).seg) @@ -300,61 +295,19 @@ extern void __put_user_unknown(void); extern int __copy_tofrom_user(void *to, const void *from, unsigned long len); static inline unsigned long -copy_from_user(void *to, const void *from, unsigned long len) -{ - unsigned long res = len; - - if (likely(access_ok(VERIFY_READ, from, len))) - res = __copy_tofrom_user(to, from, len); - - if (unlikely(res)) - memset(to + (len - res), 0, res); - - return res; -} - -static inline unsigned long -copy_to_user(void *to, const void *from, unsigned long len) -{ - if (likely(access_ok(VERIFY_WRITE, to, len))) - len = __copy_tofrom_user(to, from, len); - - return len; -} - -static inline unsigned long -__copy_from_user(void *to, const void *from, unsigned long len) +raw_copy_from_user(void *to, const void __user *from, unsigned long len) { - unsigned long left = __copy_tofrom_user(to, from, len); - if (unlikely(left)) - memset(to + (len - left), 0, left); - return left; + return __copy_tofrom_user(to, (__force const void *)from, len); } -#define __copy_to_user(to, from, len) \ - __copy_tofrom_user((to), (from), (len)) - static inline unsigned long -__copy_to_user_inatomic(void *to, const void *from, unsigned long len) +raw_copy_to_user(void __user *to, const void *from, unsigned long len) { - return __copy_to_user(to, from, len); + return __copy_tofrom_user((__force void *)to, from, len); } -static inline unsigned long -__copy_from_user_inatomic(void *to, const void *from, unsigned long len) -{ - return __copy_tofrom_user(to, from, len); -} - -#define __copy_in_user(to, from, len) __copy_tofrom_user(to, from, len) - -static inline unsigned long -copy_in_user(void *to, const void *from, unsigned long len) -{ - if (access_ok(VERIFY_READ, from, len) && - access_ok(VERFITY_WRITE, to, len)) - return __copy_tofrom_user(to, from, len); -} +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER /* * __clear_user: - Zero a block of memory in user space, with less checking. diff --git a/arch/score/kernel/time.c b/arch/score/kernel/time.c index 679b8d7b0350..29aafc741f69 100644 --- a/arch/score/kernel/time.c +++ b/arch/score/kernel/time.c @@ -81,8 +81,10 @@ void __init time_init(void) score_clockevent.shift); score_clockevent.max_delta_ns = clockevent_delta2ns((u32)~0, &score_clockevent); + score_clockevent.max_delta_ticks = (u32)~0; score_clockevent.min_delta_ns = clockevent_delta2ns(50, &score_clockevent) + 1; + score_clockevent.min_delta_ticks = 50; score_clockevent.cpumask = cpumask_of(0); clockevents_register_device(&score_clockevent); } diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h index dcf278075429..1b77f068be2b 100644 --- a/arch/sh/include/asm/bug.h +++ b/arch/sh/include/asm/bug.h @@ -50,7 +50,7 @@ do { \ "i" (sizeof(struct bug_entry))); \ } while (0) -#define __WARN_TAINT(taint) \ +#define __WARN_FLAGS(flags) \ do { \ __asm__ __volatile__ ( \ "1:\t.short %O0\n" \ @@ -59,7 +59,7 @@ do { \ : "n" (TRAPA_BUG_OPCODE), \ "i" (__FILE__), \ "i" (__LINE__), \ - "i" (BUGFLAG_TAINT(taint)), \ + "i" (BUGFLAG_WARNING|(flags)), \ "i" (sizeof(struct bug_entry))); \ } while (0) diff --git a/arch/sh/include/asm/extable.h b/arch/sh/include/asm/extable.h new file mode 100644 index 000000000000..df2ee2fcb8d3 --- /dev/null +++ b/arch/sh/include/asm/extable.h @@ -0,0 +1,10 @@ +#ifndef __ASM_SH_EXTABLE_H +#define __ASM_SH_EXTABLE_H + +#include <asm-generic/extable.h> + +#if defined(CONFIG_SUPERH64) && defined(CONFIG_MMU) +#define ARCH_HAS_SEARCH_EXTABLE +#endif + +#endif diff --git a/arch/sh/include/asm/uaccess.h b/arch/sh/include/asm/uaccess.h index c4f0fee812c3..2722b61b2283 100644 --- a/arch/sh/include/asm/uaccess.h +++ b/arch/sh/include/asm/uaccess.h @@ -1,12 +1,8 @@ #ifndef __ASM_SH_UACCESS_H #define __ASM_SH_UACCESS_H -#include <linux/errno.h> -#include <linux/sched.h> #include <asm/segment.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 +#include <asm/extable.h> #define __addr_ok(addr) \ ((unsigned long __force)(addr) < current_thread_info()->addr_limit.seg) @@ -112,19 +108,18 @@ extern __must_check long strnlen_user(const char __user *str, long n); __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); static __always_inline unsigned long -__copy_from_user(void *to, const void __user *from, unsigned long n) +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { return __copy_user(to, (__force void *)from, n); } static __always_inline unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n) +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { return __copy_user((__force void *)to, from, n); } - -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER /* * Clear the area and return remaining number of bytes @@ -144,55 +139,6 @@ __kernel_size_t __clear_user(void *addr, __kernel_size_t size); __cl_size; \ }) -static inline unsigned long -copy_from_user(void *to, const void __user *from, unsigned long n) -{ - unsigned long __copy_from = (unsigned long) from; - __kernel_size_t __copy_size = (__kernel_size_t) n; - - if (__copy_size && __access_ok(__copy_from, __copy_size)) - __copy_size = __copy_user(to, from, __copy_size); - - if (unlikely(__copy_size)) - memset(to + (n - __copy_size), 0, __copy_size); - - return __copy_size; -} - -static inline unsigned long -copy_to_user(void __user *to, const void *from, unsigned long n) -{ - unsigned long __copy_to = (unsigned long) to; - __kernel_size_t __copy_size = (__kernel_size_t) n; - - if (__copy_size && __access_ok(__copy_to, __copy_size)) - return __copy_user(to, from, __copy_size); - - return __copy_size; -} - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ -struct exception_table_entry { - unsigned long insn, fixup; -}; - -#if defined(CONFIG_SUPERH64) && defined(CONFIG_MMU) -#define ARCH_HAS_SEARCH_EXTABLE -#endif - -int fixup_exception(struct pt_regs *regs); - extern void *set_exception_table_vec(unsigned int vec, void *handler); static inline void *set_exception_table_evt(unsigned int evt, void *handler) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 68ac5c7cd982..ed96869c4101 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -42,8 +42,7 @@ config SPARC select OLD_SIGSUSPEND select ARCH_HAS_SG_CHAIN select CPU_NO_EFFICIENT_FFS - select HAVE_ARCH_HARDENED_USERCOPY - select PROVE_LOCKING_SMALL if PROVE_LOCKING + select LOCKDEP_SMALL if LOCKDEP select ARCH_WANT_RELAX_ORDER config SPARC32 @@ -82,6 +81,7 @@ config SPARC64 select HAVE_ARCH_AUDITSYSCALL select ARCH_SUPPORTS_ATOMIC_RMW select HAVE_NMI + select HAVE_REGS_AND_STACK_ACCESS_API config ARCH_DEFCONFIG string diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h index f294dd42fc7d..5961b2d8398a 100644 --- a/arch/sparc/include/asm/page_64.h +++ b/arch/sparc/include/asm/page_64.h @@ -17,6 +17,7 @@ #define HPAGE_SHIFT 23 #define REAL_HPAGE_SHIFT 22 +#define HPAGE_2GB_SHIFT 31 #define HPAGE_256MB_SHIFT 28 #define HPAGE_64K_SHIFT 16 #define REAL_HPAGE_SIZE (_AC(1,UL) << REAL_HPAGE_SHIFT) @@ -27,7 +28,7 @@ #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #define REAL_HPAGE_PER_HPAGE (_AC(1,UL) << (HPAGE_SHIFT - REAL_HPAGE_SHIFT)) -#define HUGE_MAX_HSTATE 3 +#define HUGE_MAX_HSTATE 4 #endif #ifndef __ASSEMBLY__ diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 8a598528ec1f..6fbd931f0570 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -679,26 +679,27 @@ static inline unsigned long pmd_pfn(pmd_t pmd) return pte_pfn(pte); } -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -static inline unsigned long pmd_dirty(pmd_t pmd) +#define __HAVE_ARCH_PMD_WRITE +static inline unsigned long pmd_write(pmd_t pmd) { pte_t pte = __pte(pmd_val(pmd)); - return pte_dirty(pte); + return pte_write(pte); } -static inline unsigned long pmd_young(pmd_t pmd) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static inline unsigned long pmd_dirty(pmd_t pmd) { pte_t pte = __pte(pmd_val(pmd)); - return pte_young(pte); + return pte_dirty(pte); } -static inline unsigned long pmd_write(pmd_t pmd) +static inline unsigned long pmd_young(pmd_t pmd) { pte_t pte = __pte(pmd_val(pmd)); - return pte_write(pte); + return pte_young(pte); } static inline unsigned long pmd_trans_huge(pmd_t pmd) diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h index 365d4cb267b4..dd27159819eb 100644 --- a/arch/sparc/include/asm/processor_32.h +++ b/arch/sparc/include/asm/processor_32.h @@ -18,12 +18,6 @@ #include <asm/signal.h> #include <asm/page.h> -/* - * The sparc has no problems with write protection - */ -#define wp_works_ok 1 -#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ - /* Whee, this is STACK_TOP + PAGE_SIZE and the lowest kernel address too... * That one page is used to protect kernel from intruders, so that * we can make our access_ok test faster diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 6448cfc8292f..b58ee9018433 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h @@ -18,10 +18,6 @@ #include <asm/ptrace.h> #include <asm/page.h> -/* The sparc has no problems with write protection */ -#define wp_works_ok 1 -#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ - /* * User lives in his very own context, and cannot reference us. Note * that TASK_SIZE is a misnomer, it really gives maximum user virtual diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h index ca57f08bd3db..d73428e4333c 100644 --- a/arch/sparc/include/asm/ptrace.h +++ b/arch/sparc/include/asm/ptrace.h @@ -83,7 +83,8 @@ unsigned long profile_pc(struct pt_regs *); #define MAX_REG_OFFSET (offsetof(struct pt_regs, magic)) -extern int regs_query_register_offset(const char *name); +int regs_query_register_offset(const char *name); +unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n); /** * regs_get_register() - get register value from its offset diff --git a/arch/sparc/include/asm/uaccess.h b/arch/sparc/include/asm/uaccess.h index bd56c28fff9f..9e068bf9060a 100644 --- a/arch/sparc/include/asm/uaccess.h +++ b/arch/sparc/include/asm/uaccess.h @@ -7,7 +7,7 @@ #endif #define user_addr_max() \ - (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL) + (uaccess_kernel() ? ~0UL : TASK_SIZE) long strncpy_from_user(char *dest, const char __user *src, long count); diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h index ea55f86d7ccd..12ebee2d97c7 100644 --- a/arch/sparc/include/asm/uaccess_32.h +++ b/arch/sparc/include/asm/uaccess_32.h @@ -7,14 +7,8 @@ #ifndef _ASM_UACCESS_H #define _ASM_UACCESS_H -#ifdef __KERNEL__ #include <linux/compiler.h> -#include <linux/sched.h> #include <linux/string.h> -#include <linux/errno.h> -#endif - -#ifndef __ASSEMBLY__ #include <asm/processor.h> @@ -30,9 +24,6 @@ #define KERNEL_DS ((mm_segment_t) { 0 }) #define USER_DS ((mm_segment_t) { -1 }) -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - #define get_ds() (KERNEL_DS) #define get_fs() (current->thread.current_ds) #define set_fs(val) ((current->thread.current_ds) = (val)) @@ -45,7 +36,7 @@ * large size and address near to PAGE_OFFSET - a fault will break his intentions. */ #define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; }) -#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) +#define __kernel_ok (uaccess_kernel()) #define __access_ok(addr, size) (__user_ok((addr) & get_fs().seg, (size))) #define access_ok(type, addr, size) \ ({ (void)(type); __access_ok((unsigned long)(addr), size); }) @@ -80,8 +71,6 @@ struct exception_table_entry /* Returns 0 if exception not found and fixup otherwise. */ unsigned long search_extables_range(unsigned long addr, unsigned long *g2); -void __ret_efault(void); - /* Uh, these should become the main single-value transfer routines.. * They automatically use the right size if we just have the right * pointer type.. @@ -246,39 +235,18 @@ int __get_user_bad(void); unsigned long __copy_user(void __user *to, const void __user *from, unsigned long size); -static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) -{ - if (n && __access_ok((unsigned long) to, n)) { - check_object_size(from, n, true); - return __copy_user(to, (__force void __user *) from, n); - } else - return n; -} - -static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) +static inline unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - check_object_size(from, n, true); return __copy_user(to, (__force void __user *) from, n); } -static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) -{ - if (n && __access_ok((unsigned long) from, n)) { - check_object_size(to, n, false); - return __copy_user((__force void __user *) to, from, n); - } else { - memset(to, 0, n); - return n; - } -} - -static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) +static inline unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) { return __copy_user((__force void __user *) to, from, n); } -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER static inline unsigned long __clear_user(void __user *addr, unsigned long size) { @@ -312,6 +280,4 @@ static inline unsigned long clear_user(void __user *addr, unsigned long n) __must_check long strlen_user(const char __user *str); __must_check long strnlen_user(const char __user *str, long n); -#endif /* __ASSEMBLY__ */ - #endif /* _ASM_UACCESS_H */ diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index 5373136c412b..6096d671aa63 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h @@ -5,18 +5,12 @@ * User space memory access functions */ -#ifdef __KERNEL__ -#include <linux/errno.h> #include <linux/compiler.h> #include <linux/string.h> -#include <linux/thread_info.h> #include <asm/asi.h> #include <asm/spitfire.h> #include <asm-generic/uaccess-unaligned.h> #include <asm/extable_64.h> -#endif - -#ifndef __ASSEMBLY__ #include <asm/processor.h> @@ -36,9 +30,6 @@ #define KERNEL_DS ((mm_segment_t) { ASI_P }) #define USER_DS ((mm_segment_t) { ASI_AIUS }) /* har har har */ -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - #define get_fs() ((mm_segment_t){(current_thread_info()->current_ds)}) #define get_ds() (KERNEL_DS) @@ -185,39 +176,19 @@ __asm__ __volatile__( \ int __get_user_bad(void); -unsigned long __must_check ___copy_from_user(void *to, +unsigned long __must_check raw_copy_from_user(void *to, const void __user *from, unsigned long size); -static inline unsigned long __must_check -copy_from_user(void *to, const void __user *from, unsigned long size) -{ - check_object_size(to, size, false); - return ___copy_from_user(to, from, size); -} -#define __copy_from_user copy_from_user - -unsigned long __must_check ___copy_to_user(void __user *to, +unsigned long __must_check raw_copy_to_user(void __user *to, const void *from, unsigned long size); -static inline unsigned long __must_check -copy_to_user(void __user *to, const void *from, unsigned long size) -{ - check_object_size(from, size, true); +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER - return ___copy_to_user(to, from, size); -} -#define __copy_to_user copy_to_user - -unsigned long __must_check ___copy_in_user(void __user *to, +unsigned long __must_check raw_copy_in_user(void __user *to, const void __user *from, unsigned long size); -static inline unsigned long __must_check -copy_in_user(void __user *to, void __user *from, unsigned long size) -{ - return ___copy_in_user(to, from, size); -} -#define __copy_in_user copy_in_user unsigned long __must_check __clear_user(void __user *, unsigned long); @@ -226,14 +197,9 @@ unsigned long __must_check __clear_user(void __user *, unsigned long); __must_check long strlen_user(const char __user *str); __must_check long strnlen_user(const char __user *str, long n); -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - struct pt_regs; unsigned long compute_effective_address(struct pt_regs *, unsigned int insn, unsigned int rd); -#endif /* __ASSEMBLY__ */ - #endif /* _ASM_UACCESS_H */ diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index 36eee8132c22..ae77df75bffa 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h @@ -425,8 +425,9 @@ #define __NR_copy_file_range 357 #define __NR_preadv2 358 #define __NR_pwritev2 359 +#define __NR_statx 360 -#define NR_syscalls 360 +#define NR_syscalls 361 /* Bitmask values returned from kern_features system call. */ #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 @@ -442,4 +443,9 @@ #define __IGNORE_getresgid #endif +/* Sparc doesn't have protection keys. */ +#define __IGNORE_pkey_mprotect +#define __IGNORE_pkey_alloc +#define __IGNORE_pkey_free + #endif /* _UAPI_SPARC_UNISTD_H */ diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index 7bb317b87dde..7274e43ff9be 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S @@ -809,10 +809,3 @@ lvl14_save: .word 0 .word 0 .word t_irq14 - - .section ".fixup",#alloc,#execinstr - .globl __ret_efault -__ret_efault: - ret - restore %g0, -EFAULT, %o0 -EXPORT_SYMBOL(__ret_efault) diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 6aa3da152c20..44101196d02b 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -96,6 +96,7 @@ sparc64_boot: andn %g1, PSTATE_AM, %g1 wrpr %g1, 0x0, %pstate ba,a,pt %xcc, 1f + nop .globl prom_finddev_name, prom_chosen_path, prom_root_node .globl prom_getprop_name, prom_mmu_name, prom_peer_name @@ -613,6 +614,7 @@ niagara_tlb_fixup: nop ba,a,pt %xcc, 80f + nop niagara4_patch: call niagara4_patch_copyops nop @@ -622,6 +624,7 @@ niagara4_patch: nop ba,a,pt %xcc, 80f + nop niagara2_patch: call niagara2_patch_copyops @@ -632,6 +635,7 @@ niagara2_patch: nop ba,a,pt %xcc, 80f + nop niagara_patch: call niagara_patch_copyops diff --git a/arch/sparc/kernel/misctrap.S b/arch/sparc/kernel/misctrap.S index 34b4933900bf..9276d2f0dd86 100644 --- a/arch/sparc/kernel/misctrap.S +++ b/arch/sparc/kernel/misctrap.S @@ -82,6 +82,7 @@ do_stdfmna: call handle_stdfmna add %sp, PTREGS_OFF, %o0 ba,a,pt %xcc, rtrap + nop .size do_stdfmna,.-do_stdfmna .type breakpoint_trap,#function diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index fc5124ccdb53..e1d965e90e16 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c @@ -1162,3 +1162,39 @@ int regs_query_register_offset(const char *name) return roff->offset; return -EINVAL; } + +/** + * regs_within_kernel_stack() - check the address in the stack + * @regs: pt_regs which contains kernel stack pointer. + * @addr: address which is checked. + * + * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). + * If @addr is within the kernel stack, it returns true. If not, returns false. + */ +static inline int regs_within_kernel_stack(struct pt_regs *regs, + unsigned long addr) +{ + unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS; + return ((addr & ~(THREAD_SIZE - 1)) == + (ksp & ~(THREAD_SIZE - 1))); +} + +/** + * regs_get_kernel_stack_nth() - get Nth entry of the stack + * @regs: pt_regs which contains kernel stack pointer. + * @n: stack entry number. + * + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which + * is specified by @regs. If the @n th entry is NOT in the kernel stack, + * this returns 0. + */ +unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) +{ + unsigned long ksp = kernel_stack_pointer(regs) + STACK_BIAS; + unsigned long *addr = (unsigned long *)ksp; + addr += n; + if (regs_within_kernel_stack(regs, (unsigned long)addr)) + return *addr; + else + return 0; +} diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 216948ca4382..709a82ebd294 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -237,6 +237,7 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 bne,pt %xcc, user_rtt_fill_32bit wrpr %g1, %cwp ba,a,pt %xcc, user_rtt_fill_64bit + nop user_rtt_fill_fixup_dax: ba,pt %xcc, user_rtt_fill_fixup_common diff --git a/arch/sparc/kernel/spiterrs.S b/arch/sparc/kernel/spiterrs.S index 4a73009f66a5..d7e540842809 100644 --- a/arch/sparc/kernel/spiterrs.S +++ b/arch/sparc/kernel/spiterrs.S @@ -86,6 +86,7 @@ __spitfire_cee_trap_continue: rd %pc, %g7 ba,a,pt %xcc, 2f + nop 1: ba,pt %xcc, etrap_irq rd %pc, %g7 diff --git a/arch/sparc/kernel/sun4v_tlb_miss.S b/arch/sparc/kernel/sun4v_tlb_miss.S index 6179e19bc9b9..c19f352f46c7 100644 --- a/arch/sparc/kernel/sun4v_tlb_miss.S +++ b/arch/sparc/kernel/sun4v_tlb_miss.S @@ -352,6 +352,7 @@ sun4v_mna: call sun4v_do_mna add %sp, PTREGS_OFF, %o0 ba,a,pt %xcc, rtrap + nop /* Privileged Action. */ sun4v_privact: diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c index d63fc613e7a9..5fd352b759af 100644 --- a/arch/sparc/kernel/sysfs.c +++ b/arch/sparc/kernel/sysfs.c @@ -98,27 +98,7 @@ static struct attribute_group mmu_stat_group = { .name = "mmu_stats", }; -/* XXX convert to rusty's on_one_cpu */ -static unsigned long run_on_cpu(unsigned long cpu, - unsigned long (*func)(unsigned long), - unsigned long arg) -{ - cpumask_t old_affinity; - unsigned long ret; - - cpumask_copy(&old_affinity, ¤t->cpus_allowed); - /* should return -EINVAL to userspace */ - if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) - return 0; - - ret = func(arg); - - set_cpus_allowed_ptr(current, &old_affinity); - - return ret; -} - -static unsigned long read_mmustat_enable(unsigned long junk) +static long read_mmustat_enable(void *data __maybe_unused) { unsigned long ra = 0; @@ -127,11 +107,11 @@ static unsigned long read_mmustat_enable(unsigned long junk) return ra != 0; } -static unsigned long write_mmustat_enable(unsigned long val) +static long write_mmustat_enable(void *data) { - unsigned long ra, orig_ra; + unsigned long ra, orig_ra, *val = data; - if (val) + if (*val) ra = __pa(&per_cpu(mmu_stats, smp_processor_id())); else ra = 0UL; @@ -142,7 +122,8 @@ static unsigned long write_mmustat_enable(unsigned long val) static ssize_t show_mmustat_enable(struct device *s, struct device_attribute *attr, char *buf) { - unsigned long val = run_on_cpu(s->id, read_mmustat_enable, 0); + long val = work_on_cpu(s->id, read_mmustat_enable, NULL); + return sprintf(buf, "%lx\n", val); } @@ -150,13 +131,15 @@ static ssize_t store_mmustat_enable(struct device *s, struct device_attribute *attr, const char *buf, size_t count) { - unsigned long val, err; - int ret = sscanf(buf, "%lu", &val); + unsigned long val; + long err; + int ret; + ret = sscanf(buf, "%lu", &val); if (ret != 1) return -EINVAL; - err = run_on_cpu(s->id, write_mmustat_enable, val); + err = work_on_cpu(s->id, write_mmustat_enable, &val); if (err) return -EIO; diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index eac7f0db5c8c..5253e895b81b 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -89,3 +89,4 @@ sys_call_table: /*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf /*350*/ .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen /*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2 +/*360*/ .long sys_statx diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index b0f17ff2ddba..82339f6be0b2 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -90,6 +90,7 @@ sys_call_table32: .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf /*350*/ .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen .word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range, compat_sys_preadv2, compat_sys_pwritev2 +/*360*/ .word sys_statx #endif /* CONFIG_COMPAT */ @@ -171,3 +172,4 @@ sys_call_table: .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf /*350*/ .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen .word sys_setsockopt, sys_mlock2, sys_copy_file_range, sys_preadv2, sys_pwritev2 +/*360*/ .word sys_statx diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 244062bdaa56..9f575dfc2e41 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -228,7 +228,9 @@ void register_percpu_ce(int cpu) ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC, ce->shift); ce->max_delta_ns = clockevent_delta2ns(sparc_config.clock_rate, ce); + ce->max_delta_ticks = (unsigned long)sparc_config.clock_rate; ce->min_delta_ns = clockevent_delta2ns(100, ce); + ce->min_delta_ticks = 100; clockevents_register_device(ce); } diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 12a6d3555cb8..98d05de8da66 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -796,8 +796,10 @@ void __init time_init(void) sparc64_clockevent.max_delta_ns = clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent); + sparc64_clockevent.max_delta_ticks = 0x7fffffffffffffffUL; sparc64_clockevent.min_delta_ns = clockevent_delta2ns(0xF, &sparc64_clockevent); + sparc64_clockevent.min_delta_ticks = 0xF; printk("clockevent: mult[%x] shift[%d]\n", sparc64_clockevent.mult, sparc64_clockevent.shift); diff --git a/arch/sparc/kernel/urtt_fill.S b/arch/sparc/kernel/urtt_fill.S index 5604a2b051d4..364af3250646 100644 --- a/arch/sparc/kernel/urtt_fill.S +++ b/arch/sparc/kernel/urtt_fill.S @@ -92,6 +92,7 @@ user_rtt_fill_fixup_common: call sun4v_data_access_exception nop ba,a,pt %xcc, rtrap + nop 1: call spitfire_data_access_exception nop diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S index 855019a8590e..1ee173cc3c39 100644 --- a/arch/sparc/kernel/winfixup.S +++ b/arch/sparc/kernel/winfixup.S @@ -152,6 +152,8 @@ fill_fixup_dax: call sun4v_data_access_exception nop ba,a,pt %xcc, rtrap + nop 1: call spitfire_data_access_exception nop ba,a,pt %xcc, rtrap + nop diff --git a/arch/sparc/lib/GENcopy_from_user.S b/arch/sparc/lib/GENcopy_from_user.S index 69a439fa2fc1..8aa16ef113f2 100644 --- a/arch/sparc/lib/GENcopy_from_user.S +++ b/arch/sparc/lib/GENcopy_from_user.S @@ -23,7 +23,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop #endif diff --git a/arch/sparc/lib/GENcopy_to_user.S b/arch/sparc/lib/GENcopy_to_user.S index 9947427ce354..311c8fa5e98e 100644 --- a/arch/sparc/lib/GENcopy_to_user.S +++ b/arch/sparc/lib/GENcopy_to_user.S @@ -27,7 +27,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop #endif diff --git a/arch/sparc/lib/GENpatch.S b/arch/sparc/lib/GENpatch.S index fab9e89f16bd..95e2f1f9e477 100644 --- a/arch/sparc/lib/GENpatch.S +++ b/arch/sparc/lib/GENpatch.S @@ -26,8 +26,8 @@ .type generic_patch_copyops,#function generic_patch_copyops: GEN_DO_PATCH(memcpy, GENmemcpy) - GEN_DO_PATCH(___copy_from_user, GENcopy_from_user) - GEN_DO_PATCH(___copy_to_user, GENcopy_to_user) + GEN_DO_PATCH(raw_copy_from_user, GENcopy_from_user) + GEN_DO_PATCH(raw_copy_to_user, GENcopy_to_user) retl nop .size generic_patch_copyops,.-generic_patch_copyops diff --git a/arch/sparc/lib/NG2copy_from_user.S b/arch/sparc/lib/NG2copy_from_user.S index b79a6998d87c..0d8a018118c2 100644 --- a/arch/sparc/lib/NG2copy_from_user.S +++ b/arch/sparc/lib/NG2copy_from_user.S @@ -36,7 +36,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop #endif diff --git a/arch/sparc/lib/NG2copy_to_user.S b/arch/sparc/lib/NG2copy_to_user.S index dcec55f254ab..a7a0ea0d8a0b 100644 --- a/arch/sparc/lib/NG2copy_to_user.S +++ b/arch/sparc/lib/NG2copy_to_user.S @@ -45,7 +45,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop #endif diff --git a/arch/sparc/lib/NG2memcpy.S b/arch/sparc/lib/NG2memcpy.S index c629dbd121b6..64dcd6cdb606 100644 --- a/arch/sparc/lib/NG2memcpy.S +++ b/arch/sparc/lib/NG2memcpy.S @@ -326,11 +326,13 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ blu 170f nop ba,a,pt %xcc, 180f + nop 4: /* 32 <= low bits < 48 */ blu 150f nop ba,a,pt %xcc, 160f + nop 5: /* 0 < low bits < 32 */ blu,a 6f cmp %g2, 8 @@ -338,6 +340,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ blu 130f nop ba,a,pt %xcc, 140f + nop 6: /* 0 < low bits < 16 */ bgeu 120f nop @@ -475,6 +478,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ brz,pt %o2, 85f sub %o0, %o1, GLOBAL_SPARE ba,a,pt %XCC, 90f + nop .align 64 75: /* 16 < len <= 64 */ diff --git a/arch/sparc/lib/NG2patch.S b/arch/sparc/lib/NG2patch.S index 28c36f06a6d1..56ccc19adde8 100644 --- a/arch/sparc/lib/NG2patch.S +++ b/arch/sparc/lib/NG2patch.S @@ -26,8 +26,8 @@ .type niagara2_patch_copyops,#function niagara2_patch_copyops: NG_DO_PATCH(memcpy, NG2memcpy) - NG_DO_PATCH(___copy_from_user, NG2copy_from_user) - NG_DO_PATCH(___copy_to_user, NG2copy_to_user) + NG_DO_PATCH(raw_copy_from_user, NG2copy_from_user) + NG_DO_PATCH(raw_copy_to_user, NG2copy_to_user) retl nop .size niagara2_patch_copyops,.-niagara2_patch_copyops diff --git a/arch/sparc/lib/NG4copy_from_user.S b/arch/sparc/lib/NG4copy_from_user.S index 16a286c1a528..5bb506bd61fa 100644 --- a/arch/sparc/lib/NG4copy_from_user.S +++ b/arch/sparc/lib/NG4copy_from_user.S @@ -31,7 +31,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop #endif diff --git a/arch/sparc/lib/NG4copy_to_user.S b/arch/sparc/lib/NG4copy_to_user.S index 6b0276ffc858..a82d4d45fc1c 100644 --- a/arch/sparc/lib/NG4copy_to_user.S +++ b/arch/sparc/lib/NG4copy_to_user.S @@ -40,7 +40,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop #endif diff --git a/arch/sparc/lib/NG4memcpy.S b/arch/sparc/lib/NG4memcpy.S index 75bb93b1437f..78ea962edcbe 100644 --- a/arch/sparc/lib/NG4memcpy.S +++ b/arch/sparc/lib/NG4memcpy.S @@ -530,4 +530,5 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ bne,pt %icc, 1b EX_ST(STORE(stb, %g1, %o0 - 0x01), NG4_retl_o2_plus_1) ba,a,pt %icc, .Lexit + nop .size FUNC_NAME, .-FUNC_NAME diff --git a/arch/sparc/lib/NG4memset.S b/arch/sparc/lib/NG4memset.S index 41da4bdd95cb..7c0c81f18837 100644 --- a/arch/sparc/lib/NG4memset.S +++ b/arch/sparc/lib/NG4memset.S @@ -102,4 +102,5 @@ NG4bzero: bne,pt %icc, 1b add %o0, 0x30, %o0 ba,a,pt %icc, .Lpostloop + nop .size NG4bzero,.-NG4bzero diff --git a/arch/sparc/lib/NG4patch.S b/arch/sparc/lib/NG4patch.S index a114cbcf2a48..3cc0f8cc95df 100644 --- a/arch/sparc/lib/NG4patch.S +++ b/arch/sparc/lib/NG4patch.S @@ -26,8 +26,8 @@ .type niagara4_patch_copyops,#function niagara4_patch_copyops: NG_DO_PATCH(memcpy, NG4memcpy) - NG_DO_PATCH(___copy_from_user, NG4copy_from_user) - NG_DO_PATCH(___copy_to_user, NG4copy_to_user) + NG_DO_PATCH(raw_copy_from_user, NG4copy_from_user) + NG_DO_PATCH(raw_copy_to_user, NG4copy_to_user) retl nop .size niagara4_patch_copyops,.-niagara4_patch_copyops diff --git a/arch/sparc/lib/NGcopy_from_user.S b/arch/sparc/lib/NGcopy_from_user.S index 9cd42fcbc781..2333b6f3e824 100644 --- a/arch/sparc/lib/NGcopy_from_user.S +++ b/arch/sparc/lib/NGcopy_from_user.S @@ -25,7 +25,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop #endif diff --git a/arch/sparc/lib/NGcopy_to_user.S b/arch/sparc/lib/NGcopy_to_user.S index 5c358afd464e..07ba20bc4ea4 100644 --- a/arch/sparc/lib/NGcopy_to_user.S +++ b/arch/sparc/lib/NGcopy_to_user.S @@ -28,7 +28,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop #endif diff --git a/arch/sparc/lib/NGmemcpy.S b/arch/sparc/lib/NGmemcpy.S index d88c4ed50a00..cd654a719b27 100644 --- a/arch/sparc/lib/NGmemcpy.S +++ b/arch/sparc/lib/NGmemcpy.S @@ -394,6 +394,7 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */ brz,pt %i2, 85f sub %o0, %i1, %i3 ba,a,pt %XCC, 90f + nop .align 64 70: /* 16 < len <= 64 */ diff --git a/arch/sparc/lib/NGpatch.S b/arch/sparc/lib/NGpatch.S index 3b0674fc3366..62ccda7e7b38 100644 --- a/arch/sparc/lib/NGpatch.S +++ b/arch/sparc/lib/NGpatch.S @@ -26,8 +26,8 @@ .type niagara_patch_copyops,#function niagara_patch_copyops: NG_DO_PATCH(memcpy, NGmemcpy) - NG_DO_PATCH(___copy_from_user, NGcopy_from_user) - NG_DO_PATCH(___copy_to_user, NGcopy_to_user) + NG_DO_PATCH(raw_copy_from_user, NGcopy_from_user) + NG_DO_PATCH(raw_copy_to_user, NGcopy_to_user) retl nop .size niagara_patch_copyops,.-niagara_patch_copyops diff --git a/arch/sparc/lib/U1copy_from_user.S b/arch/sparc/lib/U1copy_from_user.S index bb6ff73229e3..9a6e68a9bf4a 100644 --- a/arch/sparc/lib/U1copy_from_user.S +++ b/arch/sparc/lib/U1copy_from_user.S @@ -19,7 +19,7 @@ .text; \ .align 4; -#define FUNC_NAME ___copy_from_user +#define FUNC_NAME raw_copy_from_user #define LOAD(type,addr,dest) type##a [addr] %asi, dest #define LOAD_BLK(addr,dest) ldda [addr] ASI_BLK_AIUS, dest #define EX_RETVAL(x) 0 @@ -31,7 +31,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop; \ #include "U1memcpy.S" diff --git a/arch/sparc/lib/U1copy_to_user.S b/arch/sparc/lib/U1copy_to_user.S index ed92ce739558..d7b28491eddf 100644 --- a/arch/sparc/lib/U1copy_to_user.S +++ b/arch/sparc/lib/U1copy_to_user.S @@ -19,7 +19,7 @@ .text; \ .align 4; -#define FUNC_NAME ___copy_to_user +#define FUNC_NAME raw_copy_to_user #define STORE(type,src,addr) type##a src, [addr] ASI_AIUS #define STORE_BLK(src,addr) stda src, [addr] ASI_BLK_AIUS #define EX_RETVAL(x) 0 @@ -31,7 +31,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop; \ #include "U1memcpy.S" diff --git a/arch/sparc/lib/U3copy_to_user.S b/arch/sparc/lib/U3copy_to_user.S index c4ee858e352a..f48fb87fe9f2 100644 --- a/arch/sparc/lib/U3copy_to_user.S +++ b/arch/sparc/lib/U3copy_to_user.S @@ -31,7 +31,7 @@ #define PREAMBLE \ rd %asi, %g1; \ cmp %g1, ASI_AIUS; \ - bne,pn %icc, ___copy_in_user; \ + bne,pn %icc, raw_copy_in_user; \ nop; \ #include "U3memcpy.S" diff --git a/arch/sparc/lib/U3patch.S b/arch/sparc/lib/U3patch.S index ecc302619a6e..91cd6539b6e1 100644 --- a/arch/sparc/lib/U3patch.S +++ b/arch/sparc/lib/U3patch.S @@ -26,8 +26,8 @@ .type cheetah_patch_copyops,#function cheetah_patch_copyops: ULTRA3_DO_PATCH(memcpy, U3memcpy) - ULTRA3_DO_PATCH(___copy_from_user, U3copy_from_user) - ULTRA3_DO_PATCH(___copy_to_user, U3copy_to_user) + ULTRA3_DO_PATCH(raw_copy_from_user, U3copy_from_user) + ULTRA3_DO_PATCH(raw_copy_to_user, U3copy_to_user) retl nop .size cheetah_patch_copyops,.-cheetah_patch_copyops diff --git a/arch/sparc/lib/copy_in_user.S b/arch/sparc/lib/copy_in_user.S index 0252b218de45..1b73bb80aeb0 100644 --- a/arch/sparc/lib/copy_in_user.S +++ b/arch/sparc/lib/copy_in_user.S @@ -44,7 +44,7 @@ __retl_o2_plus_1: * to copy register windows around during thread cloning. */ -ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ +ENTRY(raw_copy_in_user) /* %o0=dst, %o1=src, %o2=len */ cmp %o2, 0 be,pn %XCC, 85f or %o0, %o1, %o3 @@ -105,5 +105,5 @@ ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ add %o0, 1, %o0 retl clr %o0 -ENDPROC(___copy_in_user) -EXPORT_SYMBOL(___copy_in_user) +ENDPROC(raw_copy_in_user) +EXPORT_SYMBOL(raw_copy_in_user) diff --git a/arch/sparc/lib/copy_user.S b/arch/sparc/lib/copy_user.S index cea644dc67a6..bc243ee807cc 100644 --- a/arch/sparc/lib/copy_user.S +++ b/arch/sparc/lib/copy_user.S @@ -364,21 +364,7 @@ short_aligned_end: 97: mov %o2, %g3 fixupretl: - sethi %hi(PAGE_OFFSET), %g1 - cmp %o0, %g1 - blu 1f - cmp %o1, %g1 - bgeu 1f - ld [%g6 + TI_PREEMPT], %g1 - cmp %g1, 0 - bne 1f - nop - save %sp, -64, %sp - mov %i0, %o0 - call __bzero - mov %g3, %o1 - restore -1: retl + retl mov %g3, %o0 /* exception routine sets %g2 to (broken_insn - first_insn)>>2 */ diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index 323bc6b6e3ad..7c29d38e6b99 100644 --- a/arch/sparc/mm/hugetlbpage.c +++ b/arch/sparc/mm/hugetlbpage.c @@ -143,6 +143,10 @@ static pte_t sun4v_hugepage_shift_to_tte(pte_t entry, unsigned int shift) pte_val(entry) = pte_val(entry) & ~_PAGE_SZALL_4V; switch (shift) { + case HPAGE_2GB_SHIFT: + hugepage_size = _PAGE_SZ2GB_4V; + pte_val(entry) |= _PAGE_PMD_HUGE; + break; case HPAGE_256MB_SHIFT: hugepage_size = _PAGE_SZ256MB_4V; pte_val(entry) |= _PAGE_PMD_HUGE; @@ -183,6 +187,9 @@ static unsigned int sun4v_huge_tte_to_shift(pte_t entry) unsigned int shift; switch (tte_szbits) { + case _PAGE_SZ2GB_4V: + shift = HPAGE_2GB_SHIFT; + break; case _PAGE_SZ256MB_4V: shift = HPAGE_256MB_SHIFT; break; @@ -261,7 +268,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, if (!pmd) return NULL; - if (sz == PMD_SHIFT) + if (sz >= PMD_SIZE) pte = (pte_t *)pmd; else pte = pte_alloc_map(mm, pmd, addr); @@ -454,6 +461,22 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb, pgd_t *pgd; unsigned long next; + addr &= PMD_MASK; + if (addr < floor) { + addr += PMD_SIZE; + if (!addr) + return; + } + if (ceiling) { + ceiling &= PMD_MASK; + if (!ceiling) + return; + } + if (end - 1 > ceiling - 1) + end -= PMD_SIZE; + if (addr > end - 1) + return; + pgd = pgd_offset(tlb->mm, addr); do { next = pgd_addr_end(addr, end); diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index ccd455328989..0cda653ae007 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -337,6 +337,10 @@ static int __init setup_hugepagesz(char *string) hugepage_shift = ilog2(hugepage_size); switch (hugepage_shift) { + case HPAGE_2GB_SHIFT: + hv_pgsz_mask = HV_PGSZ_MASK_2GB; + hv_pgsz_idx = HV_PGSZ_IDX_2GB; + break; case HPAGE_256MB_SHIFT: hv_pgsz_mask = HV_PGSZ_MASK_256MB; hv_pgsz_idx = HV_PGSZ_IDX_256MB; @@ -1563,7 +1567,7 @@ bool kern_addr_valid(unsigned long addr) if ((long)addr < 0L) { unsigned long pa = __pa(addr); - if ((addr >> max_phys_bits) != 0UL) + if ((pa >> max_phys_bits) != 0UL) return false; return pfn_valid(pa >> PAGE_SHIFT); diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index def82f6d626f..8e76ebba2986 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -54,6 +54,7 @@ enum mbus_module srmmu_modtype; static unsigned int hwbug_bitmask; int vac_cache_size; +EXPORT_SYMBOL(vac_cache_size); int vac_line_size; extern struct resource sparc_iomap; diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index afda3bbf7854..ee8066c3d96c 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c @@ -154,7 +154,7 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, if (pte_val(*pte) & _PAGE_VALID) { bool exec = pte_exec(*pte); - tlb_batch_add_one(mm, vaddr, exec, false); + tlb_batch_add_one(mm, vaddr, exec, PAGE_SHIFT); } pte++; vaddr += PAGE_SIZE; @@ -209,9 +209,9 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, pte_t orig_pte = __pte(pmd_val(orig)); bool exec = pte_exec(orig_pte); - tlb_batch_add_one(mm, addr, exec, true); + tlb_batch_add_one(mm, addr, exec, REAL_HPAGE_SHIFT); tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec, - true); + REAL_HPAGE_SHIFT); } else { tlb_batch_pmd_scan(mm, addr, orig); } diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c index 0a04811f06b7..bedf08b22a47 100644 --- a/arch/sparc/mm/tsb.c +++ b/arch/sparc/mm/tsb.c @@ -122,7 +122,7 @@ void flush_tsb_user(struct tlb_batch *tb) spin_lock_irqsave(&mm->context.lock, flags); - if (tb->hugepage_shift < HPAGE_SHIFT) { + if (tb->hugepage_shift < REAL_HPAGE_SHIFT) { base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb; nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries; if (tlb_type == cheetah_plus || tlb_type == hypervisor) @@ -155,7 +155,7 @@ void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr, spin_lock_irqsave(&mm->context.lock, flags); - if (hugepage_shift < HPAGE_SHIFT) { + if (hugepage_shift < REAL_HPAGE_SHIFT) { base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb; nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries; if (tlb_type == cheetah_plus || tlb_type == hypervisor) diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index fd122ef45b00..0d925fa0f0c1 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig @@ -249,7 +249,6 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_TILE=y CONFIG_EXT2_FS=y diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index eb6a55944191..149d8e8eacb8 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig @@ -358,7 +358,6 @@ CONFIG_WATCHDOG_NOWAYOUT=y # CONFIG_VGA_ARB is not set # CONFIG_USB_SUPPORT is not set CONFIG_EDAC=y -CONFIG_EDAC_MM_EDAC=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_TILE=y CONFIG_EXT2_FS=y diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index aa48b6eaff2d..24c44e93804d 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild @@ -7,6 +7,7 @@ generic-y += clkdev.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += fb.h generic-y += fcntl.h generic-y += hw_irq.h diff --git a/arch/tile/include/asm/uaccess.h b/arch/tile/include/asm/uaccess.h index a77369e91e54..a803f6bb4d92 100644 --- a/arch/tile/include/asm/uaccess.h +++ b/arch/tile/include/asm/uaccess.h @@ -18,15 +18,11 @@ /* * User space memory access functions */ -#include <linux/sched.h> #include <linux/mm.h> #include <asm-generic/uaccess-unaligned.h> #include <asm/processor.h> #include <asm/page.h> -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - /* * The fs value determines whether argument validity checking should be * performed or not. If get_fs() == USER_DS, checking is performed, with @@ -102,24 +98,7 @@ int __range_ok(unsigned long addr, unsigned long size); likely(__range_ok((unsigned long)(addr), (size)) == 0); \ }) -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry { - unsigned long insn, fixup; -}; - -extern int fixup_exception(struct pt_regs *regs); +#include <asm/extable.h> /* * This is a type: either unsigned long, if the argument fits into @@ -334,145 +313,16 @@ extern int __put_user_bad(void) ((x) = 0, -EFAULT); \ }) -/** - * __copy_to_user() - copy data into user space, with less checking. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from kernel space to user space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * An alternate version - __copy_to_user_inatomic() - is designed - * to be called from atomic context, typically bracketed by calls - * to pagefault_disable() and pagefault_enable(). - */ -extern unsigned long __must_check __copy_to_user_inatomic( - void __user *to, const void *from, unsigned long n); - -static inline unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n) -{ - might_fault(); - return __copy_to_user_inatomic(to, from, n); -} - -static inline unsigned long __must_check -copy_to_user(void __user *to, const void *from, unsigned long n) -{ - if (access_ok(VERIFY_WRITE, to, n)) - n = __copy_to_user(to, from, n); - return n; -} - -/** - * __copy_from_user() - copy data from user space, with less checking. - * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from user space to kernel space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - * - * An alternate version - __copy_from_user_inatomic() - is designed - * to be called from atomic context, typically bracketed by calls - * to pagefault_disable() and pagefault_enable(). This version - * does *NOT* pad with zeros. - */ -extern unsigned long __must_check __copy_from_user_inatomic( - void *to, const void __user *from, unsigned long n); -extern unsigned long __must_check __copy_from_user_zeroing( - void *to, const void __user *from, unsigned long n); - -static inline unsigned long __must_check -__copy_from_user(void *to, const void __user *from, unsigned long n) -{ - might_fault(); - return __copy_from_user_zeroing(to, from, n); -} - -static inline unsigned long __must_check -_copy_from_user(void *to, const void __user *from, unsigned long n) -{ - if (access_ok(VERIFY_READ, from, n)) - n = __copy_from_user(to, from, n); - else - memset(to, 0, n); - return n; -} - -extern void __compiletime_error("usercopy buffer size is too small") -__bad_copy_user(void); - -static inline void copy_user_overflow(int size, unsigned long count) -{ - WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); -} - -static inline unsigned long __must_check copy_from_user(void *to, - const void __user *from, - unsigned long n) -{ - int sz = __compiletime_object_size(to); - - if (likely(sz == -1 || sz >= n)) - n = _copy_from_user(to, from, n); - else if (!__builtin_constant_p(n)) - copy_user_overflow(sz, n); - else - __bad_copy_user(); - - return n; -} +extern unsigned long __must_check +raw_copy_to_user(void __user *to, const void *from, unsigned long n); +extern unsigned long __must_check +raw_copy_from_user(void *to, const void __user *from, unsigned long n); +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER #ifdef __tilegx__ -/** - * __copy_in_user() - copy data within user space, with less checking. - * @to: Destination address, in user space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from user space to user space. Caller must check - * the specified blocks with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - */ -extern unsigned long __copy_in_user_inatomic( +extern unsigned long raw_copy_in_user( void __user *to, const void __user *from, unsigned long n); - -static inline unsigned long __must_check -__copy_in_user(void __user *to, const void __user *from, unsigned long n) -{ - might_fault(); - return __copy_in_user_inatomic(to, from, n); -} - -static inline unsigned long __must_check -copy_in_user(void __user *to, const void __user *from, unsigned long n) -{ - if (access_ok(VERIFY_WRITE, to, n) && access_ok(VERIFY_READ, from, n)) - n = __copy_in_user(to, from, n); - return n; -} #endif diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index 5bd4e88c7c60..6643ffbc0615 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c @@ -155,6 +155,8 @@ static DEFINE_PER_CPU(struct clock_event_device, tile_timer) = { .name = "tile timer", .features = CLOCK_EVT_FEAT_ONESHOT, .min_delta_ns = 1000, + .min_delta_ticks = 1, + .max_delta_ticks = MAX_TICK, .rating = 100, .irq = -1, .set_next_event = tile_timer_set_next_event, diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c index c5369fe643c7..ecce8e177e3f 100644 --- a/arch/tile/lib/exports.c +++ b/arch/tile/lib/exports.c @@ -38,11 +38,10 @@ EXPORT_SYMBOL(__mcount); /* arch/tile/lib/, various memcpy files */ EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(__copy_to_user_inatomic); -EXPORT_SYMBOL(__copy_from_user_inatomic); -EXPORT_SYMBOL(__copy_from_user_zeroing); +EXPORT_SYMBOL(raw_copy_to_user); +EXPORT_SYMBOL(raw_copy_from_user); #ifdef __tilegx__ -EXPORT_SYMBOL(__copy_in_user_inatomic); +EXPORT_SYMBOL(raw_copy_in_user); #endif /* hypervisor glue */ diff --git a/arch/tile/lib/memcpy_32.S b/arch/tile/lib/memcpy_32.S index a2771ae5da53..270f1267cd18 100644 --- a/arch/tile/lib/memcpy_32.S +++ b/arch/tile/lib/memcpy_32.S @@ -24,7 +24,6 @@ #define IS_MEMCPY 0 #define IS_COPY_FROM_USER 1 -#define IS_COPY_FROM_USER_ZEROING 2 #define IS_COPY_TO_USER -1 .section .text.memcpy_common, "ax" @@ -42,40 +41,31 @@ 9 -/* __copy_from_user_inatomic takes the kernel target address in r0, +/* raw_copy_from_user takes the kernel target address in r0, * the user source in r1, and the bytes to copy in r2. * It returns the number of uncopiable bytes (hopefully zero) in r0. */ -ENTRY(__copy_from_user_inatomic) -.type __copy_from_user_inatomic, @function - FEEDBACK_ENTER_EXPLICIT(__copy_from_user_inatomic, \ +ENTRY(raw_copy_from_user) +.type raw_copy_from_user, @function + FEEDBACK_ENTER_EXPLICIT(raw_copy_from_user, \ .text.memcpy_common, \ - .Lend_memcpy_common - __copy_from_user_inatomic) + .Lend_memcpy_common - raw_copy_from_user) { movei r29, IS_COPY_FROM_USER; j memcpy_common } - .size __copy_from_user_inatomic, . - __copy_from_user_inatomic + .size raw_copy_from_user, . - raw_copy_from_user -/* __copy_from_user_zeroing is like __copy_from_user_inatomic, but - * any uncopiable bytes are zeroed in the target. - */ -ENTRY(__copy_from_user_zeroing) -.type __copy_from_user_zeroing, @function - FEEDBACK_REENTER(__copy_from_user_inatomic) - { movei r29, IS_COPY_FROM_USER_ZEROING; j memcpy_common } - .size __copy_from_user_zeroing, . - __copy_from_user_zeroing - -/* __copy_to_user_inatomic takes the user target address in r0, +/* raw_copy_to_user takes the user target address in r0, * the kernel source in r1, and the bytes to copy in r2. * It returns the number of uncopiable bytes (hopefully zero) in r0. */ -ENTRY(__copy_to_user_inatomic) -.type __copy_to_user_inatomic, @function - FEEDBACK_REENTER(__copy_from_user_inatomic) +ENTRY(raw_copy_to_user) +.type raw_copy_to_user, @function + FEEDBACK_REENTER(raw_copy_from_user) { movei r29, IS_COPY_TO_USER; j memcpy_common } - .size __copy_to_user_inatomic, . - __copy_to_user_inatomic + .size raw_copy_to_user, . - raw_copy_to_user ENTRY(memcpy) .type memcpy, @function - FEEDBACK_REENTER(__copy_from_user_inatomic) + FEEDBACK_REENTER(raw_copy_from_user) { movei r29, IS_MEMCPY } .size memcpy, . - memcpy /* Fall through */ @@ -520,12 +510,7 @@ copy_from_user_fixup_loop: { bnzt r2, copy_from_user_fixup_loop } .Lcopy_from_user_fixup_zero_remainder: - { bbs r29, 2f } /* low bit set means IS_COPY_FROM_USER */ - /* byte-at-a-time loop faulted, so zero the rest. */ - { move r3, r2; bz r2, 2f /* should be impossible, but handle it. */ } -1: { sb r0, zero; addi r0, r0, 1; addi r3, r3, -1 } - { bnzt r3, 1b } -2: move lr, r27 + move lr, r27 { move r0, r2; jrp lr } copy_to_user_fixup_loop: diff --git a/arch/tile/lib/memcpy_user_64.c b/arch/tile/lib/memcpy_user_64.c index 97bbb6060b25..a3fea9fd973e 100644 --- a/arch/tile/lib/memcpy_user_64.c +++ b/arch/tile/lib/memcpy_user_64.c @@ -51,7 +51,7 @@ __v; \ }) -#define USERCOPY_FUNC __copy_to_user_inatomic +#define USERCOPY_FUNC raw_copy_to_user #define ST1(p, v) _ST((p), st1, (v)) #define ST2(p, v) _ST((p), st2, (v)) #define ST4(p, v) _ST((p), st4, (v)) @@ -62,7 +62,7 @@ #define LD8 LD #include "memcpy_64.c" -#define USERCOPY_FUNC __copy_from_user_inatomic +#define USERCOPY_FUNC raw_copy_from_user #define ST1 ST #define ST2 ST #define ST4 ST @@ -73,7 +73,7 @@ #define LD8(p) _LD((p), ld) #include "memcpy_64.c" -#define USERCOPY_FUNC __copy_in_user_inatomic +#define USERCOPY_FUNC raw_copy_in_user #define ST1(p, v) _ST((p), st1, (v)) #define ST2(p, v) _ST((p), st2, (v)) #define ST4(p, v) _ST((p), st4, (v)) @@ -83,12 +83,3 @@ #define LD4(p) _LD((p), ld4u) #define LD8(p) _LD((p), ld) #include "memcpy_64.c" - -unsigned long __copy_from_user_zeroing(void *to, const void __user *from, - unsigned long n) -{ - unsigned long rc = __copy_from_user_inatomic(to, from, n); - if (unlikely(rc)) - memset(to + n - rc, 0, rc); - return rc; -} diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index fd443852103c..ed9c5b5ff028 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -50,11 +50,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config GENERIC_BUG - bool - default y - depends on BUG - config HZ int default 100 diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index e9d42aab76dc..50a32c33d729 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -6,6 +6,7 @@ generic-y += delay.h generic-y += device.h generic-y += emergency-restart.h generic-y += exec.h +generic-y += extable.h generic-y += ftrace.h generic-y += futex.h generic-y += hardirq.h diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h index 3705620ca298..cc00fc50768f 100644 --- a/arch/um/include/asm/uaccess.h +++ b/arch/um/include/asm/uaccess.h @@ -7,7 +7,6 @@ #ifndef __UM_UACCESS_H #define __UM_UACCESS_H -#include <asm/thread_info.h> #include <asm/elf.h> #define __under_task_size(addr, size) \ @@ -22,8 +21,8 @@ #define __addr_range_nowrap(addr, size) \ ((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) -extern long __copy_from_user(void *to, const void __user *from, unsigned long n); -extern long __copy_to_user(void __user *to, const void *from, unsigned long n); +extern unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n); +extern unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n); extern long __strncpy_from_user(char *dst, const char __user *src, long count); extern long __strnlen_user(const void __user *str, long len); extern unsigned long __clear_user(void __user *mem, unsigned long len); @@ -32,12 +31,10 @@ static inline int __access_ok(unsigned long addr, unsigned long size); /* Teach asm-generic/uaccess.h that we have C functions for these. */ #define __access_ok __access_ok #define __clear_user __clear_user -#define __copy_to_user __copy_to_user -#define __copy_from_user __copy_from_user #define __strnlen_user __strnlen_user #define __strncpy_from_user __strncpy_from_user -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER #include <asm-generic/uaccess.h> @@ -46,7 +43,7 @@ static inline int __access_ok(unsigned long addr, unsigned long size) return __addr_range_nowrap(addr, size) && (__under_task_size(addr, size) || __access_ok_vsyscall(addr, size) || - segment_eq(get_fs(), KERNEL_DS)); + uaccess_kernel()); } #endif diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index de5d572225f3..cd1fa97776c3 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -302,8 +302,8 @@ extern int ignore_sigio_fd(int fd); extern void maybe_sigio_broken(int fd, int read); extern void sigio_broken(int fd, int read); -/* sys-x86_64/prctl.c */ -extern int os_arch_prctl(int pid, int code, unsigned long *addr); +/* prctl.c */ +extern int os_arch_prctl(int pid, int option, unsigned long *arg2); /* tty.c */ extern int get_pty(void); diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 85ac8adb069b..d450797a3a7c 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -139,16 +139,16 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg) return 0; } -long __copy_from_user(void *to, const void __user *from, unsigned long n) +unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - if (segment_eq(get_fs(), KERNEL_DS)) { + if (uaccess_kernel()) { memcpy(to, (__force void*)from, n); return 0; } return buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to); } -EXPORT_SYMBOL(__copy_from_user); +EXPORT_SYMBOL(raw_copy_from_user); static int copy_chunk_to_user(unsigned long to, int len, void *arg) { @@ -159,16 +159,16 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg) return 0; } -long __copy_to_user(void __user *to, const void *from, unsigned long n) +unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - if (segment_eq(get_fs(), KERNEL_DS)) { + if (uaccess_kernel()) { memcpy((__force void *) to, from, n); return 0; } return buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from); } -EXPORT_SYMBOL(__copy_to_user); +EXPORT_SYMBOL(raw_copy_to_user); static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) { @@ -189,7 +189,7 @@ long __strncpy_from_user(char *dst, const char __user *src, long count) long n; char *ptr = dst; - if (segment_eq(get_fs(), KERNEL_DS)) { + if (uaccess_kernel()) { strncpy(dst, (__force void *) src, count); return strnlen(dst, count); } @@ -210,7 +210,7 @@ static int clear_chunk(unsigned long addr, int len, void *unused) unsigned long __clear_user(void __user *mem, unsigned long len) { - if (segment_eq(get_fs(), KERNEL_DS)) { + if (uaccess_kernel()) { memset((__force void*)mem, 0, len); return 0; } @@ -235,7 +235,7 @@ long __strnlen_user(const void __user *str, long len) { int count = 0, n; - if (segment_eq(get_fs(), KERNEL_DS)) + if (uaccess_kernel()) return strnlen((__force char*)str, len) + 1; n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count); diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index ba87a27d6715..0b034ebbda2a 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -65,7 +65,9 @@ static struct clock_event_device timer_clockevent = { .set_next_event = itimer_next_event, .shift = 0, .max_delta_ns = 0xffffffff, - .min_delta_ns = TIMER_MIN_DELTA, //microsecond resolution should be enough for anyone, same as 640K RAM + .max_delta_ticks = 0xffffffff, + .min_delta_ns = TIMER_MIN_DELTA, + .min_delta_ticks = TIMER_MIN_DELTA, // microsecond resolution should be enough for anyone, same as 640K RAM .irq = 0, .mult = 1, }; diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index 84205fe1cd79..e9ad511c1043 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild @@ -10,6 +10,7 @@ generic-y += div64.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += fb.h generic-y += fcntl.h generic-y += ftrace.h diff --git a/arch/unicore32/include/asm/uaccess.h b/arch/unicore32/include/asm/uaccess.h index 897e11ad8124..1d55f2f83759 100644 --- a/arch/unicore32/include/asm/uaccess.h +++ b/arch/unicore32/include/asm/uaccess.h @@ -12,35 +12,30 @@ #ifndef __UNICORE_UACCESS_H__ #define __UNICORE_UACCESS_H__ -#include <linux/thread_info.h> -#include <linux/errno.h> - #include <asm/memory.h> -#define __copy_from_user __copy_from_user -#define __copy_to_user __copy_to_user #define __strncpy_from_user __strncpy_from_user #define __strnlen_user __strnlen_user #define __clear_user __clear_user -#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) +#define __kernel_ok (uaccess_kernel()) #define __user_ok(addr, size) (((size) <= TASK_SIZE) \ && ((addr) <= TASK_SIZE - (size))) #define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size))) extern unsigned long __must_check -__copy_from_user(void *to, const void __user *from, unsigned long n); +raw_copy_from_user(void *to, const void __user *from, unsigned long n); extern unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n); +raw_copy_to_user(void __user *to, const void *from, unsigned long n); extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count); extern unsigned long __strnlen_user(const char __user *s, long n); +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER #include <asm-generic/uaccess.h> -extern int fixup_exception(struct pt_regs *regs); - #endif /* __UNICORE_UACCESS_H__ */ diff --git a/arch/unicore32/kernel/ksyms.c b/arch/unicore32/kernel/ksyms.c index 0323528a80fd..dcc72ee1fcdb 100644 --- a/arch/unicore32/kernel/ksyms.c +++ b/arch/unicore32/kernel/ksyms.c @@ -46,8 +46,8 @@ EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(copy_page); -EXPORT_SYMBOL(__copy_from_user); -EXPORT_SYMBOL(__copy_to_user); +EXPORT_SYMBOL(raw_copy_from_user); +EXPORT_SYMBOL(raw_copy_to_user); EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(__ashldi3); diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index d22c1dc7e39e..ddaf78ae6854 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c @@ -178,7 +178,7 @@ void __show_regs(struct pt_regs *regs) buf, interrupts_enabled(regs) ? "n" : "ff", fast_interrupts_enabled(regs) ? "n" : "ff", processor_modes[processor_mode(regs)], - segment_eq(get_fs(), get_ds()) ? "kernel" : "user"); + uaccess_kernel() ? "kernel" : "user"); { unsigned int ctrl; diff --git a/arch/unicore32/kernel/time.c b/arch/unicore32/kernel/time.c index fceaa673f861..c6b3fa3ee0b6 100644 --- a/arch/unicore32/kernel/time.c +++ b/arch/unicore32/kernel/time.c @@ -91,8 +91,10 @@ void __init time_init(void) ckevt_puv3_osmr0.max_delta_ns = clockevent_delta2ns(0x7fffffff, &ckevt_puv3_osmr0); + ckevt_puv3_osmr0.max_delta_ticks = 0x7fffffff; ckevt_puv3_osmr0.min_delta_ns = clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_puv3_osmr0) + 1; + ckevt_puv3_osmr0.min_delta_ticks = MIN_OSCR_DELTA * 2; ckevt_puv3_osmr0.cpumask = cpumask_of(0); setup_irq(IRQ_TIMER0, &puv3_timer_irq); diff --git a/arch/unicore32/lib/copy_from_user.S b/arch/unicore32/lib/copy_from_user.S index ab0767ea5dbd..5f80fcbe8631 100644 --- a/arch/unicore32/lib/copy_from_user.S +++ b/arch/unicore32/lib/copy_from_user.S @@ -16,7 +16,7 @@ /* * Prototype: * - * size_t __copy_from_user(void *to, const void *from, size_t n) + * size_t raw_copy_from_user(void *to, const void *from, size_t n) * * Purpose: * @@ -87,22 +87,18 @@ .text -ENTRY(__copy_from_user) +ENTRY(raw_copy_from_user) #include "copy_template.S" -ENDPROC(__copy_from_user) +ENDPROC(raw_copy_from_user) .pushsection .fixup,"ax" .align 0 copy_abort_preamble - ldm.w (r1, r2), [sp]+ - sub r3, r0, r1 - rsub r2, r3, r2 - stw r2, [sp] - mov r1, #0 - b.l memset - ldw.w r0, [sp]+, #4 + ldm.w (r1, r2, r3), [sp]+ + sub r0, r0, r1 + rsub r0, r0, r2 copy_abort_end .popsection diff --git a/arch/unicore32/lib/copy_to_user.S b/arch/unicore32/lib/copy_to_user.S index 6e22151c840d..857c6816ffe7 100644 --- a/arch/unicore32/lib/copy_to_user.S +++ b/arch/unicore32/lib/copy_to_user.S @@ -16,7 +16,7 @@ /* * Prototype: * - * size_t __copy_to_user(void *to, const void *from, size_t n) + * size_t raw_copy_to_user(void *to, const void *from, size_t n) * * Purpose: * @@ -79,11 +79,11 @@ .text -WEAK(__copy_to_user) +WEAK(raw_copy_to_user) #include "copy_template.S" -ENDPROC(__copy_to_user) +ENDPROC(raw_copy_to_user) .pushsection .fixup,"ax" .align 0 diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cc98d5a294ee..2b899858532a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -98,7 +98,6 @@ config X86 select HAVE_ACPI_APEI_NMI if ACPI select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_ARCH_AUDITSYSCALL - select HAVE_ARCH_HARDENED_USERCOPY select HAVE_ARCH_HUGE_VMAP if X86_64 || X86_PAE select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KASAN if X86_64 && SPARSEMEM_VMEMMAP @@ -127,7 +126,7 @@ config X86 select HAVE_EBPF_JIT if X86_64 select HAVE_EFFICIENT_UNALIGNED_ACCESS select HAVE_EXIT_THREAD - select HAVE_FENTRY if X86_64 + select HAVE_FENTRY if X86_64 || DYNAMIC_FTRACE select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER @@ -1043,6 +1042,14 @@ config X86_MCE The action the kernel takes depends on the severity of the problem, ranging from warning messages to halting the machine. +config X86_MCELOG_LEGACY + bool "Support for deprecated /dev/mcelog character device" + depends on X86_MCE + ---help--- + Enable support for /dev/mcelog which is needed by the old mcelog + userspace logging daemon. Consider switching to the new generation + rasdaemon solution. + config X86_MCE_INTEL def_bool y prompt "Intel MCE features" @@ -1072,7 +1079,7 @@ config X86_MCE_THRESHOLD def_bool y config X86_MCE_INJECT - depends on X86_MCE && X86_LOCAL_APIC + depends on X86_MCE && X86_LOCAL_APIC && X86_MCELOG_LEGACY tristate "Machine check injector support" ---help--- Provide support for injecting machine checks for testing purposes. @@ -1966,7 +1973,7 @@ config RELOCATABLE config RANDOMIZE_BASE bool "Randomize the address of the kernel image (KASLR)" depends on RELOCATABLE - default n + default y ---help--- In support of Kernel Address Space Layout Randomization (KASLR), this randomizes the physical address at which the kernel image @@ -1996,7 +2003,7 @@ config RANDOMIZE_BASE theoretically possible, but the implementations are further limited due to memory layouts. - If unsure, say N. + If unsure, say Y. # Relocation on x86 needs some additional build support config X86_NEED_RELOCS @@ -2045,7 +2052,7 @@ config RANDOMIZE_MEMORY configuration have in average 30,000 different possible virtual addresses for each memory section. - If unsure, say N. + If unsure, say Y. config RANDOMIZE_MEMORY_PHYSICAL_PADDING hex "Physical memory mapping padding" if EXPERT diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 2d449337a360..4430dd489620 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -88,10 +88,10 @@ else KBUILD_CFLAGS += -m64 # Align jump targets to 1 byte, not the default 16 bytes: - KBUILD_CFLAGS += -falign-jumps=1 + KBUILD_CFLAGS += $(call cc-option,-falign-jumps=1) # Pack loops tightly as well: - KBUILD_CFLAGS += -falign-loops=1 + KBUILD_CFLAGS += $(call cc-option,-falign-loops=1) # Don't autogenerate traditional x87 instructions KBUILD_CFLAGS += $(call cc-option,-mno-80387) @@ -120,10 +120,6 @@ else # -funit-at-a-time shrinks the kernel .text considerably # unfortunately it makes reading oopses harder. KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) - - # this works around some issues with generating unwind tables in older gccs - # newer gccs do it by default - KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args) endif ifdef CONFIG_X86_X32 @@ -147,6 +143,45 @@ ifeq ($(CONFIG_KMEMCHECK),y) KBUILD_CFLAGS += $(call cc-option,-fno-builtin-memcpy) endif +# +# If the function graph tracer is used with mcount instead of fentry, +# '-maccumulate-outgoing-args' is needed to prevent a GCC bug +# (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42109) +# +ifdef CONFIG_FUNCTION_GRAPH_TRACER + ifndef CONFIG_HAVE_FENTRY + ACCUMULATE_OUTGOING_ARGS := 1 + else + ifeq ($(call cc-option-yn, -mfentry), n) + ACCUMULATE_OUTGOING_ARGS := 1 + + # GCC ignores '-maccumulate-outgoing-args' when used with '-Os'. + # If '-Os' is enabled, disable it and print a warning. + ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE + undefine CONFIG_CC_OPTIMIZE_FOR_SIZE + $(warning Disabling CONFIG_CC_OPTIMIZE_FOR_SIZE. Your compiler does not have -mfentry so you cannot optimize for size with CONFIG_FUNCTION_GRAPH_TRACER.) + endif + + endif + endif +endif + +# +# Jump labels need '-maccumulate-outgoing-args' for gcc < 4.5.2 to prevent a +# GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46226). There's no way +# to test for this bug at compile-time because the test case needs to execute, +# which is a no-go for cross compilers. So check the GCC version instead. +# +ifdef CONFIG_JUMP_LABEL + ifneq ($(ACCUMULATE_OUTGOING_ARGS), 1) + ACCUMULATE_OUTGOING_ARGS = $(call cc-if-fullversion, -lt, 040502, 1) + endif +endif + +ifeq ($(ACCUMULATE_OUTGOING_ARGS), 1) + KBUILD_CFLAGS += -maccumulate-outgoing-args +endif + # Stackpointer is addressed different for 32 bit and 64 bit x86 sp-$(CONFIG_X86_32) := esp sp-$(CONFIG_X86_64) := rsp diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu index 6647ed49c66c..a45eb15b7cf2 100644 --- a/arch/x86/Makefile_32.cpu +++ b/arch/x86/Makefile_32.cpu @@ -45,24 +45,6 @@ cflags-$(CONFIG_MGEODE_LX) += $(call cc-option,-march=geode,-march=pentium-mmx) # cpu entries cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic,$(call tune,i686)) -# Work around the pentium-mmx code generator madness of gcc4.4.x which -# does stack alignment by generating horrible code _before_ the mcount -# prologue (push %ebp, mov %esp, %ebp) which breaks the function graph -# tracer assumptions. For i686, generic, core2 this is set by the -# compiler anyway -ifeq ($(CONFIG_FUNCTION_GRAPH_TRACER), y) -ADD_ACCUMULATE_OUTGOING_ARGS := y -endif - -# Work around to a bug with asm goto with first implementations of it -# in gcc causing gcc to mess up the push and pop of the stack in some -# uses of asm goto. -ifeq ($(CONFIG_JUMP_LABEL), y) -ADD_ACCUMULATE_OUTGOING_ARGS := y -endif - -cflags-$(ADD_ACCUMULATE_OUTGOING_ARGS) += $(call cc-option,-maccumulate-outgoing-args) - # Bug fix for binutils: this option is required in order to keep # binutils from generating NOPL instructions against our will. ifneq ($(CONFIG_X86_P6_NOP),y) diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index 9b42b6d1e902..ef5a9cc66fb8 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h @@ -16,7 +16,7 @@ #ifndef BOOT_BOOT_H #define BOOT_BOOT_H -#define STACK_SIZE 512 /* Minimum number of bytes for stack */ +#define STACK_SIZE 1024 /* Minimum number of bytes for stack */ #ifndef __ASSEMBLY__ diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 801c7a158e55..cbf4b87f55b9 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -9,7 +9,9 @@ #include <linux/efi.h> #include <linux/pci.h> + #include <asm/efi.h> +#include <asm/e820/types.h> #include <asm/setup.h> #include <asm/desc.h> @@ -729,7 +731,7 @@ static void add_e820ext(struct boot_params *params, unsigned long size; e820ext->type = SETUP_E820_EXT; - e820ext->len = nr_entries * sizeof(struct e820entry); + e820ext->len = nr_entries * sizeof(struct boot_e820_entry); e820ext->next = 0; data = (struct setup_data *)(unsigned long)params->hdr.setup_data; @@ -746,9 +748,9 @@ static void add_e820ext(struct boot_params *params, static efi_status_t setup_e820(struct boot_params *params, struct setup_data *e820ext, u32 e820ext_size) { - struct e820entry *e820_map = ¶ms->e820_map[0]; + struct boot_e820_entry *entry = params->e820_table; struct efi_info *efi = ¶ms->efi_info; - struct e820entry *prev = NULL; + struct boot_e820_entry *prev = NULL; u32 nr_entries; u32 nr_desc; int i; @@ -773,15 +775,15 @@ static efi_status_t setup_e820(struct boot_params *params, case EFI_MEMORY_MAPPED_IO: case EFI_MEMORY_MAPPED_IO_PORT_SPACE: case EFI_PAL_CODE: - e820_type = E820_RESERVED; + e820_type = E820_TYPE_RESERVED; break; case EFI_UNUSABLE_MEMORY: - e820_type = E820_UNUSABLE; + e820_type = E820_TYPE_UNUSABLE; break; case EFI_ACPI_RECLAIM_MEMORY: - e820_type = E820_ACPI; + e820_type = E820_TYPE_ACPI; break; case EFI_LOADER_CODE: @@ -789,15 +791,15 @@ static efi_status_t setup_e820(struct boot_params *params, case EFI_BOOT_SERVICES_CODE: case EFI_BOOT_SERVICES_DATA: case EFI_CONVENTIONAL_MEMORY: - e820_type = E820_RAM; + e820_type = E820_TYPE_RAM; break; case EFI_ACPI_MEMORY_NVS: - e820_type = E820_NVS; + e820_type = E820_TYPE_NVS; break; case EFI_PERSISTENT_MEMORY: - e820_type = E820_PMEM; + e820_type = E820_TYPE_PMEM; break; default: @@ -811,26 +813,26 @@ static efi_status_t setup_e820(struct boot_params *params, continue; } - if (nr_entries == ARRAY_SIZE(params->e820_map)) { - u32 need = (nr_desc - i) * sizeof(struct e820entry) + + if (nr_entries == ARRAY_SIZE(params->e820_table)) { + u32 need = (nr_desc - i) * sizeof(struct e820_entry) + sizeof(struct setup_data); if (!e820ext || e820ext_size < need) return EFI_BUFFER_TOO_SMALL; /* boot_params map full, switch to e820 extended */ - e820_map = (struct e820entry *)e820ext->data; + entry = (struct boot_e820_entry *)e820ext->data; } - e820_map->addr = d->phys_addr; - e820_map->size = d->num_pages << PAGE_SHIFT; - e820_map->type = e820_type; - prev = e820_map++; + entry->addr = d->phys_addr; + entry->size = d->num_pages << PAGE_SHIFT; + entry->type = e820_type; + prev = entry++; nr_entries++; } - if (nr_entries > ARRAY_SIZE(params->e820_map)) { - u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_map); + if (nr_entries > ARRAY_SIZE(params->e820_table)) { + u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_table); add_e820ext(params, e820ext, nr_e820ext); nr_entries -= nr_e820ext; @@ -848,7 +850,7 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext, unsigned long size; size = sizeof(struct setup_data) + - sizeof(struct e820entry) * nr_desc; + sizeof(struct e820_entry) * nr_desc; if (*e820ext) { efi_call_early(free_pool, *e820ext); @@ -884,9 +886,9 @@ static efi_status_t exit_boot_func(efi_system_table_t *sys_table_arg, if (first) { nr_desc = *map->buff_size / *map->desc_size; - if (nr_desc > ARRAY_SIZE(p->boot_params->e820_map)) { + if (nr_desc > ARRAY_SIZE(p->boot_params->e820_table)) { u32 nr_e820ext = nr_desc - - ARRAY_SIZE(p->boot_params->e820_map); + ARRAY_SIZE(p->boot_params->e820_table); status = alloc_e820ext(nr_e820ext, &p->e820ext, &p->e820ext_size); diff --git a/arch/x86/boot/compressed/error.c b/arch/x86/boot/compressed/error.c index 6248740b68b5..31922023de49 100644 --- a/arch/x86/boot/compressed/error.c +++ b/arch/x86/boot/compressed/error.c @@ -4,6 +4,7 @@ * memcpy() and memmove() are defined for the compressed boot environment. */ #include "misc.h" +#include "error.h" void warn(char *m) { diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index 8b7c9e75edcb..54c24f0a43d3 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -426,7 +426,7 @@ static unsigned long slots_fetch_random(void) return 0; } -static void process_e820_entry(struct e820entry *entry, +static void process_e820_entry(struct boot_e820_entry *entry, unsigned long minimum, unsigned long image_size) { @@ -435,7 +435,7 @@ static void process_e820_entry(struct e820entry *entry, unsigned long start_orig; /* Skip non-RAM entries. */ - if (entry->type != E820_RAM) + if (entry->type != E820_TYPE_RAM) return; /* On 32-bit, ignore entries entirely above our maximum. */ @@ -518,7 +518,7 @@ static unsigned long find_random_phys_addr(unsigned long minimum, /* Verify potential e820 positions, appending to slots list. */ for (i = 0; i < boot_params->e820_entries; i++) { - process_e820_entry(&boot_params->e820_map[i], minimum, + process_e820_entry(&boot_params->e820_table[i], minimum, image_size); if (slot_area_index == MAX_SLOT_AREA) { debug_putstr("Aborted e820 scan (slot_areas full)!\n"); @@ -597,10 +597,17 @@ void choose_random_location(unsigned long input, add_identity_map(random_addr, output_size); *output = random_addr; } + + /* + * This loads the identity mapping page table. + * This should only be done if a new physical address + * is found for the kernel, otherwise we should keep + * the old page table to make it be like the "nokaslr" + * case. + */ + finalize_identity_maps(); } - /* This actually loads the identity pagetable on x86_64. */ - finalize_identity_maps(); /* Pick random virtual address starting from LOAD_PHYSICAL_ADDR. */ if (IS_ENABLED(CONFIG_X86_64)) diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 3dd5be33aaa7..2ed8f0c25def 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -18,7 +18,6 @@ #include <asm/segment.h> #include <generated/utsrelease.h> #include <asm/boot.h> -#include <asm/e820.h> #include <asm/page_types.h> #include <asm/setup.h> #include <asm/bootparam.h> diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c index db75d07c3645..d9c28c87e477 100644 --- a/arch/x86/boot/memory.c +++ b/arch/x86/boot/memory.c @@ -21,8 +21,8 @@ static int detect_memory_e820(void) { int count = 0; struct biosregs ireg, oreg; - struct e820entry *desc = boot_params.e820_map; - static struct e820entry buf; /* static so it is zeroed */ + struct boot_e820_entry *desc = boot_params.e820_table; + static struct boot_e820_entry buf; /* static so it is zeroed */ initregs(&ireg); ireg.ax = 0xe820; @@ -66,7 +66,7 @@ static int detect_memory_e820(void) *desc++ = buf; count++; - } while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_map)); + } while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_table)); return boot_params.e820_entries = count; } diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index 5fa6ee2c2dde..6cf79e1a6830 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -57,6 +57,8 @@ CONFIG_EFI=y CONFIG_HZ_1000=y CONFIG_KEXEC=y CONFIG_CRASH_DUMP=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_RANDOMIZE_MEMORY=y # CONFIG_COMPAT_VDSO is not set CONFIG_HIBERNATION=y CONFIG_PM_DEBUG=y diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index 6205d3b81e6d..de45f57b410d 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -55,6 +55,8 @@ CONFIG_EFI=y CONFIG_HZ_1000=y CONFIG_KEXEC=y CONFIG_CRASH_DUMP=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_RANDOMIZE_MEMORY=y # CONFIG_COMPAT_VDSO is not set CONFIG_HIBERNATION=y CONFIG_PM_DEBUG=y diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index 57f7ec35216e..50bc26949e9e 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -35,16 +35,13 @@ #include <asm/errno.h> #include <asm/segment.h> #include <asm/smp.h> -#include <asm/page_types.h> #include <asm/percpu.h> #include <asm/processor-flags.h> -#include <asm/ftrace.h> #include <asm/irq_vectors.h> #include <asm/cpufeatures.h> #include <asm/alternative-asm.h> #include <asm/asm.h> #include <asm/smap.h> -#include <asm/export.h> #include <asm/frame.h> .section .entry.text, "ax" @@ -585,7 +582,7 @@ ENTRY(iret_exc ) * will soon execute iret and the tracer was already set to * the irqstate after the IRET: */ - DISABLE_INTERRUPTS(CLBR_EAX) + DISABLE_INTERRUPTS(CLBR_ANY) lss (%esp), %esp /* switch to espfix segment */ jmp .Lrestore_nocheck #endif @@ -886,172 +883,6 @@ BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, #endif /* CONFIG_HYPERV */ -#ifdef CONFIG_FUNCTION_TRACER -#ifdef CONFIG_DYNAMIC_FTRACE - -ENTRY(mcount) - ret -END(mcount) - -ENTRY(ftrace_caller) - pushl %eax - pushl %ecx - pushl %edx - pushl $0 /* Pass NULL as regs pointer */ - movl 4*4(%esp), %eax - movl 0x4(%ebp), %edx - movl function_trace_op, %ecx - subl $MCOUNT_INSN_SIZE, %eax - -.globl ftrace_call -ftrace_call: - call ftrace_stub - - addl $4, %esp /* skip NULL pointer */ - popl %edx - popl %ecx - popl %eax -.Lftrace_ret: -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -.globl ftrace_graph_call -ftrace_graph_call: - jmp ftrace_stub -#endif - -/* This is weak to keep gas from relaxing the jumps */ -WEAK(ftrace_stub) - ret -END(ftrace_caller) - -ENTRY(ftrace_regs_caller) - pushf /* push flags before compare (in cs location) */ - - /* - * i386 does not save SS and ESP when coming from kernel. - * Instead, to get sp, ®s->sp is used (see ptrace.h). - * Unfortunately, that means eflags must be at the same location - * as the current return ip is. We move the return ip into the - * ip location, and move flags into the return ip location. - */ - pushl 4(%esp) /* save return ip into ip slot */ - - pushl $0 /* Load 0 into orig_ax */ - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl %eax - pushl %ebp - pushl %edi - pushl %esi - pushl %edx - pushl %ecx - pushl %ebx - - movl 13*4(%esp), %eax /* Get the saved flags */ - movl %eax, 14*4(%esp) /* Move saved flags into regs->flags location */ - /* clobbering return ip */ - movl $__KERNEL_CS, 13*4(%esp) - - movl 12*4(%esp), %eax /* Load ip (1st parameter) */ - subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */ - movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */ - movl function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */ - pushl %esp /* Save pt_regs as 4th parameter */ - -GLOBAL(ftrace_regs_call) - call ftrace_stub - - addl $4, %esp /* Skip pt_regs */ - movl 14*4(%esp), %eax /* Move flags back into cs */ - movl %eax, 13*4(%esp) /* Needed to keep addl from modifying flags */ - movl 12*4(%esp), %eax /* Get return ip from regs->ip */ - movl %eax, 14*4(%esp) /* Put return ip back for ret */ - - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp - popl %eax - popl %ds - popl %es - popl %fs - popl %gs - addl $8, %esp /* Skip orig_ax and ip */ - popf /* Pop flags at end (no addl to corrupt flags) */ - jmp .Lftrace_ret - - popf - jmp ftrace_stub -#else /* ! CONFIG_DYNAMIC_FTRACE */ - -ENTRY(mcount) - cmpl $__PAGE_OFFSET, %esp - jb ftrace_stub /* Paging not enabled yet? */ - - cmpl $ftrace_stub, ftrace_trace_function - jnz .Ltrace -#ifdef CONFIG_FUNCTION_GRAPH_TRACER - cmpl $ftrace_stub, ftrace_graph_return - jnz ftrace_graph_caller - - cmpl $ftrace_graph_entry_stub, ftrace_graph_entry - jnz ftrace_graph_caller -#endif -.globl ftrace_stub -ftrace_stub: - ret - - /* taken from glibc */ -.Ltrace: - pushl %eax - pushl %ecx - pushl %edx - movl 0xc(%esp), %eax - movl 0x4(%ebp), %edx - subl $MCOUNT_INSN_SIZE, %eax - - call *ftrace_trace_function - - popl %edx - popl %ecx - popl %eax - jmp ftrace_stub -END(mcount) -#endif /* CONFIG_DYNAMIC_FTRACE */ -EXPORT_SYMBOL(mcount) -#endif /* CONFIG_FUNCTION_TRACER */ - -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -ENTRY(ftrace_graph_caller) - pushl %eax - pushl %ecx - pushl %edx - movl 0xc(%esp), %eax - lea 0x4(%ebp), %edx - movl (%ebp), %ecx - subl $MCOUNT_INSN_SIZE, %eax - call prepare_ftrace_return - popl %edx - popl %ecx - popl %eax - ret -END(ftrace_graph_caller) - -.globl return_to_handler -return_to_handler: - pushl %eax - pushl %edx - movl %ebp, %eax - call ftrace_return_to_handler - movl %eax, %ecx - popl %edx - popl %eax - jmp *%ecx -#endif - #ifdef CONFIG_TRACING ENTRY(trace_page_fault) ASM_CLAC diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 044d18ebc43c..d2b2a2948ffe 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -212,7 +212,7 @@ entry_SYSCALL_64_fastpath: * If we see that no exit work is required (which we are required * to check with IRQs off), then we can go straight to SYSRET64. */ - DISABLE_INTERRUPTS(CLBR_NONE) + DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF movq PER_CPU_VAR(current_task), %r11 testl $_TIF_ALLWORK_MASK, TASK_TI_flags(%r11) @@ -233,7 +233,7 @@ entry_SYSCALL_64_fastpath: * raise(3) will trigger this, for example. IRQs are off. */ TRACE_IRQS_ON - ENABLE_INTERRUPTS(CLBR_NONE) + ENABLE_INTERRUPTS(CLBR_ANY) SAVE_EXTRA_REGS movq %rsp, %rdi call syscall_return_slowpath /* returns with IRQs disabled */ @@ -343,7 +343,7 @@ ENTRY(stub_ptregs_64) * Called from fast path -- disable IRQs again, pop return address * and jump to slow path */ - DISABLE_INTERRUPTS(CLBR_NONE) + DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF popq %rax jmp entry_SYSCALL64_slow_path @@ -518,7 +518,7 @@ common_interrupt: interrupt do_IRQ /* 0(%rsp): old RSP */ ret_from_intr: - DISABLE_INTERRUPTS(CLBR_NONE) + DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF decl PER_CPU_VAR(irq_count) @@ -1051,7 +1051,7 @@ END(paranoid_entry) * On entry, ebx is "no swapgs" flag (1: don't need swapgs, 0: need it) */ ENTRY(paranoid_exit) - DISABLE_INTERRUPTS(CLBR_NONE) + DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF_DEBUG testl %ebx, %ebx /* swapgs needed? */ jnz paranoid_exit_no_swapgs @@ -1156,10 +1156,9 @@ END(error_entry) * 0: user gsbase is loaded, we need SWAPGS and standard preparation for return to usermode */ ENTRY(error_exit) - movl %ebx, %eax - DISABLE_INTERRUPTS(CLBR_NONE) + DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF - testl %eax, %eax + testl %ebx, %ebx jnz retint_kernel jmp retint_user END(error_exit) diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index 9ba050fe47f3..0af59fa789ea 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -390,3 +390,4 @@ 381 i386 pkey_alloc sys_pkey_alloc 382 i386 pkey_free sys_pkey_free 383 i386 statx sys_statx +384 i386 arch_prctl sys_arch_prctl compat_sys_arch_prctl diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c index 7853b53959cd..3f9d1a83891a 100644 --- a/arch/x86/entry/vdso/vdso32-setup.c +++ b/arch/x86/entry/vdso/vdso32-setup.c @@ -30,8 +30,10 @@ static int __init vdso32_setup(char *s) { vdso32_enabled = simple_strtoul(s, NULL, 0); - if (vdso32_enabled > 1) + if (vdso32_enabled > 1) { pr_warn("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n"); + vdso32_enabled = 0; + } return 1; } @@ -62,13 +64,18 @@ subsys_initcall(sysenter_setup); /* Register vsyscall32 into the ABI table */ #include <linux/sysctl.h> +static const int zero; +static const int one = 1; + static struct ctl_table abi_table2[] = { { .procname = "vsyscall32", .data = &vdso32_enabled, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec + .proc_handler = proc_dointvec_minmax, + .extra1 = (int *)&zero, + .extra2 = (int *)&one, }, {} }; diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c index b28200dea715..3641e24fdac5 100644 --- a/arch/x86/events/amd/iommu.c +++ b/arch/x86/events/amd/iommu.c @@ -11,6 +11,8 @@ * published by the Free Software Foundation. */ +#define pr_fmt(fmt) "perf/amd_iommu: " fmt + #include <linux/perf_event.h> #include <linux/init.h> #include <linux/cpumask.h> @@ -21,44 +23,42 @@ #define COUNTER_SHIFT 16 -#define _GET_BANK(ev) ((u8)(ev->hw.extra_reg.reg >> 8)) -#define _GET_CNTR(ev) ((u8)(ev->hw.extra_reg.reg)) +/* iommu pmu conf masks */ +#define GET_CSOURCE(x) ((x)->conf & 0xFFULL) +#define GET_DEVID(x) (((x)->conf >> 8) & 0xFFFFULL) +#define GET_DOMID(x) (((x)->conf >> 24) & 0xFFFFULL) +#define GET_PASID(x) (((x)->conf >> 40) & 0xFFFFFULL) -/* iommu pmu config masks */ -#define _GET_CSOURCE(ev) ((ev->hw.config & 0xFFULL)) -#define _GET_DEVID(ev) ((ev->hw.config >> 8) & 0xFFFFULL) -#define _GET_PASID(ev) ((ev->hw.config >> 24) & 0xFFFFULL) -#define _GET_DOMID(ev) ((ev->hw.config >> 40) & 0xFFFFULL) -#define _GET_DEVID_MASK(ev) ((ev->hw.extra_reg.config) & 0xFFFFULL) -#define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xFFFFULL) -#define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xFFFFULL) +/* iommu pmu conf1 masks */ +#define GET_DEVID_MASK(x) ((x)->conf1 & 0xFFFFULL) +#define GET_DOMID_MASK(x) (((x)->conf1 >> 16) & 0xFFFFULL) +#define GET_PASID_MASK(x) (((x)->conf1 >> 32) & 0xFFFFFULL) -static struct perf_amd_iommu __perf_iommu; +#define IOMMU_NAME_SIZE 16 struct perf_amd_iommu { + struct list_head list; struct pmu pmu; + struct amd_iommu *iommu; + char name[IOMMU_NAME_SIZE]; u8 max_banks; u8 max_counters; u64 cntr_assign_mask; raw_spinlock_t lock; - const struct attribute_group *attr_groups[4]; }; -#define format_group attr_groups[0] -#define cpumask_group attr_groups[1] -#define events_group attr_groups[2] -#define null_group attr_groups[3] +static LIST_HEAD(perf_amd_iommu_list); /*--------------------------------------------- * sysfs format attributes *---------------------------------------------*/ PMU_FORMAT_ATTR(csource, "config:0-7"); PMU_FORMAT_ATTR(devid, "config:8-23"); -PMU_FORMAT_ATTR(pasid, "config:24-39"); -PMU_FORMAT_ATTR(domid, "config:40-55"); +PMU_FORMAT_ATTR(domid, "config:24-39"); +PMU_FORMAT_ATTR(pasid, "config:40-59"); PMU_FORMAT_ATTR(devid_mask, "config1:0-15"); -PMU_FORMAT_ATTR(pasid_mask, "config1:16-31"); -PMU_FORMAT_ATTR(domid_mask, "config1:32-47"); +PMU_FORMAT_ATTR(domid_mask, "config1:16-31"); +PMU_FORMAT_ATTR(pasid_mask, "config1:32-51"); static struct attribute *iommu_format_attrs[] = { &format_attr_csource.attr, @@ -79,6 +79,10 @@ static struct attribute_group amd_iommu_format_group = { /*--------------------------------------------- * sysfs events attributes *---------------------------------------------*/ +static struct attribute_group amd_iommu_events_group = { + .name = "events", +}; + struct amd_iommu_event_desc { struct kobj_attribute attr; const char *event; @@ -150,30 +154,34 @@ static struct attribute_group amd_iommu_cpumask_group = { /*---------------------------------------------*/ -static int get_next_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu) +static int get_next_avail_iommu_bnk_cntr(struct perf_event *event) { + struct perf_amd_iommu *piommu = container_of(event->pmu, struct perf_amd_iommu, pmu); + int max_cntrs = piommu->max_counters; + int max_banks = piommu->max_banks; + u32 shift, bank, cntr; unsigned long flags; - int shift, bank, cntr, retval; - int max_banks = perf_iommu->max_banks; - int max_cntrs = perf_iommu->max_counters; + int retval; - raw_spin_lock_irqsave(&perf_iommu->lock, flags); + raw_spin_lock_irqsave(&piommu->lock, flags); for (bank = 0, shift = 0; bank < max_banks; bank++) { for (cntr = 0; cntr < max_cntrs; cntr++) { shift = bank + (bank*3) + cntr; - if (perf_iommu->cntr_assign_mask & (1ULL<<shift)) { + if (piommu->cntr_assign_mask & BIT_ULL(shift)) { continue; } else { - perf_iommu->cntr_assign_mask |= (1ULL<<shift); - retval = ((u16)((u16)bank<<8) | (u8)(cntr)); + piommu->cntr_assign_mask |= BIT_ULL(shift); + event->hw.iommu_bank = bank; + event->hw.iommu_cntr = cntr; + retval = 0; goto out; } } } retval = -ENOSPC; out: - raw_spin_unlock_irqrestore(&perf_iommu->lock, flags); + raw_spin_unlock_irqrestore(&piommu->lock, flags); return retval; } @@ -202,8 +210,6 @@ static int clear_avail_iommu_bnk_cntr(struct perf_amd_iommu *perf_iommu, static int perf_iommu_event_init(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; - struct perf_amd_iommu *perf_iommu; - u64 config, config1; /* test the event attr type check for PMU enumeration */ if (event->attr.type != event->pmu->type) @@ -225,80 +231,62 @@ static int perf_iommu_event_init(struct perf_event *event) if (event->cpu < 0) return -EINVAL; - perf_iommu = &__perf_iommu; - - if (event->pmu != &perf_iommu->pmu) - return -ENOENT; - - if (perf_iommu) { - config = event->attr.config; - config1 = event->attr.config1; - } else { - return -EINVAL; - } - - /* integrate with iommu base devid (0000), assume one iommu */ - perf_iommu->max_banks = - amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID); - perf_iommu->max_counters = - amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID); - if ((perf_iommu->max_banks == 0) || (perf_iommu->max_counters == 0)) - return -EINVAL; - /* update the hw_perf_event struct with the iommu config data */ - hwc->config = config; - hwc->extra_reg.config = config1; + hwc->conf = event->attr.config; + hwc->conf1 = event->attr.config1; return 0; } +static inline struct amd_iommu *perf_event_2_iommu(struct perf_event *ev) +{ + return (container_of(ev->pmu, struct perf_amd_iommu, pmu))->iommu; +} + static void perf_iommu_enable_event(struct perf_event *ev) { - u8 csource = _GET_CSOURCE(ev); - u16 devid = _GET_DEVID(ev); + struct amd_iommu *iommu = perf_event_2_iommu(ev); + struct hw_perf_event *hwc = &ev->hw; + u8 bank = hwc->iommu_bank; + u8 cntr = hwc->iommu_cntr; u64 reg = 0ULL; - reg = csource; - amd_iommu_pc_get_set_reg_val(devid, - _GET_BANK(ev), _GET_CNTR(ev) , - IOMMU_PC_COUNTER_SRC_REG, ®, true); + reg = GET_CSOURCE(hwc); + amd_iommu_pc_set_reg(iommu, bank, cntr, IOMMU_PC_COUNTER_SRC_REG, ®); - reg = 0ULL | devid | (_GET_DEVID_MASK(ev) << 32); + reg = GET_DEVID_MASK(hwc); + reg = GET_DEVID(hwc) | (reg << 32); if (reg) - reg |= (1UL << 31); - amd_iommu_pc_get_set_reg_val(devid, - _GET_BANK(ev), _GET_CNTR(ev) , - IOMMU_PC_DEVID_MATCH_REG, ®, true); + reg |= BIT(31); + amd_iommu_pc_set_reg(iommu, bank, cntr, IOMMU_PC_DEVID_MATCH_REG, ®); - reg = 0ULL | _GET_PASID(ev) | (_GET_PASID_MASK(ev) << 32); + reg = GET_PASID_MASK(hwc); + reg = GET_PASID(hwc) | (reg << 32); if (reg) - reg |= (1UL << 31); - amd_iommu_pc_get_set_reg_val(devid, - _GET_BANK(ev), _GET_CNTR(ev) , - IOMMU_PC_PASID_MATCH_REG, ®, true); + reg |= BIT(31); + amd_iommu_pc_set_reg(iommu, bank, cntr, IOMMU_PC_PASID_MATCH_REG, ®); - reg = 0ULL | _GET_DOMID(ev) | (_GET_DOMID_MASK(ev) << 32); + reg = GET_DOMID_MASK(hwc); + reg = GET_DOMID(hwc) | (reg << 32); if (reg) - reg |= (1UL << 31); - amd_iommu_pc_get_set_reg_val(devid, - _GET_BANK(ev), _GET_CNTR(ev) , - IOMMU_PC_DOMID_MATCH_REG, ®, true); + reg |= BIT(31); + amd_iommu_pc_set_reg(iommu, bank, cntr, IOMMU_PC_DOMID_MATCH_REG, ®); } static void perf_iommu_disable_event(struct perf_event *event) { + struct amd_iommu *iommu = perf_event_2_iommu(event); + struct hw_perf_event *hwc = &event->hw; u64 reg = 0ULL; - amd_iommu_pc_get_set_reg_val(_GET_DEVID(event), - _GET_BANK(event), _GET_CNTR(event), - IOMMU_PC_COUNTER_SRC_REG, ®, true); + amd_iommu_pc_set_reg(iommu, hwc->iommu_bank, hwc->iommu_cntr, + IOMMU_PC_COUNTER_SRC_REG, ®); } static void perf_iommu_start(struct perf_event *event, int flags) { struct hw_perf_event *hwc = &event->hw; - pr_debug("perf: amd_iommu:perf_iommu_start\n"); if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) return; @@ -306,10 +294,11 @@ static void perf_iommu_start(struct perf_event *event, int flags) hwc->state = 0; if (flags & PERF_EF_RELOAD) { - u64 prev_raw_count = local64_read(&hwc->prev_count); - amd_iommu_pc_get_set_reg_val(_GET_DEVID(event), - _GET_BANK(event), _GET_CNTR(event), - IOMMU_PC_COUNTER_REG, &prev_raw_count, true); + u64 prev_raw_count = local64_read(&hwc->prev_count); + struct amd_iommu *iommu = perf_event_2_iommu(event); + + amd_iommu_pc_set_reg(iommu, hwc->iommu_bank, hwc->iommu_cntr, + IOMMU_PC_COUNTER_REG, &prev_raw_count); } perf_iommu_enable_event(event); @@ -319,37 +308,30 @@ static void perf_iommu_start(struct perf_event *event, int flags) static void perf_iommu_read(struct perf_event *event) { - u64 count = 0ULL; - u64 prev_raw_count = 0ULL; - u64 delta = 0ULL; + u64 count, prev, delta; struct hw_perf_event *hwc = &event->hw; - pr_debug("perf: amd_iommu:perf_iommu_read\n"); + struct amd_iommu *iommu = perf_event_2_iommu(event); - amd_iommu_pc_get_set_reg_val(_GET_DEVID(event), - _GET_BANK(event), _GET_CNTR(event), - IOMMU_PC_COUNTER_REG, &count, false); + if (amd_iommu_pc_get_reg(iommu, hwc->iommu_bank, hwc->iommu_cntr, + IOMMU_PC_COUNTER_REG, &count)) + return; /* IOMMU pc counter register is only 48 bits */ - count &= 0xFFFFFFFFFFFFULL; + count &= GENMASK_ULL(47, 0); - prev_raw_count = local64_read(&hwc->prev_count); - if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, - count) != prev_raw_count) + prev = local64_read(&hwc->prev_count); + if (local64_cmpxchg(&hwc->prev_count, prev, count) != prev) return; - /* Handling 48-bit counter overflowing */ - delta = (count << COUNTER_SHIFT) - (prev_raw_count << COUNTER_SHIFT); + /* Handle 48-bit counter overflow */ + delta = (count << COUNTER_SHIFT) - (prev << COUNTER_SHIFT); delta >>= COUNTER_SHIFT; local64_add(delta, &event->count); - } static void perf_iommu_stop(struct perf_event *event, int flags) { struct hw_perf_event *hwc = &event->hw; - u64 config; - - pr_debug("perf: amd_iommu:perf_iommu_stop\n"); if (hwc->state & PERF_HES_UPTODATE) return; @@ -361,7 +343,6 @@ static void perf_iommu_stop(struct perf_event *event, int flags) if (hwc->state & PERF_HES_UPTODATE) return; - config = hwc->config; perf_iommu_read(event); hwc->state |= PERF_HES_UPTODATE; } @@ -369,17 +350,12 @@ static void perf_iommu_stop(struct perf_event *event, int flags) static int perf_iommu_add(struct perf_event *event, int flags) { int retval; - struct perf_amd_iommu *perf_iommu = - container_of(event->pmu, struct perf_amd_iommu, pmu); - pr_debug("perf: amd_iommu:perf_iommu_add\n"); event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; /* request an iommu bank/counter */ - retval = get_next_avail_iommu_bnk_cntr(perf_iommu); - if (retval != -ENOSPC) - event->hw.extra_reg.reg = (u16)retval; - else + retval = get_next_avail_iommu_bnk_cntr(event); + if (retval) return retval; if (flags & PERF_EF_START) @@ -390,115 +366,124 @@ static int perf_iommu_add(struct perf_event *event, int flags) static void perf_iommu_del(struct perf_event *event, int flags) { + struct hw_perf_event *hwc = &event->hw; struct perf_amd_iommu *perf_iommu = container_of(event->pmu, struct perf_amd_iommu, pmu); - pr_debug("perf: amd_iommu:perf_iommu_del\n"); perf_iommu_stop(event, PERF_EF_UPDATE); /* clear the assigned iommu bank/counter */ clear_avail_iommu_bnk_cntr(perf_iommu, - _GET_BANK(event), - _GET_CNTR(event)); + hwc->iommu_bank, hwc->iommu_cntr); perf_event_update_userpage(event); } -static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu) +static __init int _init_events_attrs(void) { - struct attribute **attrs; - struct attribute_group *attr_group; int i = 0, j; + struct attribute **attrs; while (amd_iommu_v2_event_descs[i].attr.attr.name) i++; - attr_group = kzalloc(sizeof(struct attribute *) - * (i + 1) + sizeof(*attr_group), GFP_KERNEL); - if (!attr_group) + attrs = kzalloc(sizeof(struct attribute **) * (i + 1), GFP_KERNEL); + if (!attrs) return -ENOMEM; - attrs = (struct attribute **)(attr_group + 1); for (j = 0; j < i; j++) attrs[j] = &amd_iommu_v2_event_descs[j].attr.attr; - attr_group->name = "events"; - attr_group->attrs = attrs; - perf_iommu->events_group = attr_group; - + amd_iommu_events_group.attrs = attrs; return 0; } -static __init void amd_iommu_pc_exit(void) -{ - if (__perf_iommu.events_group != NULL) { - kfree(__perf_iommu.events_group); - __perf_iommu.events_group = NULL; - } -} +const struct attribute_group *amd_iommu_attr_groups[] = { + &amd_iommu_format_group, + &amd_iommu_cpumask_group, + &amd_iommu_events_group, + NULL, +}; + +static struct pmu iommu_pmu = { + .event_init = perf_iommu_event_init, + .add = perf_iommu_add, + .del = perf_iommu_del, + .start = perf_iommu_start, + .stop = perf_iommu_stop, + .read = perf_iommu_read, + .task_ctx_nr = perf_invalid_context, + .attr_groups = amd_iommu_attr_groups, +}; -static __init int _init_perf_amd_iommu( - struct perf_amd_iommu *perf_iommu, char *name) +static __init int init_one_iommu(unsigned int idx) { + struct perf_amd_iommu *perf_iommu; int ret; + perf_iommu = kzalloc(sizeof(struct perf_amd_iommu), GFP_KERNEL); + if (!perf_iommu) + return -ENOMEM; + raw_spin_lock_init(&perf_iommu->lock); - /* Init format attributes */ - perf_iommu->format_group = &amd_iommu_format_group; + perf_iommu->pmu = iommu_pmu; + perf_iommu->iommu = get_amd_iommu(idx); + perf_iommu->max_banks = amd_iommu_pc_get_max_banks(idx); + perf_iommu->max_counters = amd_iommu_pc_get_max_counters(idx); - /* Init cpumask attributes to only core 0 */ - cpumask_set_cpu(0, &iommu_cpumask); - perf_iommu->cpumask_group = &amd_iommu_cpumask_group; - - /* Init events attributes */ - if (_init_events_attrs(perf_iommu) != 0) - pr_err("perf: amd_iommu: Only support raw events.\n"); + if (!perf_iommu->iommu || + !perf_iommu->max_banks || + !perf_iommu->max_counters) { + kfree(perf_iommu); + return -EINVAL; + } - /* Init null attributes */ - perf_iommu->null_group = NULL; - perf_iommu->pmu.attr_groups = perf_iommu->attr_groups; + snprintf(perf_iommu->name, IOMMU_NAME_SIZE, "amd_iommu_%u", idx); - ret = perf_pmu_register(&perf_iommu->pmu, name, -1); - if (ret) { - pr_err("perf: amd_iommu: Failed to initialized.\n"); - amd_iommu_pc_exit(); + ret = perf_pmu_register(&perf_iommu->pmu, perf_iommu->name, -1); + if (!ret) { + pr_info("Detected AMD IOMMU #%d (%d banks, %d counters/bank).\n", + idx, perf_iommu->max_banks, perf_iommu->max_counters); + list_add_tail(&perf_iommu->list, &perf_amd_iommu_list); } else { - pr_info("perf: amd_iommu: Detected. (%d banks, %d counters/bank)\n", - amd_iommu_pc_get_max_banks(IOMMU_BASE_DEVID), - amd_iommu_pc_get_max_counters(IOMMU_BASE_DEVID)); + pr_warn("Error initializing IOMMU %d.\n", idx); + kfree(perf_iommu); } - return ret; } -static struct perf_amd_iommu __perf_iommu = { - .pmu = { - .task_ctx_nr = perf_invalid_context, - .event_init = perf_iommu_event_init, - .add = perf_iommu_add, - .del = perf_iommu_del, - .start = perf_iommu_start, - .stop = perf_iommu_stop, - .read = perf_iommu_read, - }, - .max_banks = 0x00, - .max_counters = 0x00, - .cntr_assign_mask = 0ULL, - .format_group = NULL, - .cpumask_group = NULL, - .events_group = NULL, - .null_group = NULL, -}; - static __init int amd_iommu_pc_init(void) { + unsigned int i, cnt = 0; + int ret; + /* Make sure the IOMMU PC resource is available */ if (!amd_iommu_pc_supported()) return -ENODEV; - _init_perf_amd_iommu(&__perf_iommu, "amd_iommu"); + ret = _init_events_attrs(); + if (ret) + return ret; + + /* + * An IOMMU PMU is specific to an IOMMU, and can function independently. + * So we go through all IOMMUs and ignore the one that fails init + * unless all IOMMU are failing. + */ + for (i = 0; i < amd_iommu_get_num_iommus(); i++) { + ret = init_one_iommu(i); + if (!ret) + cnt++; + } + + if (!cnt) { + kfree(amd_iommu_events_group.attrs); + return -ENODEV; + } + /* Init cpumask attributes to only core 0 */ + cpumask_set_cpu(0, &iommu_cpumask); return 0; } diff --git a/arch/x86/events/amd/iommu.h b/arch/x86/events/amd/iommu.h index 845d173278e3..62e0702c4374 100644 --- a/arch/x86/events/amd/iommu.h +++ b/arch/x86/events/amd/iommu.h @@ -24,17 +24,23 @@ #define PC_MAX_SPEC_BNKS 64 #define PC_MAX_SPEC_CNTRS 16 -/* iommu pc reg masks*/ -#define IOMMU_BASE_DEVID 0x0000 +struct amd_iommu; /* amd_iommu_init.c external support functions */ +extern int amd_iommu_get_num_iommus(void); + extern bool amd_iommu_pc_supported(void); -extern u8 amd_iommu_pc_get_max_banks(u16 devid); +extern u8 amd_iommu_pc_get_max_banks(unsigned int idx); + +extern u8 amd_iommu_pc_get_max_counters(unsigned int idx); + +extern int amd_iommu_pc_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, + u8 fxn, u64 *value); -extern u8 amd_iommu_pc_get_max_counters(u16 devid); +extern int amd_iommu_pc_get_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, + u8 fxn, u64 *value); -extern int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, - u8 fxn, u64 *value, bool is_write); +extern struct amd_iommu *get_amd_iommu(int idx); #endif /*_PERF_EVENT_AMD_IOMMU_H_*/ diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c index 4d1f7f2d9aff..ad44af0dd667 100644 --- a/arch/x86/events/amd/uncore.c +++ b/arch/x86/events/amd/uncore.c @@ -30,6 +30,9 @@ #define COUNTER_SHIFT 16 +#undef pr_fmt +#define pr_fmt(fmt) "amd_uncore: " fmt + static int num_counters_llc; static int num_counters_nb; @@ -509,51 +512,34 @@ static int __init amd_uncore_init(void) int ret = -ENODEV; if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) - goto fail_nodev; - - switch(boot_cpu_data.x86) { - case 23: - /* Family 17h: */ - num_counters_nb = NUM_COUNTERS_NB; - num_counters_llc = NUM_COUNTERS_L3; - /* - * For Family17h, the NorthBridge counters are - * re-purposed as Data Fabric counters. Also, support is - * added for L3 counters. The pmus are exported based on - * family as either L2 or L3 and NB or DF. - */ - amd_nb_pmu.name = "amd_df"; - amd_llc_pmu.name = "amd_l3"; - format_attr_event_df.show = &event_show_df; - format_attr_event_l3.show = &event_show_l3; - break; - case 22: - /* Family 16h - may change: */ - num_counters_nb = NUM_COUNTERS_NB; - num_counters_llc = NUM_COUNTERS_L2; - amd_nb_pmu.name = "amd_nb"; - amd_llc_pmu.name = "amd_l2"; - format_attr_event_df = format_attr_event; - format_attr_event_l3 = format_attr_event; - break; - default: - /* - * All prior families have the same number of - * NorthBridge and Last Level Cache counters - */ - num_counters_nb = NUM_COUNTERS_NB; - num_counters_llc = NUM_COUNTERS_L2; - amd_nb_pmu.name = "amd_nb"; - amd_llc_pmu.name = "amd_l2"; - format_attr_event_df = format_attr_event; - format_attr_event_l3 = format_attr_event; - break; - } - amd_nb_pmu.attr_groups = amd_uncore_attr_groups_df; - amd_llc_pmu.attr_groups = amd_uncore_attr_groups_l3; + return -ENODEV; if (!boot_cpu_has(X86_FEATURE_TOPOEXT)) - goto fail_nodev; + return -ENODEV; + + if (boot_cpu_data.x86 == 0x17) { + /* + * For F17h, the Northbridge counters are repurposed as Data + * Fabric counters. Also, L3 counters are supported too. The PMUs + * are exported based on family as either L2 or L3 and NB or DF. + */ + num_counters_nb = NUM_COUNTERS_NB; + num_counters_llc = NUM_COUNTERS_L3; + amd_nb_pmu.name = "amd_df"; + amd_llc_pmu.name = "amd_l3"; + format_attr_event_df.show = &event_show_df; + format_attr_event_l3.show = &event_show_l3; + } else { + num_counters_nb = NUM_COUNTERS_NB; + num_counters_llc = NUM_COUNTERS_L2; + amd_nb_pmu.name = "amd_nb"; + amd_llc_pmu.name = "amd_l2"; + format_attr_event_df = format_attr_event; + format_attr_event_l3 = format_attr_event; + } + + amd_nb_pmu.attr_groups = amd_uncore_attr_groups_df; + amd_llc_pmu.attr_groups = amd_uncore_attr_groups_l3; if (boot_cpu_has(X86_FEATURE_PERFCTR_NB)) { amd_uncore_nb = alloc_percpu(struct amd_uncore *); @@ -565,7 +551,7 @@ static int __init amd_uncore_init(void) if (ret) goto fail_nb; - pr_info("perf: AMD NB counters detected\n"); + pr_info("AMD NB counters detected\n"); ret = 0; } @@ -579,7 +565,7 @@ static int __init amd_uncore_init(void) if (ret) goto fail_llc; - pr_info("perf: AMD LLC counters detected\n"); + pr_info("AMD LLC counters detected\n"); ret = 0; } @@ -615,7 +601,6 @@ fail_nb: if (amd_uncore_nb) free_percpu(amd_uncore_nb); -fail_nodev: return ret; } device_initcall(amd_uncore_init); diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 2aa1ad194db2..580b60f5ac83 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -2256,6 +2256,7 @@ void arch_perf_update_userpage(struct perf_event *event, struct perf_event_mmap_page *userpg, u64 now) { struct cyc2ns_data *data; + u64 offset; userpg->cap_user_time = 0; userpg->cap_user_time_zero = 0; @@ -2263,11 +2264,13 @@ void arch_perf_update_userpage(struct perf_event *event, !!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED); userpg->pmc_width = x86_pmu.cntval_bits; - if (!sched_clock_stable()) + if (!using_native_sched_clock() || !sched_clock_stable()) return; data = cyc2ns_read_begin(); + offset = data->cyc2ns_offset + __sched_clock_offset; + /* * Internal timekeeping for enabled/running/stopped times * is always in the local_clock domain. @@ -2275,7 +2278,7 @@ void arch_perf_update_userpage(struct perf_event *event, userpg->cap_user_time = 1; userpg->time_mult = data->cyc2ns_mul; userpg->time_shift = data->cyc2ns_shift; - userpg->time_offset = data->cyc2ns_offset - now; + userpg->time_offset = offset - now; /* * cap_user_time_zero doesn't make sense when we're using a different @@ -2283,7 +2286,7 @@ void arch_perf_update_userpage(struct perf_event *event, */ if (!event->attr.use_clockid) { userpg->cap_user_time_zero = 1; - userpg->time_zero = data->cyc2ns_offset; + userpg->time_zero = offset; } cyc2ns_read_end(data); diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c index 982c9e31daca..8ae8c5ce3a1f 100644 --- a/arch/x86/events/intel/bts.c +++ b/arch/x86/events/intel/bts.c @@ -63,7 +63,6 @@ struct bts_buffer { unsigned int cur_buf; bool snapshot; local_t data_size; - local_t lost; local_t head; unsigned long end; void **data_pages; @@ -199,7 +198,8 @@ static void bts_update(struct bts_ctx *bts) return; if (ds->bts_index >= ds->bts_absolute_maximum) - local_inc(&buf->lost); + perf_aux_output_flag(&bts->handle, + PERF_AUX_FLAG_TRUNCATED); /* * old and head are always in the same physical buffer, so we @@ -276,7 +276,7 @@ static void bts_event_start(struct perf_event *event, int flags) return; fail_end_stop: - perf_aux_output_end(&bts->handle, 0, false); + perf_aux_output_end(&bts->handle, 0); fail_stop: event->hw.state = PERF_HES_STOPPED; @@ -319,9 +319,8 @@ static void bts_event_stop(struct perf_event *event, int flags) bts->handle.head = local_xchg(&buf->data_size, buf->nr_pages << PAGE_SHIFT); - - perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0), - !!local_xchg(&buf->lost, 0)); + perf_aux_output_end(&bts->handle, + local_xchg(&buf->data_size, 0)); } cpuc->ds->bts_index = bts->ds_back.bts_buffer_base; @@ -484,8 +483,7 @@ int intel_bts_interrupt(void) if (old_head == local_read(&buf->head)) return handled; - perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0), - !!local_xchg(&buf->lost, 0)); + perf_aux_output_end(&bts->handle, local_xchg(&buf->data_size, 0)); buf = perf_aux_output_begin(&bts->handle, event); if (buf) @@ -500,7 +498,7 @@ int intel_bts_interrupt(void) * cleared handle::event */ barrier(); - perf_aux_output_end(&bts->handle, 0, false); + perf_aux_output_end(&bts->handle, 0); } } diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index eb1484c86bb4..a6d91d4e37a1 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -1553,6 +1553,27 @@ static __initconst const u64 slm_hw_cache_event_ids }, }; +EVENT_ATTR_STR(topdown-total-slots, td_total_slots_glm, "event=0x3c"); +EVENT_ATTR_STR(topdown-total-slots.scale, td_total_slots_scale_glm, "3"); +/* UOPS_NOT_DELIVERED.ANY */ +EVENT_ATTR_STR(topdown-fetch-bubbles, td_fetch_bubbles_glm, "event=0x9c"); +/* ISSUE_SLOTS_NOT_CONSUMED.RECOVERY */ +EVENT_ATTR_STR(topdown-recovery-bubbles, td_recovery_bubbles_glm, "event=0xca,umask=0x02"); +/* UOPS_RETIRED.ANY */ +EVENT_ATTR_STR(topdown-slots-retired, td_slots_retired_glm, "event=0xc2"); +/* UOPS_ISSUED.ANY */ +EVENT_ATTR_STR(topdown-slots-issued, td_slots_issued_glm, "event=0x0e"); + +static struct attribute *glm_events_attrs[] = { + EVENT_PTR(td_total_slots_glm), + EVENT_PTR(td_total_slots_scale_glm), + EVENT_PTR(td_fetch_bubbles_glm), + EVENT_PTR(td_recovery_bubbles_glm), + EVENT_PTR(td_slots_issued_glm), + EVENT_PTR(td_slots_retired_glm), + NULL +}; + static struct extra_reg intel_glm_extra_regs[] __read_mostly = { /* must define OFFCORE_RSP_X first, see intel_fixup_er() */ INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x760005ffbfull, RSP_0), @@ -2130,7 +2151,7 @@ again: * counters from the GLOBAL_STATUS mask and we always process PEBS * events via drain_pebs(). */ - status &= ~cpuc->pebs_enabled; + status &= ~(cpuc->pebs_enabled & PEBS_COUNTER_MASK); /* * PEBS overflow sets bit 62 in the global status register @@ -3750,6 +3771,7 @@ __init int intel_pmu_init(void) x86_pmu.pebs_prec_dist = true; x86_pmu.lbr_pt_coexist = true; x86_pmu.flags |= PMU_FL_HAS_RSP_1; + x86_pmu.cpu_events = glm_events_attrs; pr_cont("Goldmont events, "); break; diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 9dfeeeca0ea8..c6d23ffe422d 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -1222,7 +1222,7 @@ get_next_pebs_record_by_bit(void *base, void *top, int bit) /* clear non-PEBS bit and re-check */ pebs_status = p->status & cpuc->pebs_enabled; - pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1; + pebs_status &= PEBS_COUNTER_MASK; if (pebs_status == (1 << bit)) return at; } diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index 81b321ace8e0..f924629836a8 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -507,6 +507,9 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) cpuc->lbr_entries[i].to = msr_lastbranch.to; cpuc->lbr_entries[i].mispred = 0; cpuc->lbr_entries[i].predicted = 0; + cpuc->lbr_entries[i].in_tx = 0; + cpuc->lbr_entries[i].abort = 0; + cpuc->lbr_entries[i].cycles = 0; cpuc->lbr_entries[i].reserved = 0; } cpuc->lbr_stack.nr = i; diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 5900471ee508..ae8324d65e61 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -28,6 +28,7 @@ #include <asm/insn.h> #include <asm/io.h> #include <asm/intel_pt.h> +#include <asm/intel-family.h> #include "../perf_event.h" #include "pt.h" @@ -98,6 +99,7 @@ static struct attribute_group pt_cap_group = { .name = "caps", }; +PMU_FORMAT_ATTR(pt, "config:0" ); PMU_FORMAT_ATTR(cyc, "config:1" ); PMU_FORMAT_ATTR(pwr_evt, "config:4" ); PMU_FORMAT_ATTR(fup_on_ptw, "config:5" ); @@ -105,11 +107,13 @@ PMU_FORMAT_ATTR(mtc, "config:9" ); PMU_FORMAT_ATTR(tsc, "config:10" ); PMU_FORMAT_ATTR(noretcomp, "config:11" ); PMU_FORMAT_ATTR(ptw, "config:12" ); +PMU_FORMAT_ATTR(branch, "config:13" ); PMU_FORMAT_ATTR(mtc_period, "config:14-17" ); PMU_FORMAT_ATTR(cyc_thresh, "config:19-22" ); PMU_FORMAT_ATTR(psb_period, "config:24-27" ); static struct attribute *pt_formats_attr[] = { + &format_attr_pt.attr, &format_attr_cyc.attr, &format_attr_pwr_evt.attr, &format_attr_fup_on_ptw.attr, @@ -117,6 +121,7 @@ static struct attribute *pt_formats_attr[] = { &format_attr_tsc.attr, &format_attr_noretcomp.attr, &format_attr_ptw.attr, + &format_attr_branch.attr, &format_attr_mtc_period.attr, &format_attr_cyc_thresh.attr, &format_attr_psb_period.attr, @@ -197,6 +202,19 @@ static int __init pt_pmu_hw_init(void) pt_pmu.tsc_art_den = eax; } + /* model-specific quirks */ + switch (boot_cpu_data.x86_model) { + case INTEL_FAM6_BROADWELL_CORE: + case INTEL_FAM6_BROADWELL_XEON_D: + case INTEL_FAM6_BROADWELL_GT3E: + case INTEL_FAM6_BROADWELL_X: + /* not setting BRANCH_EN will #GP, erratum BDM106 */ + pt_pmu.branch_en_always_on = true; + break; + default: + break; + } + if (boot_cpu_has(X86_FEATURE_VMX)) { /* * Intel SDM, 36.5 "Tracing post-VMXON" says that @@ -263,8 +281,20 @@ fail: #define RTIT_CTL_PTW (RTIT_CTL_PTW_EN | \ RTIT_CTL_FUP_ON_PTW) -#define PT_CONFIG_MASK (RTIT_CTL_TSC_EN | \ +/* + * Bit 0 (TraceEn) in the attr.config is meaningless as the + * corresponding bit in the RTIT_CTL can only be controlled + * by the driver; therefore, repurpose it to mean: pass + * through the bit that was previously assumed to be always + * on for PT, thereby allowing the user to *not* set it if + * they so wish. See also pt_event_valid() and pt_config(). + */ +#define RTIT_CTL_PASSTHROUGH RTIT_CTL_TRACEEN + +#define PT_CONFIG_MASK (RTIT_CTL_TRACEEN | \ + RTIT_CTL_TSC_EN | \ RTIT_CTL_DISRETC | \ + RTIT_CTL_BRANCH_EN | \ RTIT_CTL_CYC_PSB | \ RTIT_CTL_MTC | \ RTIT_CTL_PWR_EVT_EN | \ @@ -332,6 +362,33 @@ static bool pt_event_valid(struct perf_event *event) return false; } + /* + * Setting bit 0 (TraceEn in RTIT_CTL MSR) in the attr.config + * clears the assomption that BranchEn must always be enabled, + * as was the case with the first implementation of PT. + * If this bit is not set, the legacy behavior is preserved + * for compatibility with the older userspace. + * + * Re-using bit 0 for this purpose is fine because it is never + * directly set by the user; previous attempts at setting it in + * the attr.config resulted in -EINVAL. + */ + if (config & RTIT_CTL_PASSTHROUGH) { + /* + * Disallow not setting BRANCH_EN where BRANCH_EN is + * always required. + */ + if (pt_pmu.branch_en_always_on && + !(config & RTIT_CTL_BRANCH_EN)) + return false; + } else { + /* + * Disallow BRANCH_EN without the PASSTHROUGH. + */ + if (config & RTIT_CTL_BRANCH_EN) + return false; + } + return true; } @@ -411,6 +468,7 @@ static u64 pt_config_filters(struct perf_event *event) static void pt_config(struct perf_event *event) { + struct pt *pt = this_cpu_ptr(&pt_ctx); u64 reg; if (!event->hw.itrace_started) { @@ -419,7 +477,20 @@ static void pt_config(struct perf_event *event) } reg = pt_config_filters(event); - reg |= RTIT_CTL_TOPA | RTIT_CTL_BRANCH_EN | RTIT_CTL_TRACEEN; + reg |= RTIT_CTL_TOPA | RTIT_CTL_TRACEEN; + + /* + * Previously, we had BRANCH_EN on by default, but now that PT has + * grown features outside of branch tracing, it is useful to allow + * the user to disable it. Setting bit 0 in the event's attr.config + * allows BRANCH_EN to pass through instead of being always on. See + * also the comment in pt_event_valid(). + */ + if (event->attr.config & BIT(0)) { + reg |= event->attr.config & RTIT_CTL_BRANCH_EN; + } else { + reg |= RTIT_CTL_BRANCH_EN; + } if (!event->attr.exclude_kernel) reg |= RTIT_CTL_OS; @@ -429,11 +500,15 @@ static void pt_config(struct perf_event *event) reg |= (event->attr.config & PT_CONFIG_MASK); event->hw.config = reg; - wrmsrl(MSR_IA32_RTIT_CTL, reg); + if (READ_ONCE(pt->vmx_on)) + perf_aux_output_flag(&pt->handle, PERF_AUX_FLAG_PARTIAL); + else + wrmsrl(MSR_IA32_RTIT_CTL, reg); } static void pt_config_stop(struct perf_event *event) { + struct pt *pt = this_cpu_ptr(&pt_ctx); u64 ctl = READ_ONCE(event->hw.config); /* may be already stopped by a PMI */ @@ -441,7 +516,8 @@ static void pt_config_stop(struct perf_event *event) return; ctl &= ~RTIT_CTL_TRACEEN; - wrmsrl(MSR_IA32_RTIT_CTL, ctl); + if (!READ_ONCE(pt->vmx_on)) + wrmsrl(MSR_IA32_RTIT_CTL, ctl); WRITE_ONCE(event->hw.config, ctl); @@ -753,7 +829,8 @@ static void pt_handle_status(struct pt *pt) */ if (!pt_cap_get(PT_CAP_topa_multiple_entries) || buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) { - local_inc(&buf->lost); + perf_aux_output_flag(&pt->handle, + PERF_AUX_FLAG_TRUNCATED); advance++; } } @@ -846,8 +923,10 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf, /* can't stop in the middle of an output region */ if (buf->output_off + handle->size + 1 < - sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) + sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) { + perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); return -EINVAL; + } /* single entry ToPA is handled by marking all regions STOP=1 INT=1 */ @@ -1171,12 +1250,6 @@ void intel_pt_interrupt(void) if (!READ_ONCE(pt->handle_nmi)) return; - /* - * If VMX is on and PT does not support it, don't touch anything. - */ - if (READ_ONCE(pt->vmx_on)) - return; - if (!event) return; @@ -1192,8 +1265,7 @@ void intel_pt_interrupt(void) pt_update_head(pt); - perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0), - local_xchg(&buf->lost, 0)); + perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0)); if (!event->hw.state) { int ret; @@ -1208,7 +1280,7 @@ void intel_pt_interrupt(void) /* snapshot counters don't use PMI, so it's safe */ ret = pt_buffer_reset_markers(buf, &pt->handle); if (ret) { - perf_aux_output_end(&pt->handle, 0, true); + perf_aux_output_end(&pt->handle, 0); return; } @@ -1237,12 +1309,19 @@ void intel_pt_handle_vmx(int on) local_irq_save(flags); WRITE_ONCE(pt->vmx_on, on); - if (on) { - /* prevent pt_config_stop() from writing RTIT_CTL */ - event = pt->handle.event; - if (event) - event->hw.config = 0; - } + /* + * If an AUX transaction is in progress, it will contain + * gap(s), so flag it PARTIAL to inform the user. + */ + event = pt->handle.event; + if (event) + perf_aux_output_flag(&pt->handle, + PERF_AUX_FLAG_PARTIAL); + + /* Turn PTs back on */ + if (!on && event) + wrmsrl(MSR_IA32_RTIT_CTL, event->hw.config); + local_irq_restore(flags); } EXPORT_SYMBOL_GPL(intel_pt_handle_vmx); @@ -1257,9 +1336,6 @@ static void pt_event_start(struct perf_event *event, int mode) struct pt *pt = this_cpu_ptr(&pt_ctx); struct pt_buffer *buf; - if (READ_ONCE(pt->vmx_on)) - return; - buf = perf_aux_output_begin(&pt->handle, event); if (!buf) goto fail_stop; @@ -1280,7 +1356,7 @@ static void pt_event_start(struct perf_event *event, int mode) return; fail_end_stop: - perf_aux_output_end(&pt->handle, 0, true); + perf_aux_output_end(&pt->handle, 0); fail_stop: hwc->state = PERF_HES_STOPPED; } @@ -1321,8 +1397,7 @@ static void pt_event_stop(struct perf_event *event, int mode) pt->handle.head = local_xchg(&buf->data_size, buf->nr_pages << PAGE_SHIFT); - perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0), - local_xchg(&buf->lost, 0)); + perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0)); } } diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h index 53473c21b554..0eb41d07b79a 100644 --- a/arch/x86/events/intel/pt.h +++ b/arch/x86/events/intel/pt.h @@ -110,6 +110,7 @@ struct pt_pmu { struct pmu pmu; u32 caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES]; bool vmx; + bool branch_en_always_on; unsigned long max_nonturbo_ratio; unsigned int tsc_art_num; unsigned int tsc_art_den; @@ -143,7 +144,6 @@ struct pt_buffer { size_t output_off; unsigned long nr_pages; local_t data_size; - local_t lost; local64_t head; bool snapshot; unsigned long stop_pos, intr_pos; diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index bcbb1d2ae10b..be3d36254040 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -79,6 +79,7 @@ struct amd_nb { /* The maximal number of PEBS events: */ #define MAX_PEBS_EVENTS 8 +#define PEBS_COUNTER_MASK ((1ULL << MAX_PEBS_EVENTS) - 1) /* * Flags PEBS can handle without an PMI. diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 395b69551fce..2efc768e4362 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -52,6 +52,8 @@ extern u8 acpi_sci_flags; extern int acpi_sci_override_gsi; void acpi_pic_sci_set_trigger(unsigned int, u16); +struct device; + extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity); extern void (*__acpi_unregister_gsi)(u32 gsi); diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 730ef65e8393..bdffcd9eab2b 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -252,12 +252,6 @@ static inline int x2apic_enabled(void) { return 0; } #define x2apic_supported() (0) #endif /* !CONFIG_X86_X2APIC */ -#ifdef CONFIG_X86_64 -#define SET_APIC_ID(x) (apic->set_apic_id(x)) -#else - -#endif - /* * Copyright 2004 James Cleverdon, IBM. * Subject to the GNU Public License, v.2 @@ -299,6 +293,7 @@ struct apic { int (*phys_pkg_id)(int cpuid_apic, int index_msb); unsigned int (*get_apic_id)(unsigned long x); + /* Can't be NULL on 64-bit */ unsigned long (*set_apic_id)(unsigned int id); int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask, diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index 14635c5ea025..caa5798c92f4 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -186,6 +186,12 @@ static __always_inline int atomic_cmpxchg(atomic_t *v, int old, int new) return cmpxchg(&v->counter, old, new); } +#define atomic_try_cmpxchg atomic_try_cmpxchg +static __always_inline bool atomic_try_cmpxchg(atomic_t *v, int *old, int new) +{ + return try_cmpxchg(&v->counter, old, new); +} + static inline int atomic_xchg(atomic_t *v, int new) { return xchg(&v->counter, new); @@ -201,16 +207,12 @@ static inline void atomic_##op(int i, atomic_t *v) \ } #define ATOMIC_FETCH_OP(op, c_op) \ -static inline int atomic_fetch_##op(int i, atomic_t *v) \ +static inline int atomic_fetch_##op(int i, atomic_t *v) \ { \ - int old, val = atomic_read(v); \ - for (;;) { \ - old = atomic_cmpxchg(v, val, val c_op i); \ - if (old == val) \ - break; \ - val = old; \ - } \ - return old; \ + int val = atomic_read(v); \ + do { \ + } while (!atomic_try_cmpxchg(v, &val, val c_op i)); \ + return val; \ } #define ATOMIC_OPS(op, c_op) \ @@ -236,16 +238,11 @@ ATOMIC_OPS(xor, ^) */ static __always_inline int __atomic_add_unless(atomic_t *v, int a, int u) { - int c, old; - c = atomic_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = atomic_cmpxchg((v), c, c + (a)); - if (likely(old == c)) + int c = atomic_read(v); + do { + if (unlikely(c == u)) break; - c = old; - } + } while (!atomic_try_cmpxchg(v, &c, c + a)); return c; } diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h index 89ed2f6ae2f7..6189a433c9a9 100644 --- a/arch/x86/include/asm/atomic64_64.h +++ b/arch/x86/include/asm/atomic64_64.h @@ -176,6 +176,12 @@ static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new) return cmpxchg(&v->counter, old, new); } +#define atomic64_try_cmpxchg atomic64_try_cmpxchg +static __always_inline bool atomic64_try_cmpxchg(atomic64_t *v, long *old, long new) +{ + return try_cmpxchg(&v->counter, old, new); +} + static inline long atomic64_xchg(atomic64_t *v, long new) { return xchg(&v->counter, new); @@ -192,17 +198,12 @@ static inline long atomic64_xchg(atomic64_t *v, long new) */ static inline bool atomic64_add_unless(atomic64_t *v, long a, long u) { - long c, old; - c = atomic64_read(v); - for (;;) { - if (unlikely(c == (u))) - break; - old = atomic64_cmpxchg((v), c, c + (a)); - if (likely(old == c)) - break; - c = old; - } - return c != (u); + long c = atomic64_read(v); + do { + if (unlikely(c == u)) + return false; + } while (!atomic64_try_cmpxchg(v, &c, c + a)); + return true; } #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) @@ -216,17 +217,12 @@ static inline bool atomic64_add_unless(atomic64_t *v, long a, long u) */ static inline long atomic64_dec_if_positive(atomic64_t *v) { - long c, old, dec; - c = atomic64_read(v); - for (;;) { + long dec, c = atomic64_read(v); + do { dec = c - 1; if (unlikely(dec < 0)) break; - old = atomic64_cmpxchg((v), c, dec); - if (likely(old == c)) - break; - c = old; - } + } while (!atomic64_try_cmpxchg(v, &c, dec)); return dec; } @@ -242,14 +238,10 @@ static inline void atomic64_##op(long i, atomic64_t *v) \ #define ATOMIC64_FETCH_OP(op, c_op) \ static inline long atomic64_fetch_##op(long i, atomic64_t *v) \ { \ - long old, val = atomic64_read(v); \ - for (;;) { \ - old = atomic64_cmpxchg(v, val, val c_op i); \ - if (old == val) \ - break; \ - val = old; \ - } \ - return old; \ + long val = atomic64_read(v); \ + do { \ + } while (!atomic64_try_cmpxchg(v, &val, val c_op i)); \ + return val; \ } #define ATOMIC64_OPS(op, c_op) \ diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h index ba38ebbaced3..39e702d90cdb 100644 --- a/arch/x86/include/asm/bug.h +++ b/arch/x86/include/asm/bug.h @@ -1,36 +1,82 @@ #ifndef _ASM_X86_BUG_H #define _ASM_X86_BUG_H -#define HAVE_ARCH_BUG +#include <linux/stringify.h> -#ifdef CONFIG_DEBUG_BUGVERBOSE +/* + * Since some emulators terminate on UD2, we cannot use it for WARN. + * Since various instruction decoders disagree on the length of UD1, + * we cannot use it either. So use UD0 for WARN. + * + * (binutils knows about "ud1" but {en,de}codes it as 2 bytes, whereas + * our kernel decoder thinks it takes a ModRM byte, which seems consistent + * with various things like the Intel SDM instruction encoding rules) + */ + +#define ASM_UD0 ".byte 0x0f, 0xff" +#define ASM_UD1 ".byte 0x0f, 0xb9" /* + ModRM */ +#define ASM_UD2 ".byte 0x0f, 0x0b" + +#define INSN_UD0 0xff0f +#define INSN_UD2 0x0b0f + +#define LEN_UD0 2 + +#ifdef CONFIG_GENERIC_BUG #ifdef CONFIG_X86_32 -# define __BUG_C0 "2:\t.long 1b, %c0\n" +# define __BUG_REL(val) ".long " __stringify(val) #else -# define __BUG_C0 "2:\t.long 1b - 2b, %c0 - 2b\n" +# define __BUG_REL(val) ".long " __stringify(val) " - 2b" #endif -#define BUG() \ -do { \ - asm volatile("1:\tud2\n" \ - ".pushsection __bug_table,\"a\"\n" \ - __BUG_C0 \ - "\t.word %c1, 0\n" \ - "\t.org 2b+%c2\n" \ - ".popsection" \ - : : "i" (__FILE__), "i" (__LINE__), \ - "i" (sizeof(struct bug_entry))); \ - unreachable(); \ +#ifdef CONFIG_DEBUG_BUGVERBOSE + +#define _BUG_FLAGS(ins, flags) \ +do { \ + asm volatile("1:\t" ins "\n" \ + ".pushsection __bug_table,\"a\"\n" \ + "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ + "\t" __BUG_REL(%c0) "\t# bug_entry::file\n" \ + "\t.word %c1" "\t# bug_entry::line\n" \ + "\t.word %c2" "\t# bug_entry::flags\n" \ + "\t.org 2b+%c3\n" \ + ".popsection" \ + : : "i" (__FILE__), "i" (__LINE__), \ + "i" (flags), \ + "i" (sizeof(struct bug_entry))); \ } while (0) +#else /* !CONFIG_DEBUG_BUGVERBOSE */ + +#define _BUG_FLAGS(ins, flags) \ +do { \ + asm volatile("1:\t" ins "\n" \ + ".pushsection __bug_table,\"a\"\n" \ + "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ + "\t.word %c0" "\t# bug_entry::flags\n" \ + "\t.org 2b+%c1\n" \ + ".popsection" \ + : : "i" (flags), \ + "i" (sizeof(struct bug_entry))); \ +} while (0) + +#endif /* CONFIG_DEBUG_BUGVERBOSE */ + #else + +#define _BUG_FLAGS(ins, flags) asm volatile(ins) + +#endif /* CONFIG_GENERIC_BUG */ + +#define HAVE_ARCH_BUG #define BUG() \ do { \ - asm volatile("ud2"); \ + _BUG_FLAGS(ASM_UD2, 0); \ unreachable(); \ } while (0) -#endif + +#define __WARN_FLAGS(flags) _BUG_FLAGS(ASM_UD0, BUGFLAG_WARNING|(flags)) #include <asm-generic/bug.h> diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h index 97848cdfcb1a..d90296d061e8 100644 --- a/arch/x86/include/asm/cmpxchg.h +++ b/arch/x86/include/asm/cmpxchg.h @@ -153,6 +153,76 @@ extern void __add_wrong_size(void) #define cmpxchg_local(ptr, old, new) \ __cmpxchg_local(ptr, old, new, sizeof(*(ptr))) + +#define __raw_try_cmpxchg(_ptr, _pold, _new, size, lock) \ +({ \ + bool success; \ + __typeof__(_ptr) _old = (_pold); \ + __typeof__(*(_ptr)) __old = *_old; \ + __typeof__(*(_ptr)) __new = (_new); \ + switch (size) { \ + case __X86_CASE_B: \ + { \ + volatile u8 *__ptr = (volatile u8 *)(_ptr); \ + asm volatile(lock "cmpxchgb %[new], %[ptr]" \ + CC_SET(z) \ + : CC_OUT(z) (success), \ + [ptr] "+m" (*__ptr), \ + [old] "+a" (__old) \ + : [new] "q" (__new) \ + : "memory"); \ + break; \ + } \ + case __X86_CASE_W: \ + { \ + volatile u16 *__ptr = (volatile u16 *)(_ptr); \ + asm volatile(lock "cmpxchgw %[new], %[ptr]" \ + CC_SET(z) \ + : CC_OUT(z) (success), \ + [ptr] "+m" (*__ptr), \ + [old] "+a" (__old) \ + : [new] "r" (__new) \ + : "memory"); \ + break; \ + } \ + case __X86_CASE_L: \ + { \ + volatile u32 *__ptr = (volatile u32 *)(_ptr); \ + asm volatile(lock "cmpxchgl %[new], %[ptr]" \ + CC_SET(z) \ + : CC_OUT(z) (success), \ + [ptr] "+m" (*__ptr), \ + [old] "+a" (__old) \ + : [new] "r" (__new) \ + : "memory"); \ + break; \ + } \ + case __X86_CASE_Q: \ + { \ + volatile u64 *__ptr = (volatile u64 *)(_ptr); \ + asm volatile(lock "cmpxchgq %[new], %[ptr]" \ + CC_SET(z) \ + : CC_OUT(z) (success), \ + [ptr] "+m" (*__ptr), \ + [old] "+a" (__old) \ + : [new] "r" (__new) \ + : "memory"); \ + break; \ + } \ + default: \ + __cmpxchg_wrong_size(); \ + } \ + if (unlikely(!success)) \ + *_old = __old; \ + likely(success); \ +}) + +#define __try_cmpxchg(ptr, pold, new, size) \ + __raw_try_cmpxchg((ptr), (pold), (new), (size), LOCK_PREFIX) + +#define try_cmpxchg(ptr, pold, new) \ + __try_cmpxchg((ptr), (pold), (new), sizeof(*(ptr))) + /* * xadd() adds "inc" to "*ptr" and atomically returns the previous * value of "*ptr". diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index b04bb6dfed7f..2701e5f8145b 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -187,6 +187,7 @@ * Reuse free bits when adding new feature flags! */ #define X86_FEATURE_RING3MWAIT ( 7*32+ 0) /* Ring 3 MONITOR/MWAIT */ +#define X86_FEATURE_CPUID_FAULT ( 7*32+ 1) /* Intel CPUID faulting */ #define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */ #define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */ #define X86_FEATURE_CAT_L3 ( 7*32+ 4) /* Cache Allocation Technology L3 */ @@ -201,6 +202,8 @@ #define X86_FEATURE_AVX512_4VNNIW (7*32+16) /* AVX-512 Neural Network Instructions */ #define X86_FEATURE_AVX512_4FMAPS (7*32+17) /* AVX-512 Multiply Accumulation Single precision */ +#define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */ + /* Virtualization flags: Linux defined, word 8 */ #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ #define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */ diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h deleted file mode 100644 index 67313f3a9874..000000000000 --- a/arch/x86/include/asm/e820.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef _ASM_X86_E820_H -#define _ASM_X86_E820_H - -/* - * E820_X_MAX is the maximum size of the extended E820 table. The extended - * table may contain up to 3 extra E820 entries per possible NUMA node, so we - * make room for 3 * MAX_NUMNODES possible entries, beyond the standard 128. - * Also note that E820_X_MAX *must* be defined before we include uapi/asm/e820.h. - */ -#include <linux/numa.h> -#define E820_X_MAX (E820MAX + 3 * MAX_NUMNODES) - -#include <uapi/asm/e820.h> - -#ifndef __ASSEMBLY__ -/* see comment in arch/x86/kernel/e820.c */ -extern struct e820map *e820; -extern struct e820map *e820_saved; - -extern unsigned long pci_mem_start; -extern int e820_any_mapped(u64 start, u64 end, unsigned type); -extern int e820_all_mapped(u64 start, u64 end, unsigned type); -extern void e820_add_region(u64 start, u64 size, int type); -extern void e820_print_map(char *who); -extern int -sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, u32 *pnr_map); -extern u64 e820_update_range(u64 start, u64 size, unsigned old_type, - unsigned new_type); -extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type, - int checktype); -extern void update_e820(void); -extern void e820_setup_gap(void); -struct setup_data; -extern void parse_e820_ext(u64 phys_addr, u32 data_len); - -#if defined(CONFIG_X86_64) || \ - (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) -extern void e820_mark_nosave_regions(unsigned long limit_pfn); -#else -static inline void e820_mark_nosave_regions(unsigned long limit_pfn) -{ -} -#endif - -extern unsigned long e820_end_of_ram_pfn(void); -extern unsigned long e820_end_of_low_ram_pfn(void); -extern u64 early_reserve_e820(u64 sizet, u64 align); - -void memblock_x86_fill(void); -void memblock_find_dma_reserve(void); - -extern void finish_e820_parsing(void); -extern void e820_reserve_resources(void); -extern void e820_reserve_resources_late(void); -extern void setup_memory_map(void); -extern char *default_machine_specific_memory_setup(void); - -extern void e820_reallocate_tables(void); - -/* - * Returns true iff the specified range [s,e) is completely contained inside - * the ISA region. - */ -static inline bool is_ISA_range(u64 s, u64 e) -{ - return s >= ISA_START_ADDRESS && e <= ISA_END_ADDRESS; -} - -#endif /* __ASSEMBLY__ */ -#include <linux/ioport.h> - -#define HIGH_MEMORY (1024*1024) -#endif /* _ASM_X86_E820_H */ diff --git a/arch/x86/include/asm/e820/api.h b/arch/x86/include/asm/e820/api.h new file mode 100644 index 000000000000..8e0f8b85b209 --- /dev/null +++ b/arch/x86/include/asm/e820/api.h @@ -0,0 +1,50 @@ +#ifndef _ASM_E820_API_H +#define _ASM_E820_API_H + +#include <asm/e820/types.h> + +extern struct e820_table *e820_table; +extern struct e820_table *e820_table_firmware; + +extern unsigned long pci_mem_start; + +extern bool e820__mapped_any(u64 start, u64 end, enum e820_type type); +extern bool e820__mapped_all(u64 start, u64 end, enum e820_type type); + +extern void e820__range_add (u64 start, u64 size, enum e820_type type); +extern u64 e820__range_update(u64 start, u64 size, enum e820_type old_type, enum e820_type new_type); +extern u64 e820__range_remove(u64 start, u64 size, enum e820_type old_type, bool check_type); + +extern void e820__print_table(char *who); +extern int e820__update_table(struct e820_table *table); +extern void e820__update_table_print(void); + +extern unsigned long e820__end_of_ram_pfn(void); +extern unsigned long e820__end_of_low_ram_pfn(void); + +extern u64 e820__memblock_alloc_reserved(u64 size, u64 align); +extern void e820__memblock_setup(void); + +extern void e820__reserve_setup_data(void); +extern void e820__finish_early_params(void); +extern void e820__reserve_resources(void); +extern void e820__reserve_resources_late(void); + +extern void e820__memory_setup(void); +extern void e820__memory_setup_extended(u64 phys_addr, u32 data_len); +extern char *e820__memory_setup_default(void); +extern void e820__setup_pci_gap(void); + +extern void e820__reallocate_tables(void); +extern void e820__register_nosave_regions(unsigned long limit_pfn); + +/* + * Returns true iff the specified range [start,end) is completely contained inside + * the ISA region. + */ +static inline bool is_ISA_range(u64 start, u64 end) +{ + return start >= ISA_START_ADDRESS && end <= ISA_END_ADDRESS; +} + +#endif /* _ASM_E820_API_H */ diff --git a/arch/x86/include/asm/e820/types.h b/arch/x86/include/asm/e820/types.h new file mode 100644 index 000000000000..4adeed03a9a1 --- /dev/null +++ b/arch/x86/include/asm/e820/types.h @@ -0,0 +1,104 @@ +#ifndef _ASM_E820_TYPES_H +#define _ASM_E820_TYPES_H + +#include <uapi/asm/bootparam.h> + +/* + * These are the E820 types known to the kernel: + */ +enum e820_type { + E820_TYPE_RAM = 1, + E820_TYPE_RESERVED = 2, + E820_TYPE_ACPI = 3, + E820_TYPE_NVS = 4, + E820_TYPE_UNUSABLE = 5, + E820_TYPE_PMEM = 7, + + /* + * This is a non-standardized way to represent ADR or + * NVDIMM regions that persist over a reboot. + * + * The kernel will ignore their special capabilities + * unless the CONFIG_X86_PMEM_LEGACY=y option is set. + * + * ( Note that older platforms also used 6 for the same + * type of memory, but newer versions switched to 12 as + * 6 was assigned differently. Some time they will learn... ) + */ + E820_TYPE_PRAM = 12, + + /* + * Reserved RAM used by the kernel itself if + * CONFIG_INTEL_TXT=y is enabled, memory of this type + * will be included in the S3 integrity calculation + * and so should not include any memory that the BIOS + * might alter over the S3 transition: + */ + E820_TYPE_RESERVED_KERN = 128, +}; + +/* + * A single E820 map entry, describing a memory range of [addr...addr+size-1], + * of 'type' memory type: + * + * (We pack it because there can be thousands of them on large systems.) + */ +struct e820_entry { + u64 addr; + u64 size; + enum e820_type type; +} __attribute__((packed)); + +/* + * The legacy E820 BIOS limits us to 128 (E820_MAX_ENTRIES_ZEROPAGE) nodes + * due to the constrained space in the zeropage. + * + * On large systems we can easily have thousands of nodes with RAM, + * which cannot be fit into so few entries - so we have a mechanism + * to extend the e820 table size at build-time, via the E820_MAX_ENTRIES + * define below. + * + * ( Those extra entries are enumerated via the EFI memory map, not + * via the legacy zeropage mechanism. ) + * + * Size our internal memory map tables to have room for these additional + * entries, based on a heuristic calculation: up to three entries per + * NUMA node, plus E820_MAX_ENTRIES_ZEROPAGE for some extra space. + * + * This allows for bootstrap/firmware quirks such as possible duplicate + * E820 entries that might need room in the same arrays, prior to the + * call to e820__update_table() to remove duplicates. The allowance + * of three memory map entries per node is "enough" entries for + * the initial hardware platform motivating this mechanism to make + * use of additional EFI map entries. Future platforms may want + * to allow more than three entries per node or otherwise refine + * this size. + */ + +#include <linux/numa.h> + +#define E820_MAX_ENTRIES (E820_MAX_ENTRIES_ZEROPAGE + 3*MAX_NUMNODES) + +/* + * The whole array of E820 entries: + */ +struct e820_table { + __u32 nr_entries; + struct e820_entry entries[E820_MAX_ENTRIES]; +}; + +/* + * Various well-known legacy memory ranges in physical memory: + */ +#define ISA_START_ADDRESS 0x000a0000 +#define ISA_END_ADDRESS 0x00100000 + +#define BIOS_BEGIN 0x000a0000 +#define BIOS_END 0x00100000 + +#define HIGH_MEMORY 0x00100000 + +#define BIOS_ROM_BASE 0xffe00000 +#define BIOS_ROM_END 0xffffffff + +#endif /* _ASM_E820_TYPES_H */ diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index 9d49c18b5ea9..3762536619f8 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h @@ -287,7 +287,7 @@ struct task_struct; #define ARCH_DLINFO_IA32 \ do { \ - if (vdso32_enabled) { \ + if (VDSO_CURRENT_BASE) { \ NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \ } \ diff --git a/arch/x86/include/asm/gart.h b/arch/x86/include/asm/gart.h index 156cd5d18d2a..1d268098ac2e 100644 --- a/arch/x86/include/asm/gart.h +++ b/arch/x86/include/asm/gart.h @@ -1,7 +1,7 @@ #ifndef _ASM_X86_GART_H #define _ASM_X86_GART_H -#include <asm/e820.h> +#include <asm/e820/api.h> extern void set_up_gart_resume(u32, u32); @@ -97,7 +97,7 @@ static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size) printk(KERN_INFO "Aperture beyond 4GB. Ignoring.\n"); return 0; } - if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) { + if (e820__mapped_any(aper_base, aper_base + aper_size, E820_TYPE_RAM)) { printk(KERN_INFO "Aperture pointing to e820 RAM. Ignoring.\n"); return 0; } diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 9814db42b790..75b748a1deb8 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -12,6 +12,7 @@ */ #define INTEL_FAM6_CORE_YONAH 0x0E + #define INTEL_FAM6_CORE2_MEROM 0x0F #define INTEL_FAM6_CORE2_MEROM_L 0x16 #define INTEL_FAM6_CORE2_PENRYN 0x17 @@ -21,6 +22,7 @@ #define INTEL_FAM6_NEHALEM_G 0x1F /* Auburndale / Havendale */ #define INTEL_FAM6_NEHALEM_EP 0x1A #define INTEL_FAM6_NEHALEM_EX 0x2E + #define INTEL_FAM6_WESTMERE 0x25 #define INTEL_FAM6_WESTMERE_EP 0x2C #define INTEL_FAM6_WESTMERE_EX 0x2F @@ -36,9 +38,9 @@ #define INTEL_FAM6_HASWELL_GT3E 0x46 #define INTEL_FAM6_BROADWELL_CORE 0x3D -#define INTEL_FAM6_BROADWELL_XEON_D 0x56 #define INTEL_FAM6_BROADWELL_GT3E 0x47 #define INTEL_FAM6_BROADWELL_X 0x4F +#define INTEL_FAM6_BROADWELL_XEON_D 0x56 #define INTEL_FAM6_SKYLAKE_MOBILE 0x4E #define INTEL_FAM6_SKYLAKE_DESKTOP 0x5E @@ -59,8 +61,8 @@ #define INTEL_FAM6_ATOM_MERRIFIELD 0x4A /* Tangier */ #define INTEL_FAM6_ATOM_MOOREFIELD 0x5A /* Anniedale */ #define INTEL_FAM6_ATOM_GOLDMONT 0x5C -#define INTEL_FAM6_ATOM_GEMINI_LAKE 0x7A #define INTEL_FAM6_ATOM_DENVERTON 0x5F /* Goldmont Microserver */ +#define INTEL_FAM6_ATOM_GEMINI_LAKE 0x7A /* Xeon Phi */ diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h index 0d64397cee58..597dc4995678 100644 --- a/arch/x86/include/asm/intel_rdt.h +++ b/arch/x86/include/asm/intel_rdt.h @@ -12,6 +12,7 @@ #define IA32_L3_QOS_CFG 0xc81 #define IA32_L3_CBM_BASE 0xc90 #define IA32_L2_CBM_BASE 0xd10 +#define IA32_MBA_THRTL_BASE 0xd50 #define L3_QOS_CDP_ENABLE 0x01ULL @@ -37,23 +38,30 @@ struct rdtgroup { /* rdtgroup.flags */ #define RDT_DELETED 1 +/* rftype.flags */ +#define RFTYPE_FLAGS_CPUS_LIST 1 + /* List of all resource groups */ extern struct list_head rdt_all_groups; +extern int max_name_width, max_data_width; + int __init rdtgroup_init(void); /** * struct rftype - describe each file in the resctrl file system - * @name: file name - * @mode: access mode - * @kf_ops: operations - * @seq_show: show content of the file - * @write: write to the file + * @name: File name + * @mode: Access mode + * @kf_ops: File operations + * @flags: File specific RFTYPE_FLAGS_* flags + * @seq_show: Show content of the file + * @write: Write to the file */ struct rftype { char *name; umode_t mode; struct kernfs_ops *kf_ops; + unsigned long flags; int (*seq_show)(struct kernfs_open_file *of, struct seq_file *sf, void *v); @@ -67,54 +75,21 @@ struct rftype { }; /** - * struct rdt_resource - attributes of an RDT resource - * @enabled: Is this feature enabled on this machine - * @capable: Is this feature available on this machine - * @name: Name to use in "schemata" file - * @num_closid: Number of CLOSIDs available - * @max_cbm: Largest Cache Bit Mask allowed - * @min_cbm_bits: Minimum number of consecutive bits to be set - * in a cache bit mask - * @domains: All domains for this resource - * @num_domains: Number of domains active - * @msr_base: Base MSR address for CBMs - * @tmp_cbms: Scratch space when updating schemata - * @num_tmp_cbms: Number of CBMs in tmp_cbms - * @cache_level: Which cache level defines scope of this domain - * @cbm_idx_multi: Multiplier of CBM index - * @cbm_idx_offset: Offset of CBM index. CBM index is computed by: - * closid * cbm_idx_multi + cbm_idx_offset - */ -struct rdt_resource { - bool enabled; - bool capable; - char *name; - int num_closid; - int cbm_len; - int min_cbm_bits; - u32 max_cbm; - struct list_head domains; - int num_domains; - int msr_base; - u32 *tmp_cbms; - int num_tmp_cbms; - int cache_level; - int cbm_idx_multi; - int cbm_idx_offset; -}; - -/** * struct rdt_domain - group of cpus sharing an RDT resource * @list: all instances of this resource * @id: unique id for this instance * @cpu_mask: which cpus share this resource - * @cbm: array of cache bit masks (indexed by CLOSID) + * @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID) + * @new_ctrl: new ctrl value to be loaded + * @have_new_ctrl: did user provide new_ctrl for this domain */ struct rdt_domain { struct list_head list; int id; struct cpumask cpu_mask; - u32 *cbm; + u32 *ctrl_val; + u32 new_ctrl; + bool have_new_ctrl; }; /** @@ -129,6 +104,83 @@ struct msr_param { int high; }; +/** + * struct rdt_cache - Cache allocation related data + * @cbm_len: Length of the cache bit mask + * @min_cbm_bits: Minimum number of consecutive bits to be set + * @cbm_idx_mult: Multiplier of CBM index + * @cbm_idx_offset: Offset of CBM index. CBM index is computed by: + * closid * cbm_idx_multi + cbm_idx_offset + * in a cache bit mask + */ +struct rdt_cache { + unsigned int cbm_len; + unsigned int min_cbm_bits; + unsigned int cbm_idx_mult; + unsigned int cbm_idx_offset; +}; + +/** + * struct rdt_membw - Memory bandwidth allocation related data + * @max_delay: Max throttle delay. Delay is the hardware + * representation for memory bandwidth. + * @min_bw: Minimum memory bandwidth percentage user can request + * @bw_gran: Granularity at which the memory bandwidth is allocated + * @delay_linear: True if memory B/W delay is in linear scale + * @mb_map: Mapping of memory B/W percentage to memory B/W delay + */ +struct rdt_membw { + u32 max_delay; + u32 min_bw; + u32 bw_gran; + u32 delay_linear; + u32 *mb_map; +}; + +/** + * struct rdt_resource - attributes of an RDT resource + * @enabled: Is this feature enabled on this machine + * @capable: Is this feature available on this machine + * @name: Name to use in "schemata" file + * @num_closid: Number of CLOSIDs available + * @cache_level: Which cache level defines scope of this resource + * @default_ctrl: Specifies default cache cbm or memory B/W percent. + * @msr_base: Base MSR address for CBMs + * @msr_update: Function pointer to update QOS MSRs + * @data_width: Character width of data when displaying + * @domains: All domains for this resource + * @cache: Cache allocation related data + * @info_files: resctrl info files for the resource + * @nr_info_files: Number of info files + * @format_str: Per resource format string to show domain value + * @parse_ctrlval: Per resource function pointer to parse control values + */ +struct rdt_resource { + bool enabled; + bool capable; + char *name; + int num_closid; + int cache_level; + u32 default_ctrl; + unsigned int msr_base; + void (*msr_update) (struct rdt_domain *d, struct msr_param *m, + struct rdt_resource *r); + int data_width; + struct list_head domains; + struct rdt_cache cache; + struct rdt_membw membw; + struct rftype *info_files; + int nr_info_files; + const char *format_str; + int (*parse_ctrlval) (char *buf, struct rdt_resource *r, + struct rdt_domain *d); +}; + +void rdt_get_cache_infofile(struct rdt_resource *r); +void rdt_get_mba_infofile(struct rdt_resource *r); +int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d); +int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d); + extern struct mutex rdtgroup_mutex; extern struct rdt_resource rdt_resources_all[]; @@ -142,6 +194,7 @@ enum { RDT_RESOURCE_L3DATA, RDT_RESOURCE_L3CODE, RDT_RESOURCE_L2, + RDT_RESOURCE_MBA, /* Must be the last */ RDT_NUM_RESOURCES, @@ -149,7 +202,7 @@ enum { #define for_each_capable_rdt_resource(r) \ for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ - r++) \ + r++) \ if (r->capable) #define for_each_enabled_rdt_resource(r) \ @@ -165,8 +218,16 @@ union cpuid_0x10_1_eax { unsigned int full; }; -/* CPUID.(EAX=10H, ECX=ResID=1).EDX */ -union cpuid_0x10_1_edx { +/* CPUID.(EAX=10H, ECX=ResID=3).EAX */ +union cpuid_0x10_3_eax { + struct { + unsigned int max_delay:12; + } split; + unsigned int full; +}; + +/* CPUID.(EAX=10H, ECX=ResID).EDX */ +union cpuid_0x10_x_edx { struct { unsigned int cos_max:16; } split; @@ -175,7 +236,7 @@ union cpuid_0x10_1_edx { DECLARE_PER_CPU_READ_MOSTLY(int, cpu_closid); -void rdt_cbm_update(void *arg); +void rdt_ctrl_update(void *arg); struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn); void rdtgroup_kn_unlock(struct kernfs_node *kn); ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h index 200581691c6e..34b984c60790 100644 --- a/arch/x86/include/asm/kprobes.h +++ b/arch/x86/include/asm/kprobes.h @@ -72,14 +72,13 @@ struct arch_specific_insn { /* copy of the original instruction */ kprobe_opcode_t *insn; /* - * boostable = -1: This instruction type is not boostable. - * boostable = 0: This instruction type is boostable. - * boostable = 1: This instruction has been boosted: we have + * boostable = false: This instruction type is not boostable. + * boostable = true: This instruction has been boosted: we have * added a relative jump after the instruction copy in insn, * so no single-step and fixup are needed (unless there's * a post_handler or break_handler). */ - int boostable; + bool boostable; bool if_modifier; }; diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index e63873683d4a..4fd5195deed0 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -128,7 +128,7 @@ * debugging tools. Each entry is only valid when its finished flag * is set. */ -struct mce_log { +struct mce_log_buffer { char signature[12]; /* "MACHINECHECK" */ unsigned len; /* = MCE_LOG_LEN */ unsigned next; @@ -191,10 +191,12 @@ extern struct mca_config mca_cfg; extern struct mca_msr_regs msr_ops; enum mce_notifier_prios { - MCE_PRIO_SRAO = INT_MAX, - MCE_PRIO_EXTLOG = INT_MAX - 1, - MCE_PRIO_NFIT = INT_MAX - 2, - MCE_PRIO_EDAC = INT_MAX - 3, + MCE_PRIO_FIRST = INT_MAX, + MCE_PRIO_SRAO = INT_MAX - 1, + MCE_PRIO_EXTLOG = INT_MAX - 2, + MCE_PRIO_NFIT = INT_MAX - 3, + MCE_PRIO_EDAC = INT_MAX - 4, + MCE_PRIO_MCELOG = 1, MCE_PRIO_LOWEST = 0, }; diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index 32007041ef8c..831eb7895535 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h @@ -64,7 +64,7 @@ static inline void find_smp_config(void) } #ifdef CONFIG_X86_MPPARSE -extern void early_reserve_e820_mpc_new(void); +extern void e820__memblock_alloc_reserved_mpc_new(void); extern int enable_update_mptable; extern int default_mpc_apic_id(struct mpc_cpu *m); extern void default_smp_read_mpc_oem(struct mpc_table *mpc); @@ -76,7 +76,7 @@ extern void default_mpc_oem_bus_info(struct mpc_bus *m, char *str); extern void default_find_smp_config(void); extern void default_get_smp_config(unsigned int early); #else -static inline void early_reserve_e820_mpc_new(void) { } +static inline void e820__memblock_alloc_reserved_mpc_new(void) { } #define enable_update_mptable 0 #define default_mpc_apic_id NULL #define default_smp_read_mpc_oem NULL diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index d8b5f8ab8ef9..673f9ac50f6d 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -45,6 +45,8 @@ #define MSR_IA32_PERFCTR1 0x000000c2 #define MSR_FSB_FREQ 0x000000cd #define MSR_PLATFORM_INFO 0x000000ce +#define MSR_PLATFORM_INFO_CPUID_FAULT_BIT 31 +#define MSR_PLATFORM_INFO_CPUID_FAULT BIT_ULL(MSR_PLATFORM_INFO_CPUID_FAULT_BIT) #define MSR_PKG_CST_CONFIG_CONTROL 0x000000e2 #define NHM_C3_AUTO_DEMOTE (1UL << 25) @@ -127,6 +129,7 @@ /* DEBUGCTLMSR bits (others vary by model): */ #define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ +#define DEBUGCTLMSR_BTF_SHIFT 1 #define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */ #define DEBUGCTLMSR_TR (1UL << 6) #define DEBUGCTLMSR_BTS (1UL << 7) @@ -552,10 +555,12 @@ #define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT 39 #define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT) -/* MISC_FEATURE_ENABLES non-architectural features */ -#define MSR_MISC_FEATURE_ENABLES 0x00000140 +/* MISC_FEATURES_ENABLES non-architectural features */ +#define MSR_MISC_FEATURES_ENABLES 0x00000140 -#define MSR_MISC_FEATURE_ENABLES_RING3MWAIT_BIT 1 +#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT 0 +#define MSR_MISC_FEATURES_ENABLES_CPUID_FAULT BIT_ULL(MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT) +#define MSR_MISC_FEATURES_ENABLES_RING3MWAIT_BIT 1 #define MSR_IA32_TSC_DEADLINE 0x000006E0 diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index b3bebf9e5746..b4a0d43248cf 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h @@ -4,6 +4,7 @@ #include <asm/page_64_types.h> #ifndef __ASSEMBLY__ +#include <asm/alternative.h> /* duplicated to the one in bootmem.h */ extern unsigned long max_pfn; @@ -34,7 +35,20 @@ extern unsigned long __phys_addr_symbol(unsigned long); #define pfn_valid(pfn) ((pfn) < max_pfn) #endif -void clear_page(void *page); +void clear_page_orig(void *page); +void clear_page_rep(void *page); +void clear_page_erms(void *page); + +static inline void clear_page(void *page) +{ + alternative_call_2(clear_page_orig, + clear_page_rep, X86_FEATURE_REP_GOOD, + clear_page_erms, X86_FEATURE_ERMS, + "=D" (page), + "0" (page) + : "memory", "rax", "rcx"); +} + void copy_page(void *to, void *from); #endif /* !__ASSEMBLY__ */ diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index d08eacd298c2..9f1b21f372fe 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -4,6 +4,8 @@ * (c) 1999 Martin Mares <mj@ucw.cz> */ +#include <linux/ioport.h> + #undef DEBUG #ifdef DEBUG diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 585ee0d42d18..2197e5322df9 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -2,8 +2,6 @@ #define _ASM_X86_PGTABLE_H #include <asm/page.h> -#include <asm/e820.h> - #include <asm/pgtable_types.h> /* @@ -845,6 +843,7 @@ static inline int pgd_none(pgd_t pgd) extern int direct_gbpages; void init_mem_mapping(void); void early_alloc_pgt_buf(void); +extern void memblock_find_dma_reserve(void); #ifdef CONFIG_X86_64 /* Realmode trampoline initialization. */ diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h index 2c1ebeb4d737..529bb4a6487a 100644 --- a/arch/x86/include/asm/pmem.h +++ b/arch/x86/include/asm/pmem.h @@ -55,7 +55,8 @@ static inline int arch_memcpy_from_pmem(void *dst, const void *src, size_t n) * @size: number of bytes to write back * * Write back a cache range using the CLWB (cache line write back) - * instruction. + * instruction. Note that @size is internally rounded up to be cache + * line size aligned. */ static inline void arch_wb_cache_pmem(void *addr, size_t size) { @@ -69,15 +70,6 @@ static inline void arch_wb_cache_pmem(void *addr, size_t size) clwb(p); } -/* - * copy_from_iter_nocache() on x86 only uses non-temporal stores for iovec - * iterators, so for other types (bvec & kvec) we must do a cache write-back. - */ -static inline bool __iter_needs_pmem_wb(struct iov_iter *i) -{ - return iter_is_iovec(i) == false; -} - /** * arch_copy_from_iter_pmem - copy data from an iterator to PMEM * @addr: PMEM destination address @@ -94,7 +86,35 @@ static inline size_t arch_copy_from_iter_pmem(void *addr, size_t bytes, /* TODO: skip the write-back by always using non-temporal stores */ len = copy_from_iter_nocache(addr, bytes, i); - if (__iter_needs_pmem_wb(i)) + /* + * In the iovec case on x86_64 copy_from_iter_nocache() uses + * non-temporal stores for the bulk of the transfer, but we need + * to manually flush if the transfer is unaligned. A cached + * memory copy is used when destination or size is not naturally + * aligned. That is: + * - Require 8-byte alignment when size is 8 bytes or larger. + * - Require 4-byte alignment when size is 4 bytes. + * + * In the non-iovec case the entire destination needs to be + * flushed. + */ + if (iter_is_iovec(i)) { + unsigned long flushed, dest = (unsigned long) addr; + + if (bytes < 8) { + if (!IS_ALIGNED(dest, 4) || (bytes != 4)) + arch_wb_cache_pmem(addr, 1); + } else { + if (!IS_ALIGNED(dest, 8)) { + dest = ALIGN(dest, boot_cpu_data.x86_clflush_size); + arch_wb_cache_pmem(addr, 1); + } + + flushed = dest - (unsigned long) addr; + if (bytes > flushed && !IS_ALIGNED(bytes - flushed, 8)) + arch_wb_cache_pmem(addr + bytes - 1, 1); + } + } else arch_wb_cache_pmem(addr, bytes); return len; diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index f385eca5407a..78defd0aa220 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -80,7 +80,7 @@ extern u16 __read_mostly tlb_lld_1g[NR_INFO]; /* * CPU type and hardware bug flags. Kept separately for each CPU. - * Members of this structure are referenced in head.S, so think twice + * Members of this structure are referenced in head_32.S, so think twice * before touching them. [mj] */ @@ -89,14 +89,7 @@ struct cpuinfo_x86 { __u8 x86_vendor; /* CPU vendor */ __u8 x86_model; __u8 x86_mask; -#ifdef CONFIG_X86_32 - char wp_works_ok; /* It doesn't on 386's */ - - /* Problems on some 486Dx4's and old 386's: */ - char rfu; - char pad0; - char pad1; -#else +#ifdef CONFIG_X86_64 /* Number of 4K pages in DTLB/ITLB combined(in pages): */ int x86_tlbsize; #endif @@ -884,6 +877,8 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip, extern int get_tsc_mode(unsigned long adr); extern int set_tsc_mode(unsigned int val); +DECLARE_PER_CPU(u64, msr_misc_features_shadow); + /* Register/unregister a process' MPX related resource */ #define MPX_ENABLE_MANAGEMENT() mpx_enable_management() #define MPX_DISABLE_MANAGEMENT() mpx_disable_management() diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h index 9b9b30b19441..8d3964fc5f91 100644 --- a/arch/x86/include/asm/proto.h +++ b/arch/x86/include/asm/proto.h @@ -9,6 +9,7 @@ void syscall_init(void); #ifdef CONFIG_X86_64 void entry_SYSCALL_64(void); +long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2); #endif #ifdef CONFIG_X86_32 @@ -30,6 +31,7 @@ void x86_report_nx(void); extern int reboot_force; -long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); +long do_arch_prctl_common(struct task_struct *task, int option, + unsigned long cpuid_enabled); #endif /* _ASM_X86_PROTO_H */ diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h index 2cb1cc253d51..fc62ba8dce93 100644 --- a/arch/x86/include/asm/reboot.h +++ b/arch/x86/include/asm/reboot.h @@ -15,6 +15,7 @@ struct machine_ops { }; extern struct machine_ops machine_ops; +extern int crashing_cpu; void native_machine_crash_shutdown(struct pt_regs *regs); void native_machine_shutdown(void); diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index ad6f5eb07a95..9fc44b95f7cb 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -87,6 +87,7 @@ struct thread_info { #define TIF_SECCOMP 8 /* secure computing */ #define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */ #define TIF_UPROBE 12 /* breakpointed or singlestepping */ +#define TIF_NOCPUID 15 /* CPUID is not accessible in userland */ #define TIF_NOTSC 16 /* TSC is not accessible in userland */ #define TIF_IA32 17 /* IA32 compatibility process */ #define TIF_NOHZ 19 /* in adaptive nohz mode */ @@ -110,6 +111,7 @@ struct thread_info { #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_USER_RETURN_NOTIFY (1 << TIF_USER_RETURN_NOTIFY) #define _TIF_UPROBE (1 << TIF_UPROBE) +#define _TIF_NOCPUID (1 << TIF_NOCPUID) #define _TIF_NOTSC (1 << TIF_NOTSC) #define _TIF_IA32 (1 << TIF_IA32) #define _TIF_NOHZ (1 << TIF_NOHZ) @@ -138,7 +140,7 @@ struct thread_info { /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW \ - (_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP) + (_TIF_IO_BITMAP|_TIF_NOCPUID|_TIF_NOTSC|_TIF_BLOCKSTEP) #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) @@ -239,6 +241,8 @@ static inline int arch_within_stack_frames(const void * const stack, extern void arch_task_cache_init(void); extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); extern void arch_release_task_struct(struct task_struct *tsk); +extern void arch_setup_new_exec(void); +#define arch_setup_new_exec arch_setup_new_exec #endif /* !__ASSEMBLY__ */ #endif /* _ASM_X86_THREAD_INFO_H */ diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h index a04eabd43d06..27e9f9d769b8 100644 --- a/arch/x86/include/asm/timer.h +++ b/arch/x86/include/asm/timer.h @@ -12,6 +12,8 @@ extern int recalibrate_cpu_khz(void); extern int no_timer_check; +extern bool using_native_sched_clock(void); + /* * We use the full linear equation: f(x) = a + b*x, in order to allow * a continuous function in the face of dynamic freq changes. diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index fc5abff9b7fd..75d002bdb3f3 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -110,6 +110,16 @@ static inline void cr4_clear_bits(unsigned long mask) } } +static inline void cr4_toggle_bits(unsigned long mask) +{ + unsigned long cr4; + + cr4 = this_cpu_read(cpu_tlbstate.cr4); + cr4 ^= mask; + this_cpu_write(cpu_tlbstate.cr4, cr4); + __write_cr4(cr4); +} + /* Read the CR4 shadow. */ static inline unsigned long cr4_read_shadow(void) { diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index ea148313570f..68766b276d9e 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -3,19 +3,14 @@ /* * User space memory access functions */ -#include <linux/errno.h> #include <linux/compiler.h> #include <linux/kasan-checks.h> -#include <linux/thread_info.h> #include <linux/string.h> #include <asm/asm.h> #include <asm/page.h> #include <asm/smap.h> #include <asm/extable.h> -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - /* * The fs value determines whether argument validity checking should be * performed or not. If get_fs() == USER_DS, checking is performed, with @@ -384,6 +379,18 @@ do { \ : "=r" (err), ltype(x) \ : "m" (__m(addr)), "i" (errret), "0" (err)) +#define __get_user_asm_nozero(x, addr, err, itype, rtype, ltype, errret) \ + asm volatile("\n" \ + "1: mov"itype" %2,%"rtype"1\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: mov %3,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE(1b, 3b) \ + : "=r" (err), ltype(x) \ + : "m" (__m(addr)), "i" (errret), "0" (err)) + /* * This doesn't do __uaccess_begin/end - the exception handling * around it must do that. @@ -675,59 +682,6 @@ extern struct movsl_mask { # include <asm/uaccess_64.h> #endif -unsigned long __must_check _copy_from_user(void *to, const void __user *from, - unsigned n); -unsigned long __must_check _copy_to_user(void __user *to, const void *from, - unsigned n); - -extern void __compiletime_error("usercopy buffer size is too small") -__bad_copy_user(void); - -static inline void copy_user_overflow(int size, unsigned long count) -{ - WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); -} - -static __always_inline unsigned long __must_check -copy_from_user(void *to, const void __user *from, unsigned long n) -{ - int sz = __compiletime_object_size(to); - - might_fault(); - - kasan_check_write(to, n); - - if (likely(sz < 0 || sz >= n)) { - check_object_size(to, n, false); - n = _copy_from_user(to, from, n); - } else if (!__builtin_constant_p(n)) - copy_user_overflow(sz, n); - else - __bad_copy_user(); - - return n; -} - -static __always_inline unsigned long __must_check -copy_to_user(void __user *to, const void *from, unsigned long n) -{ - int sz = __compiletime_object_size(from); - - kasan_check_read(from, n); - - might_fault(); - - if (likely(sz < 0 || sz >= n)) { - check_object_size(from, n, true); - n = _copy_to_user(to, from, n); - } else if (!__builtin_constant_p(n)) - copy_user_overflow(sz, n); - else - __bad_copy_user(); - - return n; -} - /* * We rely on the nested NMI work to allow atomic faults from the NMI path; the * nested NMI paths are careful to preserve CR2. diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h index 7d3bdd1ed697..aeda9bb8af50 100644 --- a/arch/x86/include/asm/uaccess_32.h +++ b/arch/x86/include/asm/uaccess_32.h @@ -4,149 +4,52 @@ /* * User space memory access functions */ -#include <linux/errno.h> -#include <linux/thread_info.h> #include <linux/string.h> #include <asm/asm.h> #include <asm/page.h> -unsigned long __must_check __copy_to_user_ll - (void __user *to, const void *from, unsigned long n); -unsigned long __must_check __copy_from_user_ll - (void *to, const void __user *from, unsigned long n); -unsigned long __must_check __copy_from_user_ll_nozero - (void *to, const void __user *from, unsigned long n); -unsigned long __must_check __copy_from_user_ll_nocache - (void *to, const void __user *from, unsigned long n); +unsigned long __must_check __copy_user_ll + (void *to, const void *from, unsigned long n); unsigned long __must_check __copy_from_user_ll_nocache_nozero (void *to, const void __user *from, unsigned long n); -/** - * __copy_to_user_inatomic: - Copy a block of data into user space, with less checking. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. - * - * Copy data from kernel space to user space. Caller must check - * the specified block with access_ok() before calling this function. - * The caller should also make sure he pins the user space address - * so that we don't result in page fault and sleep. - */ -static __always_inline unsigned long __must_check -__copy_to_user_inatomic(void __user *to, const void *from, unsigned long n) -{ - check_object_size(from, n, true); - return __copy_to_user_ll(to, from, n); -} - -/** - * __copy_to_user: - Copy a block of data into user space, with less checking. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from kernel space to user space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - */ static __always_inline unsigned long __must_check -__copy_to_user(void __user *to, const void *from, unsigned long n) +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - might_fault(); - return __copy_to_user_inatomic(to, from, n); + return __copy_user_ll((__force void *)to, from, n); } static __always_inline unsigned long -__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) -{ - return __copy_from_user_ll_nozero(to, from, n); -} - -/** - * __copy_from_user: - Copy a block of data from user space, with less checking. - * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from user space to kernel space. Caller must check - * the specified block with access_ok() before calling this function. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - * - * An alternate version - __copy_from_user_inatomic() - may be called from - * atomic context and will fail rather than sleep. In this case the - * uncopied bytes will *NOT* be padded with zeros. See fs/filemap.h - * for explanation of why this is needed. - */ -static __always_inline unsigned long -__copy_from_user(void *to, const void __user *from, unsigned long n) -{ - might_fault(); - check_object_size(to, n, false); - if (__builtin_constant_p(n)) { - unsigned long ret; - - switch (n) { - case 1: - __uaccess_begin(); - __get_user_size(*(u8 *)to, from, 1, ret, 1); - __uaccess_end(); - return ret; - case 2: - __uaccess_begin(); - __get_user_size(*(u16 *)to, from, 2, ret, 2); - __uaccess_end(); - return ret; - case 4: - __uaccess_begin(); - __get_user_size(*(u32 *)to, from, 4, ret, 4); - __uaccess_end(); - return ret; - } - } - return __copy_from_user_ll(to, from, n); -} - -static __always_inline unsigned long __copy_from_user_nocache(void *to, - const void __user *from, unsigned long n) +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - might_fault(); if (__builtin_constant_p(n)) { unsigned long ret; switch (n) { case 1: + ret = 0; __uaccess_begin(); - __get_user_size(*(u8 *)to, from, 1, ret, 1); + __get_user_asm_nozero(*(u8 *)to, from, ret, + "b", "b", "=q", 1); __uaccess_end(); return ret; case 2: + ret = 0; __uaccess_begin(); - __get_user_size(*(u16 *)to, from, 2, ret, 2); + __get_user_asm_nozero(*(u16 *)to, from, ret, + "w", "w", "=r", 2); __uaccess_end(); return ret; case 4: + ret = 0; __uaccess_begin(); - __get_user_size(*(u32 *)to, from, 4, ret, 4); + __get_user_asm_nozero(*(u32 *)to, from, ret, + "l", "k", "=r", 4); __uaccess_end(); return ret; } } - return __copy_from_user_ll_nocache(to, from, n); + return __copy_user_ll(to, (__force const void *)from, n); } static __always_inline unsigned long diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 673059a109fe..c5504b9a472e 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -5,7 +5,6 @@ * User space memory access functions */ #include <linux/compiler.h> -#include <linux/errno.h> #include <linux/lockdep.h> #include <linux/kasan-checks.h> #include <asm/alternative.h> @@ -46,58 +45,54 @@ copy_user_generic(void *to, const void *from, unsigned len) return ret; } -__must_check unsigned long -copy_in_user(void __user *to, const void __user *from, unsigned len); - -static __always_inline __must_check -int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size) +static __always_inline __must_check unsigned long +raw_copy_from_user(void *dst, const void __user *src, unsigned long size) { int ret = 0; - check_object_size(dst, size, false); if (!__builtin_constant_p(size)) return copy_user_generic(dst, (__force void *)src, size); switch (size) { case 1: __uaccess_begin(); - __get_user_asm(*(u8 *)dst, (u8 __user *)src, + __get_user_asm_nozero(*(u8 *)dst, (u8 __user *)src, ret, "b", "b", "=q", 1); __uaccess_end(); return ret; case 2: __uaccess_begin(); - __get_user_asm(*(u16 *)dst, (u16 __user *)src, + __get_user_asm_nozero(*(u16 *)dst, (u16 __user *)src, ret, "w", "w", "=r", 2); __uaccess_end(); return ret; case 4: __uaccess_begin(); - __get_user_asm(*(u32 *)dst, (u32 __user *)src, + __get_user_asm_nozero(*(u32 *)dst, (u32 __user *)src, ret, "l", "k", "=r", 4); __uaccess_end(); return ret; case 8: __uaccess_begin(); - __get_user_asm(*(u64 *)dst, (u64 __user *)src, + __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, ret, "q", "", "=r", 8); __uaccess_end(); return ret; case 10: __uaccess_begin(); - __get_user_asm(*(u64 *)dst, (u64 __user *)src, + __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, ret, "q", "", "=r", 10); if (likely(!ret)) - __get_user_asm(*(u16 *)(8 + (char *)dst), + __get_user_asm_nozero(*(u16 *)(8 + (char *)dst), (u16 __user *)(8 + (char __user *)src), ret, "w", "w", "=r", 2); __uaccess_end(); return ret; case 16: __uaccess_begin(); - __get_user_asm(*(u64 *)dst, (u64 __user *)src, + __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, ret, "q", "", "=r", 16); if (likely(!ret)) - __get_user_asm(*(u64 *)(8 + (char *)dst), + __get_user_asm_nozero(*(u64 *)(8 + (char *)dst), (u64 __user *)(8 + (char __user *)src), ret, "q", "", "=r", 8); __uaccess_end(); @@ -107,20 +102,11 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size) } } -static __always_inline __must_check -int __copy_from_user(void *dst, const void __user *src, unsigned size) -{ - might_fault(); - kasan_check_write(dst, size); - return __copy_from_user_nocheck(dst, src, size); -} - -static __always_inline __must_check -int __copy_to_user_nocheck(void __user *dst, const void *src, unsigned size) +static __always_inline __must_check unsigned long +raw_copy_to_user(void __user *dst, const void *src, unsigned long size) { int ret = 0; - check_object_size(src, size, true); if (!__builtin_constant_p(size)) return copy_user_generic((__force void *)dst, src, size); switch (size) { @@ -176,100 +162,16 @@ int __copy_to_user_nocheck(void __user *dst, const void *src, unsigned size) } static __always_inline __must_check -int __copy_to_user(void __user *dst, const void *src, unsigned size) -{ - might_fault(); - kasan_check_read(src, size); - return __copy_to_user_nocheck(dst, src, size); -} - -static __always_inline __must_check -int __copy_in_user(void __user *dst, const void __user *src, unsigned size) -{ - int ret = 0; - - might_fault(); - if (!__builtin_constant_p(size)) - return copy_user_generic((__force void *)dst, - (__force void *)src, size); - switch (size) { - case 1: { - u8 tmp; - __uaccess_begin(); - __get_user_asm(tmp, (u8 __user *)src, - ret, "b", "b", "=q", 1); - if (likely(!ret)) - __put_user_asm(tmp, (u8 __user *)dst, - ret, "b", "b", "iq", 1); - __uaccess_end(); - return ret; - } - case 2: { - u16 tmp; - __uaccess_begin(); - __get_user_asm(tmp, (u16 __user *)src, - ret, "w", "w", "=r", 2); - if (likely(!ret)) - __put_user_asm(tmp, (u16 __user *)dst, - ret, "w", "w", "ir", 2); - __uaccess_end(); - return ret; - } - - case 4: { - u32 tmp; - __uaccess_begin(); - __get_user_asm(tmp, (u32 __user *)src, - ret, "l", "k", "=r", 4); - if (likely(!ret)) - __put_user_asm(tmp, (u32 __user *)dst, - ret, "l", "k", "ir", 4); - __uaccess_end(); - return ret; - } - case 8: { - u64 tmp; - __uaccess_begin(); - __get_user_asm(tmp, (u64 __user *)src, - ret, "q", "", "=r", 8); - if (likely(!ret)) - __put_user_asm(tmp, (u64 __user *)dst, - ret, "q", "", "er", 8); - __uaccess_end(); - return ret; - } - default: - return copy_user_generic((__force void *)dst, - (__force void *)src, size); - } -} - -static __must_check __always_inline int -__copy_from_user_inatomic(void *dst, const void __user *src, unsigned size) -{ - kasan_check_write(dst, size); - return __copy_from_user_nocheck(dst, src, size); -} - -static __must_check __always_inline int -__copy_to_user_inatomic(void __user *dst, const void *src, unsigned size) +unsigned long raw_copy_in_user(void __user *dst, const void __user *src, unsigned long size) { - kasan_check_read(src, size); - return __copy_to_user_nocheck(dst, src, size); + return copy_user_generic((__force void *)dst, + (__force void *)src, size); } extern long __copy_user_nocache(void *dst, const void __user *src, unsigned size, int zerorest); static inline int -__copy_from_user_nocache(void *dst, const void __user *src, unsigned size) -{ - might_fault(); - kasan_check_write(dst, size); - return __copy_user_nocache(dst, src, size, 1); -} - -static inline int __copy_from_user_inatomic_nocache(void *dst, const void __user *src, unsigned size) { diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h index 6fa75b17aec3..9b10dcd51716 100644 --- a/arch/x86/include/asm/unwind.h +++ b/arch/x86/include/asm/unwind.h @@ -12,8 +12,10 @@ struct unwind_state { struct task_struct *task; int graph_idx; #ifdef CONFIG_FRAME_POINTER + bool got_irq; unsigned long *bp, *orig_sp; struct pt_regs *regs; + unsigned long ip; #else unsigned long *sp; #endif diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h index 72e8300b1e8a..9cffb44a3cf5 100644 --- a/arch/x86/include/asm/uv/uv_hub.h +++ b/arch/x86/include/asm/uv/uv_hub.h @@ -485,15 +485,17 @@ static inline unsigned long uv_soc_phys_ram_to_gpa(unsigned long paddr) if (paddr < uv_hub_info->lowmem_remap_top) paddr |= uv_hub_info->lowmem_remap_base; - paddr |= uv_hub_info->gnode_upper; - if (m_val) + + if (m_val) { + paddr |= uv_hub_info->gnode_upper; paddr = ((paddr << uv_hub_info->m_shift) >> uv_hub_info->m_shift) | ((paddr >> uv_hub_info->m_val) << uv_hub_info->n_lshift); - else + } else { paddr |= uv_soc_phys_ram_to_nasid(paddr) << uv_hub_info->gpa_shift; + } return paddr; } diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 33cbd3db97b9..64c5e745ebad 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -6,6 +6,7 @@ #include <linux/spinlock.h> #include <linux/pfn.h> #include <linux/mm.h> +#include <linux/device.h> #include <linux/uaccess.h> #include <asm/page.h> diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index 07244ea16765..ddef37b16af2 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h @@ -34,7 +34,6 @@ #include <linux/screen_info.h> #include <linux/apm_bios.h> #include <linux/edd.h> -#include <asm/e820.h> #include <asm/ist.h> #include <video/edid.h> @@ -111,6 +110,21 @@ struct efi_info { __u32 efi_memmap_hi; }; +/* + * This is the maximum number of entries in struct boot_params::e820_table + * (the zeropage), which is part of the x86 boot protocol ABI: + */ +#define E820_MAX_ENTRIES_ZEROPAGE 128 + +/* + * The E820 memory region entry of the boot protocol ABI: + */ +struct boot_e820_entry { + __u64 addr; + __u64 size; + __u32 type; +} __attribute__((packed)); + /* The so-called "zeropage" */ struct boot_params { struct screen_info screen_info; /* 0x000 */ @@ -153,7 +167,7 @@ struct boot_params { struct setup_header hdr; /* setup header */ /* 0x1f1 */ __u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)]; __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */ - struct e820entry e820_map[E820MAX]; /* 0x2d0 */ + struct boot_e820_entry e820_table[E820_MAX_ENTRIES_ZEROPAGE]; /* 0x2d0 */ __u8 _pad8[48]; /* 0xcd0 */ struct edd_info eddbuf[EDDMAXNR]; /* 0xd00 */ __u8 _pad9[276]; /* 0xeec */ diff --git a/arch/x86/include/uapi/asm/prctl.h b/arch/x86/include/uapi/asm/prctl.h index 835aa51c7f6e..c45765517092 100644 --- a/arch/x86/include/uapi/asm/prctl.h +++ b/arch/x86/include/uapi/asm/prctl.h @@ -1,10 +1,13 @@ #ifndef _ASM_X86_PRCTL_H #define _ASM_X86_PRCTL_H -#define ARCH_SET_GS 0x1001 -#define ARCH_SET_FS 0x1002 -#define ARCH_GET_FS 0x1003 -#define ARCH_GET_GS 0x1004 +#define ARCH_SET_GS 0x1001 +#define ARCH_SET_FS 0x1002 +#define ARCH_GET_FS 0x1003 +#define ARCH_GET_GS 0x1004 + +#define ARCH_GET_CPUID 0x1011 +#define ARCH_SET_CPUID 0x1012 #define ARCH_MAP_VDSO_X32 0x2001 #define ARCH_MAP_VDSO_32 0x2002 diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 84c00592d359..4b994232cb57 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -27,7 +27,7 @@ KASAN_SANITIZE_stacktrace.o := n OBJECT_FILES_NON_STANDARD_head_$(BITS).o := y OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y -OBJECT_FILES_NON_STANDARD_mcount_$(BITS).o := y +OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o := y OBJECT_FILES_NON_STANDARD_test_nx.o := y # If instrumentation of this dir is enabled, boot hangs during first second. @@ -46,7 +46,7 @@ obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o obj-$(CONFIG_IRQ_WORK) += irq_work.o obj-y += probe_roms.o -obj-$(CONFIG_X86_64) += sys_x86_64.o mcount_64.o +obj-$(CONFIG_X86_64) += sys_x86_64.o obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o obj-$(CONFIG_SYSFS) += ksysfs.o obj-y += bootflag.o e820.o @@ -82,6 +82,7 @@ obj-y += apic/ obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_LIVEPATCH) += livepatch.o +obj-$(CONFIG_FUNCTION_TRACER) += ftrace_$(BITS).o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o obj-$(CONFIG_X86_TSC) += trace_clock.o diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index b2879cc23db4..6bb680671088 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -37,6 +37,7 @@ #include <linux/pci.h> #include <linux/efi-bgrt.h> +#include <asm/e820/api.h> #include <asm/irqdomain.h> #include <asm/pci_x86.h> #include <asm/pgtable.h> @@ -1564,12 +1565,6 @@ int __init early_acpi_boot_init(void) return 0; } -static int __init acpi_parse_bgrt(struct acpi_table_header *table) -{ - efi_bgrt_init(table); - return 0; -} - int __init acpi_boot_init(void) { /* those are executed after early-quirks are executed */ @@ -1729,6 +1724,6 @@ int __acpi_release_global_lock(unsigned int *lock) void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size) { - e820_add_region(addr, size, E820_ACPI); - update_e820(); + e820__range_add(addr, size, E820_TYPE_ACPI); + e820__update_table_print(); } diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 0a2bb1f62e72..ef2859f9fcce 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -21,7 +21,7 @@ #include <linux/pci.h> #include <linux/bitops.h> #include <linux/suspend.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/io.h> #include <asm/iommu.h> #include <asm/gart.h> @@ -306,13 +306,13 @@ void __init early_gart_iommu_check(void) fix = 1; if (gart_fix_e820 && !fix && aper_enabled) { - if (e820_any_mapped(aper_base, aper_base + aper_size, - E820_RAM)) { + if (e820__mapped_any(aper_base, aper_base + aper_size, + E820_TYPE_RAM)) { /* reserve it, so we can reuse it in second kernel */ pr_info("e820: reserve [mem %#010Lx-%#010Lx] for GART\n", aper_base, aper_base + aper_size - 1); - e820_add_region(aper_base, aper_size, E820_RESERVED); - update_e820(); + e820__range_add(aper_base, aper_size, E820_TYPE_RESERVED); + e820__update_table_print(); } } diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 8ccb7ef512e0..2d75faf743f2 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -731,8 +731,10 @@ static int __init calibrate_APIC_clock(void) TICK_NSEC, lapic_clockevent.shift); lapic_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); + lapic_clockevent.max_delta_ticks = 0x7FFFFF; lapic_clockevent.min_delta_ns = clockevent_delta2ns(0xF, &lapic_clockevent); + lapic_clockevent.min_delta_ticks = 0xF; lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; return 0; } @@ -778,8 +780,10 @@ static int __init calibrate_APIC_clock(void) lapic_clockevent.shift); lapic_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent); + lapic_clockevent.max_delta_ticks = 0x7FFFFFFF; lapic_clockevent.min_delta_ns = clockevent_delta2ns(0xF, &lapic_clockevent); + lapic_clockevent.min_delta_ticks = 0xF; lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS; @@ -1789,8 +1793,8 @@ void __init init_apic_mappings(void) apic_phys = mp_lapic_addr; /* - * acpi lapic path already maps that address in - * acpi_register_lapic_address() + * If the system has ACPI MADT tables or MP info, the LAPIC + * address is already registered. */ if (!acpi_lapic && !smp_found_config) register_lapic_address(apic_phys); @@ -2237,7 +2241,7 @@ void __init apic_set_eoi_write(void (*eoi_write)(u32 reg, u32 v)) static void __init apic_bsp_up_setup(void) { #ifdef CONFIG_X86_64 - apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid)); + apic_write(APIC_ID, apic->set_apic_id(boot_cpu_physical_apicid)); #else /* * Hack: In case of kdump, after a crash, kernel might be booting @@ -2627,7 +2631,7 @@ static int __init lapic_insert_resource(void) } /* - * need call insert after e820_reserve_resources() + * need call insert after e820__reserve_resources() * that is using request_resource */ late_initcall(lapic_insert_resource); diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index b109e4389c92..2262eb6df796 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c @@ -26,7 +26,7 @@ #include <linux/interrupt.h> #include <asm/acpi.h> -#include <asm/e820.h> +#include <asm/e820/api.h> static void noop_init_apic_ldr(void) { } static void noop_send_IPI(int cpu, int vector) { } diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c index c48264e202fd..2e8f7f048f4f 100644 --- a/arch/x86/kernel/apic/probe_32.c +++ b/arch/x86/kernel/apic/probe_32.c @@ -25,7 +25,7 @@ #include <linux/interrupt.h> #include <asm/acpi.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #ifdef CONFIG_HOTPLUG_CPU #define DEFAULT_SEND_IPI (1) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index e9f8f8cdd570..b487b3a01615 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -34,6 +34,7 @@ #include <asm/uv/bios.h> #include <asm/uv/uv.h> #include <asm/apic.h> +#include <asm/e820/api.h> #include <asm/ipi.h> #include <asm/smp.h> #include <asm/x86_init.h> @@ -1105,7 +1106,8 @@ void __init uv_init_hub_info(struct uv_hub_info_s *hi) node_id.v = uv_read_local_mmr(UVH_NODE_ID); uv_cpuid.gnode_shift = max_t(unsigned int, uv_cpuid.gnode_shift, mn.n_val); hi->gnode_extra = (node_id.s.node_id & ~((1 << uv_cpuid.gnode_shift) - 1)) >> 1; - hi->gnode_upper = (unsigned long)hi->gnode_extra << mn.m_val; + if (mn.m_val) + hi->gnode_upper = (u64)hi->gnode_extra << mn.m_val; if (uv_gp_table) { hi->global_mmr_base = uv_gp_table->mmr_base; diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index 43955ee6715b..44207b71fee1 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c @@ -3,7 +3,7 @@ #include <linux/sched/clock.h> #include <asm/cpufeature.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/mtrr.h> #include <asm/msr.h> diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 063197771b8d..dfa90a3a5145 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -90,16 +90,12 @@ static void probe_xeon_phi_r3mwait(struct cpuinfo_x86 *c) return; } - if (ring3mwait_disabled) { - msr_clear_bit(MSR_MISC_FEATURE_ENABLES, - MSR_MISC_FEATURE_ENABLES_RING3MWAIT_BIT); + if (ring3mwait_disabled) return; - } - - msr_set_bit(MSR_MISC_FEATURE_ENABLES, - MSR_MISC_FEATURE_ENABLES_RING3MWAIT_BIT); set_cpu_cap(c, X86_FEATURE_RING3MWAIT); + this_cpu_or(msr_misc_features_shadow, + 1UL << MSR_MISC_FEATURES_ENABLES_RING3MWAIT_BIT); if (c == &boot_cpu_data) ELF_HWCAP2 |= HWCAP2_RING3MWAIT; @@ -488,6 +484,34 @@ static void intel_bsp_resume(struct cpuinfo_x86 *c) init_intel_energy_perf(c); } +static void init_cpuid_fault(struct cpuinfo_x86 *c) +{ + u64 msr; + + if (!rdmsrl_safe(MSR_PLATFORM_INFO, &msr)) { + if (msr & MSR_PLATFORM_INFO_CPUID_FAULT) + set_cpu_cap(c, X86_FEATURE_CPUID_FAULT); + } +} + +static void init_intel_misc_features(struct cpuinfo_x86 *c) +{ + u64 msr; + + if (rdmsrl_safe(MSR_MISC_FEATURES_ENABLES, &msr)) + return; + + /* Clear all MISC features */ + this_cpu_write(msr_misc_features_shadow, 0); + + /* Check features and update capabilities and shadow control bits */ + init_cpuid_fault(c); + probe_xeon_phi_r3mwait(c); + + msr = this_cpu_read(msr_misc_features_shadow); + wrmsrl(MSR_MISC_FEATURES_ENABLES, msr); +} + static void init_intel(struct cpuinfo_x86 *c) { unsigned int l2 = 0; @@ -602,7 +626,7 @@ static void init_intel(struct cpuinfo_x86 *c) init_intel_energy_perf(c); - probe_xeon_phi_r3mwait(c); + init_intel_misc_features(c); } #ifdef CONFIG_X86_32 diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index 5a533fefefa0..5b366462f579 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c @@ -32,55 +32,98 @@ #include <asm/intel-family.h> #include <asm/intel_rdt.h> +#define MAX_MBA_BW 100u +#define MBA_IS_LINEAR 0x4 + /* Mutex to protect rdtgroup access. */ DEFINE_MUTEX(rdtgroup_mutex); DEFINE_PER_CPU_READ_MOSTLY(int, cpu_closid); +/* + * Used to store the max resource name width and max resource data width + * to display the schemata in a tabular format + */ +int max_name_width, max_data_width; + +static void +mba_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r); +static void +cat_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r); + #define domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].domains) struct rdt_resource rdt_resources_all[] = { { - .name = "L3", - .domains = domain_init(RDT_RESOURCE_L3), - .msr_base = IA32_L3_CBM_BASE, - .min_cbm_bits = 1, - .cache_level = 3, - .cbm_idx_multi = 1, - .cbm_idx_offset = 0 + .name = "L3", + .domains = domain_init(RDT_RESOURCE_L3), + .msr_base = IA32_L3_CBM_BASE, + .msr_update = cat_wrmsr, + .cache_level = 3, + .cache = { + .min_cbm_bits = 1, + .cbm_idx_mult = 1, + .cbm_idx_offset = 0, + }, + .parse_ctrlval = parse_cbm, + .format_str = "%d=%0*x", + }, + { + .name = "L3DATA", + .domains = domain_init(RDT_RESOURCE_L3DATA), + .msr_base = IA32_L3_CBM_BASE, + .msr_update = cat_wrmsr, + .cache_level = 3, + .cache = { + .min_cbm_bits = 1, + .cbm_idx_mult = 2, + .cbm_idx_offset = 0, + }, + .parse_ctrlval = parse_cbm, + .format_str = "%d=%0*x", }, { - .name = "L3DATA", - .domains = domain_init(RDT_RESOURCE_L3DATA), - .msr_base = IA32_L3_CBM_BASE, - .min_cbm_bits = 1, - .cache_level = 3, - .cbm_idx_multi = 2, - .cbm_idx_offset = 0 + .name = "L3CODE", + .domains = domain_init(RDT_RESOURCE_L3CODE), + .msr_base = IA32_L3_CBM_BASE, + .msr_update = cat_wrmsr, + .cache_level = 3, + .cache = { + .min_cbm_bits = 1, + .cbm_idx_mult = 2, + .cbm_idx_offset = 1, + }, + .parse_ctrlval = parse_cbm, + .format_str = "%d=%0*x", }, { - .name = "L3CODE", - .domains = domain_init(RDT_RESOURCE_L3CODE), - .msr_base = IA32_L3_CBM_BASE, - .min_cbm_bits = 1, - .cache_level = 3, - .cbm_idx_multi = 2, - .cbm_idx_offset = 1 + .name = "L2", + .domains = domain_init(RDT_RESOURCE_L2), + .msr_base = IA32_L2_CBM_BASE, + .msr_update = cat_wrmsr, + .cache_level = 2, + .cache = { + .min_cbm_bits = 1, + .cbm_idx_mult = 1, + .cbm_idx_offset = 0, + }, + .parse_ctrlval = parse_cbm, + .format_str = "%d=%0*x", }, { - .name = "L2", - .domains = domain_init(RDT_RESOURCE_L2), - .msr_base = IA32_L2_CBM_BASE, - .min_cbm_bits = 1, - .cache_level = 2, - .cbm_idx_multi = 1, - .cbm_idx_offset = 0 + .name = "MB", + .domains = domain_init(RDT_RESOURCE_MBA), + .msr_base = IA32_MBA_THRTL_BASE, + .msr_update = mba_wrmsr, + .cache_level = 3, + .parse_ctrlval = parse_bw, + .format_str = "%d=%*d", }, }; -static int cbm_idx(struct rdt_resource *r, int closid) +static unsigned int cbm_idx(struct rdt_resource *r, unsigned int closid) { - return closid * r->cbm_idx_multi + r->cbm_idx_offset; + return closid * r->cache.cbm_idx_mult + r->cache.cbm_idx_offset; } /* @@ -118,9 +161,9 @@ static inline bool cache_alloc_hsw_probe(void) return false; r->num_closid = 4; - r->cbm_len = 20; - r->max_cbm = max_cbm; - r->min_cbm_bits = 2; + r->default_ctrl = max_cbm; + r->cache.cbm_len = 20; + r->cache.min_cbm_bits = 2; r->capable = true; r->enabled = true; @@ -130,16 +173,66 @@ static inline bool cache_alloc_hsw_probe(void) return false; } -static void rdt_get_config(int idx, struct rdt_resource *r) +/* + * rdt_get_mb_table() - get a mapping of bandwidth(b/w) percentage values + * exposed to user interface and the h/w understandable delay values. + * + * The non-linear delay values have the granularity of power of two + * and also the h/w does not guarantee a curve for configured delay + * values vs. actual b/w enforced. + * Hence we need a mapping that is pre calibrated so the user can + * express the memory b/w as a percentage value. + */ +static inline bool rdt_get_mb_table(struct rdt_resource *r) +{ + /* + * There are no Intel SKUs as of now to support non-linear delay. + */ + pr_info("MBA b/w map not implemented for cpu:%d, model:%d", + boot_cpu_data.x86, boot_cpu_data.x86_model); + + return false; +} + +static bool rdt_get_mem_config(struct rdt_resource *r) +{ + union cpuid_0x10_3_eax eax; + union cpuid_0x10_x_edx edx; + u32 ebx, ecx; + + cpuid_count(0x00000010, 3, &eax.full, &ebx, &ecx, &edx.full); + r->num_closid = edx.split.cos_max + 1; + r->membw.max_delay = eax.split.max_delay + 1; + r->default_ctrl = MAX_MBA_BW; + if (ecx & MBA_IS_LINEAR) { + r->membw.delay_linear = true; + r->membw.min_bw = MAX_MBA_BW - r->membw.max_delay; + r->membw.bw_gran = MAX_MBA_BW - r->membw.max_delay; + } else { + if (!rdt_get_mb_table(r)) + return false; + } + r->data_width = 3; + rdt_get_mba_infofile(r); + + r->capable = true; + r->enabled = true; + + return true; +} + +static void rdt_get_cache_config(int idx, struct rdt_resource *r) { union cpuid_0x10_1_eax eax; - union cpuid_0x10_1_edx edx; + union cpuid_0x10_x_edx edx; u32 ebx, ecx; cpuid_count(0x00000010, idx, &eax.full, &ebx, &ecx, &edx.full); r->num_closid = edx.split.cos_max + 1; - r->cbm_len = eax.split.cbm_len + 1; - r->max_cbm = BIT_MASK(eax.split.cbm_len + 1) - 1; + r->cache.cbm_len = eax.split.cbm_len + 1; + r->default_ctrl = BIT_MASK(eax.split.cbm_len + 1) - 1; + r->data_width = (r->cache.cbm_len + 3) / 4; + rdt_get_cache_infofile(r); r->capable = true; r->enabled = true; } @@ -150,8 +243,9 @@ static void rdt_get_cdp_l3_config(int type) struct rdt_resource *r = &rdt_resources_all[type]; r->num_closid = r_l3->num_closid / 2; - r->cbm_len = r_l3->cbm_len; - r->max_cbm = r_l3->max_cbm; + r->cache.cbm_len = r_l3->cache.cbm_len; + r->default_ctrl = r_l3->default_ctrl; + r->data_width = (r->cache.cbm_len + 3) / 4; r->capable = true; /* * By default, CDP is disabled. CDP can be enabled by mount parameter @@ -160,33 +254,6 @@ static void rdt_get_cdp_l3_config(int type) r->enabled = false; } -static inline bool get_rdt_resources(void) -{ - bool ret = false; - - if (cache_alloc_hsw_probe()) - return true; - - if (!boot_cpu_has(X86_FEATURE_RDT_A)) - return false; - - if (boot_cpu_has(X86_FEATURE_CAT_L3)) { - rdt_get_config(1, &rdt_resources_all[RDT_RESOURCE_L3]); - if (boot_cpu_has(X86_FEATURE_CDP_L3)) { - rdt_get_cdp_l3_config(RDT_RESOURCE_L3DATA); - rdt_get_cdp_l3_config(RDT_RESOURCE_L3CODE); - } - ret = true; - } - if (boot_cpu_has(X86_FEATURE_CAT_L2)) { - /* CPUID 0x10.2 fields are same format at 0x10.1 */ - rdt_get_config(2, &rdt_resources_all[RDT_RESOURCE_L2]); - ret = true; - } - - return ret; -} - static int get_cache_id(int cpu, int level) { struct cpu_cacheinfo *ci = get_cpu_cacheinfo(cpu); @@ -200,29 +267,55 @@ static int get_cache_id(int cpu, int level) return -1; } -void rdt_cbm_update(void *arg) +/* + * Map the memory b/w percentage value to delay values + * that can be written to QOS_MSRs. + * There are currently no SKUs which support non linear delay values. + */ +static u32 delay_bw_map(unsigned long bw, struct rdt_resource *r) { - struct msr_param *m = (struct msr_param *)arg; + if (r->membw.delay_linear) + return MAX_MBA_BW - bw; + + pr_warn_once("Non Linear delay-bw map not supported but queried\n"); + return r->default_ctrl; +} + +static void +mba_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r) +{ + unsigned int i; + + /* Write the delay values for mba. */ + for (i = m->low; i < m->high; i++) + wrmsrl(r->msr_base + i, delay_bw_map(d->ctrl_val[i], r)); +} + +static void +cat_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r) +{ + unsigned int i; + + for (i = m->low; i < m->high; i++) + wrmsrl(r->msr_base + cbm_idx(r, i), d->ctrl_val[i]); +} + +void rdt_ctrl_update(void *arg) +{ + struct msr_param *m = arg; struct rdt_resource *r = m->res; - int i, cpu = smp_processor_id(); + int cpu = smp_processor_id(); struct rdt_domain *d; list_for_each_entry(d, &r->domains, list) { /* Find the domain that contains this CPU */ - if (cpumask_test_cpu(cpu, &d->cpu_mask)) - goto found; + if (cpumask_test_cpu(cpu, &d->cpu_mask)) { + r->msr_update(d, m, r); + return; + } } - pr_info_once("cpu %d not found in any domain for resource %s\n", + pr_warn_once("cpu %d not found in any domain for resource %s\n", cpu, r->name); - - return; - -found: - for (i = m->low; i < m->high; i++) { - int idx = cbm_idx(r, i); - - wrmsrl(r->msr_base + idx, d->cbm[i]); - } } /* @@ -258,6 +351,32 @@ static struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id, return NULL; } +static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d) +{ + struct msr_param m; + u32 *dc; + int i; + + dc = kmalloc_array(r->num_closid, sizeof(*d->ctrl_val), GFP_KERNEL); + if (!dc) + return -ENOMEM; + + d->ctrl_val = dc; + + /* + * Initialize the Control MSRs to having no control. + * For Cache Allocation: Set all bits in cbm + * For Memory Allocation: Set b/w requested to 100 + */ + for (i = 0; i < r->num_closid; i++, dc++) + *dc = r->default_ctrl; + + m.low = 0; + m.high = r->num_closid; + r->msr_update(d, &m, r); + return 0; +} + /* * domain_add_cpu - Add a cpu to a resource's domain list. * @@ -273,7 +392,7 @@ static struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id, */ static void domain_add_cpu(int cpu, struct rdt_resource *r) { - int i, id = get_cache_id(cpu, r->cache_level); + int id = get_cache_id(cpu, r->cache_level); struct list_head *add_pos = NULL; struct rdt_domain *d; @@ -294,22 +413,13 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r) d->id = id; - d->cbm = kmalloc_array(r->num_closid, sizeof(*d->cbm), GFP_KERNEL); - if (!d->cbm) { + if (domain_setup_ctrlval(r, d)) { kfree(d); return; } - for (i = 0; i < r->num_closid; i++) { - int idx = cbm_idx(r, i); - - d->cbm[i] = r->max_cbm; - wrmsrl(r->msr_base + idx, d->cbm[i]); - } - cpumask_set_cpu(cpu, &d->cpu_mask); list_add_tail(&d->list, add_pos); - r->num_domains++; } static void domain_remove_cpu(int cpu, struct rdt_resource *r) @@ -325,8 +435,7 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r) cpumask_clear_cpu(cpu, &d->cpu_mask); if (cpumask_empty(&d->cpu_mask)) { - r->num_domains--; - kfree(d->cbm); + kfree(d->ctrl_val); list_del(&d->list); kfree(d); } @@ -374,6 +483,57 @@ static int intel_rdt_offline_cpu(unsigned int cpu) return 0; } +/* + * Choose a width for the resource name and resource data based on the + * resource that has widest name and cbm. + */ +static __init void rdt_init_padding(void) +{ + struct rdt_resource *r; + int cl; + + for_each_capable_rdt_resource(r) { + cl = strlen(r->name); + if (cl > max_name_width) + max_name_width = cl; + + if (r->data_width > max_data_width) + max_data_width = r->data_width; + } +} + +static __init bool get_rdt_resources(void) +{ + bool ret = false; + + if (cache_alloc_hsw_probe()) + return true; + + if (!boot_cpu_has(X86_FEATURE_RDT_A)) + return false; + + if (boot_cpu_has(X86_FEATURE_CAT_L3)) { + rdt_get_cache_config(1, &rdt_resources_all[RDT_RESOURCE_L3]); + if (boot_cpu_has(X86_FEATURE_CDP_L3)) { + rdt_get_cdp_l3_config(RDT_RESOURCE_L3DATA); + rdt_get_cdp_l3_config(RDT_RESOURCE_L3CODE); + } + ret = true; + } + if (boot_cpu_has(X86_FEATURE_CAT_L2)) { + /* CPUID 0x10.2 fields are same format at 0x10.1 */ + rdt_get_cache_config(2, &rdt_resources_all[RDT_RESOURCE_L2]); + ret = true; + } + + if (boot_cpu_has(X86_FEATURE_MBA)) { + if (rdt_get_mem_config(&rdt_resources_all[RDT_RESOURCE_MBA])) + ret = true; + } + + return ret; +} + static int __init intel_rdt_late_init(void) { struct rdt_resource *r; @@ -382,6 +542,8 @@ static int __init intel_rdt_late_init(void) if (!get_rdt_resources()) return -ENODEV; + rdt_init_padding(); + state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/rdt/cat:online:", intel_rdt_online_cpu, intel_rdt_offline_cpu); diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c index 9ac2a5cdd9c2..f5af0cc7eb0d 100644 --- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c @@ -174,6 +174,13 @@ static struct kernfs_ops rdtgroup_kf_single_ops = { .seq_show = rdtgroup_seqfile_show, }; +static bool is_cpu_list(struct kernfs_open_file *of) +{ + struct rftype *rft = of->kn->priv; + + return rft->flags & RFTYPE_FLAGS_CPUS_LIST; +} + static int rdtgroup_cpus_show(struct kernfs_open_file *of, struct seq_file *s, void *v) { @@ -182,10 +189,12 @@ static int rdtgroup_cpus_show(struct kernfs_open_file *of, rdtgrp = rdtgroup_kn_lock_live(of->kn); - if (rdtgrp) - seq_printf(s, "%*pb\n", cpumask_pr_args(&rdtgrp->cpu_mask)); - else + if (rdtgrp) { + seq_printf(s, is_cpu_list(of) ? "%*pbl\n" : "%*pb\n", + cpumask_pr_args(&rdtgrp->cpu_mask)); + } else { ret = -ENOENT; + } rdtgroup_kn_unlock(of->kn); return ret; @@ -252,7 +261,11 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of, goto unlock; } - ret = cpumask_parse(buf, newmask); + if (is_cpu_list(of)) + ret = cpulist_parse(buf, newmask); + else + ret = cpumask_parse(buf, newmask); + if (ret) goto unlock; @@ -473,6 +486,14 @@ static struct rftype rdtgroup_base_files[] = { .seq_show = rdtgroup_cpus_show, }, { + .name = "cpus_list", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = rdtgroup_cpus_write, + .seq_show = rdtgroup_cpus_show, + .flags = RFTYPE_FLAGS_CPUS_LIST, + }, + { .name = "tasks", .mode = 0644, .kf_ops = &rdtgroup_kf_single_ops, @@ -494,32 +515,56 @@ static int rdt_num_closids_show(struct kernfs_open_file *of, struct rdt_resource *r = of->kn->parent->priv; seq_printf(seq, "%d\n", r->num_closid); + return 0; +} + +static int rdt_default_ctrl_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + seq_printf(seq, "%x\n", r->default_ctrl); return 0; } -static int rdt_cbm_mask_show(struct kernfs_open_file *of, +static int rdt_min_cbm_bits_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) { struct rdt_resource *r = of->kn->parent->priv; - seq_printf(seq, "%x\n", r->max_cbm); + seq_printf(seq, "%u\n", r->cache.min_cbm_bits); + return 0; +} + +static int rdt_min_bw_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + seq_printf(seq, "%u\n", r->membw.min_bw); return 0; } -static int rdt_min_cbm_bits_show(struct kernfs_open_file *of, +static int rdt_bw_gran_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) { struct rdt_resource *r = of->kn->parent->priv; - seq_printf(seq, "%d\n", r->min_cbm_bits); + seq_printf(seq, "%u\n", r->membw.bw_gran); + return 0; +} + +static int rdt_delay_linear_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + seq_printf(seq, "%u\n", r->membw.delay_linear); return 0; } /* rdtgroup information files for one cache resource. */ -static struct rftype res_info_files[] = { +static struct rftype res_cache_info_files[] = { { .name = "num_closids", .mode = 0444, @@ -530,7 +575,7 @@ static struct rftype res_info_files[] = { .name = "cbm_mask", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, - .seq_show = rdt_cbm_mask_show, + .seq_show = rdt_default_ctrl_show, }, { .name = "min_cbm_bits", @@ -540,11 +585,52 @@ static struct rftype res_info_files[] = { }, }; +/* rdtgroup information files for memory bandwidth. */ +static struct rftype res_mba_info_files[] = { + { + .name = "num_closids", + .mode = 0444, + .kf_ops = &rdtgroup_kf_single_ops, + .seq_show = rdt_num_closids_show, + }, + { + .name = "min_bandwidth", + .mode = 0444, + .kf_ops = &rdtgroup_kf_single_ops, + .seq_show = rdt_min_bw_show, + }, + { + .name = "bandwidth_gran", + .mode = 0444, + .kf_ops = &rdtgroup_kf_single_ops, + .seq_show = rdt_bw_gran_show, + }, + { + .name = "delay_linear", + .mode = 0444, + .kf_ops = &rdtgroup_kf_single_ops, + .seq_show = rdt_delay_linear_show, + }, +}; + +void rdt_get_mba_infofile(struct rdt_resource *r) +{ + r->info_files = res_mba_info_files; + r->nr_info_files = ARRAY_SIZE(res_mba_info_files); +} + +void rdt_get_cache_infofile(struct rdt_resource *r) +{ + r->info_files = res_cache_info_files; + r->nr_info_files = ARRAY_SIZE(res_cache_info_files); +} + static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) { struct kernfs_node *kn_subdir; + struct rftype *res_info_files; struct rdt_resource *r; - int ret; + int ret, len; /* create the directory */ kn_info = kernfs_create_dir(parent_kn, "info", parent_kn->mode, NULL); @@ -563,8 +649,11 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) ret = rdtgroup_kn_set_ugid(kn_subdir); if (ret) goto out_destroy; - ret = rdtgroup_add_files(kn_subdir, res_info_files, - ARRAY_SIZE(res_info_files)); + + res_info_files = r->info_files; + len = r->nr_info_files; + + ret = rdtgroup_add_files(kn_subdir, res_info_files, len); if (ret) goto out_destroy; kernfs_activate(kn_subdir); @@ -780,7 +869,7 @@ out: return dentry; } -static int reset_all_cbms(struct rdt_resource *r) +static int reset_all_ctrls(struct rdt_resource *r) { struct msr_param msr_param; cpumask_var_t cpu_mask; @@ -803,14 +892,14 @@ static int reset_all_cbms(struct rdt_resource *r) cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask); for (i = 0; i < r->num_closid; i++) - d->cbm[i] = r->max_cbm; + d->ctrl_val[i] = r->default_ctrl; } cpu = get_cpu(); /* Update CBM on this cpu if it's in cpu_mask. */ if (cpumask_test_cpu(cpu, cpu_mask)) - rdt_cbm_update(&msr_param); + rdt_ctrl_update(&msr_param); /* Update CBM on all other cpus in cpu_mask. */ - smp_call_function_many(cpu_mask, rdt_cbm_update, &msr_param, 1); + smp_call_function_many(cpu_mask, rdt_ctrl_update, &msr_param, 1); put_cpu(); free_cpumask_var(cpu_mask); @@ -896,7 +985,7 @@ static void rdt_kill_sb(struct super_block *sb) /*Put everything back to default values. */ for_each_enabled_rdt_resource(r) - reset_all_cbms(r); + reset_all_ctrls(r); cdp_disable(); rmdir_all_sub(); static_branch_disable(&rdt_enable_key); diff --git a/arch/x86/kernel/cpu/intel_rdt_schemata.c b/arch/x86/kernel/cpu/intel_rdt_schemata.c index f369cb8db0d5..406d7a6532f9 100644 --- a/arch/x86/kernel/cpu/intel_rdt_schemata.c +++ b/arch/x86/kernel/cpu/intel_rdt_schemata.c @@ -29,26 +29,77 @@ #include <asm/intel_rdt.h> /* + * Check whether MBA bandwidth percentage value is correct. The value is + * checked against the minimum and max bandwidth values specified by the + * hardware. The allocated bandwidth percentage is rounded to the next + * control step available on the hardware. + */ +static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) +{ + unsigned long bw; + int ret; + + /* + * Only linear delay values is supported for current Intel SKUs. + */ + if (!r->membw.delay_linear) + return false; + + ret = kstrtoul(buf, 10, &bw); + if (ret) + return false; + + if (bw < r->membw.min_bw || bw > r->default_ctrl) + return false; + + *data = roundup(bw, (unsigned long)r->membw.bw_gran); + return true; +} + +int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d) +{ + unsigned long data; + + if (d->have_new_ctrl) + return -EINVAL; + + if (!bw_validate(buf, &data, r)) + return -EINVAL; + d->new_ctrl = data; + d->have_new_ctrl = true; + + return 0; +} + +/* * Check whether a cache bit mask is valid. The SDM says: * Please note that all (and only) contiguous '1' combinations * are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.). * Additionally Haswell requires at least two bits set. */ -static bool cbm_validate(unsigned long var, struct rdt_resource *r) +static bool cbm_validate(char *buf, unsigned long *data, struct rdt_resource *r) { - unsigned long first_bit, zero_bit; + unsigned long first_bit, zero_bit, val; + unsigned int cbm_len = r->cache.cbm_len; + int ret; + + ret = kstrtoul(buf, 16, &val); + if (ret) + return false; - if (var == 0 || var > r->max_cbm) + if (val == 0 || val > r->default_ctrl) return false; - first_bit = find_first_bit(&var, r->cbm_len); - zero_bit = find_next_zero_bit(&var, r->cbm_len, first_bit); + first_bit = find_first_bit(&val, cbm_len); + zero_bit = find_next_zero_bit(&val, cbm_len, first_bit); - if (find_next_bit(&var, r->cbm_len, zero_bit) < r->cbm_len) + if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len) return false; - if ((zero_bit - first_bit) < r->min_cbm_bits) + if ((zero_bit - first_bit) < r->cache.min_cbm_bits) return false; + + *data = val; return true; } @@ -56,17 +107,17 @@ static bool cbm_validate(unsigned long var, struct rdt_resource *r) * Read one cache bit mask (hex). Check that it is valid for the current * resource type. */ -static int parse_cbm(char *buf, struct rdt_resource *r) +int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d) { unsigned long data; - int ret; - ret = kstrtoul(buf, 16, &data); - if (ret) - return ret; - if (!cbm_validate(data, r)) + if (d->have_new_ctrl) return -EINVAL; - r->tmp_cbms[r->num_tmp_cbms++] = data; + + if(!cbm_validate(buf, &data, r)) + return -EINVAL; + d->new_ctrl = data; + d->have_new_ctrl = true; return 0; } @@ -74,8 +125,8 @@ static int parse_cbm(char *buf, struct rdt_resource *r) /* * For each domain in this resource we expect to find a series of: * id=mask - * separated by ";". The "id" is in decimal, and must appear in the - * right order. + * separated by ";". The "id" is in decimal, and must match one of + * the "id"s for this resource. */ static int parse_line(char *line, struct rdt_resource *r) { @@ -83,21 +134,22 @@ static int parse_line(char *line, struct rdt_resource *r) struct rdt_domain *d; unsigned long dom_id; +next: + if (!line || line[0] == '\0') + return 0; + dom = strsep(&line, ";"); + id = strsep(&dom, "="); + if (!dom || kstrtoul(id, 10, &dom_id)) + return -EINVAL; + dom = strim(dom); list_for_each_entry(d, &r->domains, list) { - dom = strsep(&line, ";"); - if (!dom) - return -EINVAL; - id = strsep(&dom, "="); - if (kstrtoul(id, 10, &dom_id) || dom_id != d->id) - return -EINVAL; - if (parse_cbm(dom, r)) - return -EINVAL; + if (d->id == dom_id) { + if (r->parse_ctrlval(dom, r, d)) + return -EINVAL; + goto next; + } } - - /* Any garbage at the end of the line? */ - if (line && line[0]) - return -EINVAL; - return 0; + return -EINVAL; } static int update_domains(struct rdt_resource *r, int closid) @@ -105,7 +157,7 @@ static int update_domains(struct rdt_resource *r, int closid) struct msr_param msr_param; cpumask_var_t cpu_mask; struct rdt_domain *d; - int cpu, idx = 0; + int cpu; if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL)) return -ENOMEM; @@ -115,30 +167,46 @@ static int update_domains(struct rdt_resource *r, int closid) msr_param.res = r; list_for_each_entry(d, &r->domains, list) { - cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask); - d->cbm[msr_param.low] = r->tmp_cbms[idx++]; + if (d->have_new_ctrl && d->new_ctrl != d->ctrl_val[closid]) { + cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask); + d->ctrl_val[closid] = d->new_ctrl; + } } + if (cpumask_empty(cpu_mask)) + goto done; cpu = get_cpu(); /* Update CBM on this cpu if it's in cpu_mask. */ if (cpumask_test_cpu(cpu, cpu_mask)) - rdt_cbm_update(&msr_param); + rdt_ctrl_update(&msr_param); /* Update CBM on other cpus. */ - smp_call_function_many(cpu_mask, rdt_cbm_update, &msr_param, 1); + smp_call_function_many(cpu_mask, rdt_ctrl_update, &msr_param, 1); put_cpu(); +done: free_cpumask_var(cpu_mask); return 0; } +static int rdtgroup_parse_resource(char *resname, char *tok, int closid) +{ + struct rdt_resource *r; + + for_each_enabled_rdt_resource(r) { + if (!strcmp(resname, r->name) && closid < r->num_closid) + return parse_line(tok, r); + } + return -EINVAL; +} + ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { struct rdtgroup *rdtgrp; + struct rdt_domain *dom; struct rdt_resource *r; char *tok, *resname; int closid, ret = 0; - u32 *l3_cbms = NULL; /* Valid input requires a trailing newline */ if (nbytes == 0 || buf[nbytes - 1] != '\n') @@ -153,44 +221,20 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, closid = rdtgrp->closid; - /* get scratch space to save all the masks while we validate input */ for_each_enabled_rdt_resource(r) { - r->tmp_cbms = kcalloc(r->num_domains, sizeof(*l3_cbms), - GFP_KERNEL); - if (!r->tmp_cbms) { - ret = -ENOMEM; - goto out; - } - r->num_tmp_cbms = 0; + list_for_each_entry(dom, &r->domains, list) + dom->have_new_ctrl = false; } while ((tok = strsep(&buf, "\n")) != NULL) { - resname = strsep(&tok, ":"); + resname = strim(strsep(&tok, ":")); if (!tok) { ret = -EINVAL; goto out; } - for_each_enabled_rdt_resource(r) { - if (!strcmp(resname, r->name) && - closid < r->num_closid) { - ret = parse_line(tok, r); - if (ret) - goto out; - break; - } - } - if (!r->name) { - ret = -EINVAL; - goto out; - } - } - - /* Did the parser find all the masks we need? */ - for_each_enabled_rdt_resource(r) { - if (r->num_tmp_cbms != r->num_domains) { - ret = -EINVAL; + ret = rdtgroup_parse_resource(resname, tok, closid); + if (ret) goto out; - } } for_each_enabled_rdt_resource(r) { @@ -201,10 +245,6 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, out: rdtgroup_kn_unlock(of->kn); - for_each_enabled_rdt_resource(r) { - kfree(r->tmp_cbms); - r->tmp_cbms = NULL; - } return ret ?: nbytes; } @@ -213,11 +253,12 @@ static void show_doms(struct seq_file *s, struct rdt_resource *r, int closid) struct rdt_domain *dom; bool sep = false; - seq_printf(s, "%s:", r->name); + seq_printf(s, "%*s:", max_name_width, r->name); list_for_each_entry(dom, &r->domains, list) { if (sep) seq_puts(s, ";"); - seq_printf(s, "%d=%x", dom->id, dom->cbm[closid]); + seq_printf(s, r->format_str, dom->id, max_data_width, + dom->ctrl_val[closid]); sep = true; } seq_puts(s, "\n"); diff --git a/arch/x86/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile index a3311c886194..43051f0777d4 100644 --- a/arch/x86/kernel/cpu/mcheck/Makefile +++ b/arch/x86/kernel/cpu/mcheck/Makefile @@ -9,3 +9,5 @@ obj-$(CONFIG_X86_MCE_INJECT) += mce-inject.o obj-$(CONFIG_X86_THERMAL_VECTOR) += therm_throt.o obj-$(CONFIG_ACPI_APEI) += mce-apei.o + +obj-$(CONFIG_X86_MCELOG_LEGACY) += dev-mcelog.o diff --git a/arch/x86/kernel/cpu/mcheck/dev-mcelog.c b/arch/x86/kernel/cpu/mcheck/dev-mcelog.c new file mode 100644 index 000000000000..9c632cb88546 --- /dev/null +++ b/arch/x86/kernel/cpu/mcheck/dev-mcelog.c @@ -0,0 +1,397 @@ +/* + * /dev/mcelog driver + * + * K8 parts Copyright 2002,2003 Andi Kleen, SuSE Labs. + * Rest from unknown author(s). + * 2004 Andi Kleen. Rewrote most of it. + * Copyright 2008 Intel Corporation + * Author: Andi Kleen + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/miscdevice.h> +#include <linux/slab.h> +#include <linux/kmod.h> +#include <linux/poll.h> + +#include "mce-internal.h" + +static DEFINE_MUTEX(mce_chrdev_read_mutex); + +static char mce_helper[128]; +static char *mce_helper_argv[2] = { mce_helper, NULL }; + +#define mce_log_get_idx_check(p) \ +({ \ + RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held() && \ + !lockdep_is_held(&mce_chrdev_read_mutex), \ + "suspicious mce_log_get_idx_check() usage"); \ + smp_load_acquire(&(p)); \ +}) + +/* + * Lockless MCE logging infrastructure. + * This avoids deadlocks on printk locks without having to break locks. Also + * separate MCEs from kernel messages to avoid bogus bug reports. + */ + +static struct mce_log_buffer mcelog = { + .signature = MCE_LOG_SIGNATURE, + .len = MCE_LOG_LEN, + .recordlen = sizeof(struct mce), +}; + +static DECLARE_WAIT_QUEUE_HEAD(mce_chrdev_wait); + +/* User mode helper program triggered by machine check event */ +extern char mce_helper[128]; + +static int dev_mce_log(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct mce *mce = (struct mce *)data; + unsigned int next, entry; + + wmb(); + for (;;) { + entry = mce_log_get_idx_check(mcelog.next); + for (;;) { + + /* + * When the buffer fills up discard new entries. + * Assume that the earlier errors are the more + * interesting ones: + */ + if (entry >= MCE_LOG_LEN) { + set_bit(MCE_OVERFLOW, + (unsigned long *)&mcelog.flags); + return NOTIFY_OK; + } + /* Old left over entry. Skip: */ + if (mcelog.entry[entry].finished) { + entry++; + continue; + } + break; + } + smp_rmb(); + next = entry + 1; + if (cmpxchg(&mcelog.next, entry, next) == entry) + break; + } + memcpy(mcelog.entry + entry, mce, sizeof(struct mce)); + wmb(); + mcelog.entry[entry].finished = 1; + wmb(); + + /* wake processes polling /dev/mcelog */ + wake_up_interruptible(&mce_chrdev_wait); + + return NOTIFY_OK; +} + +static struct notifier_block dev_mcelog_nb = { + .notifier_call = dev_mce_log, + .priority = MCE_PRIO_MCELOG, +}; + +static void mce_do_trigger(struct work_struct *work) +{ + call_usermodehelper(mce_helper, mce_helper_argv, NULL, UMH_NO_WAIT); +} + +static DECLARE_WORK(mce_trigger_work, mce_do_trigger); + + +void mce_work_trigger(void) +{ + if (mce_helper[0]) + schedule_work(&mce_trigger_work); +} + +static ssize_t +show_trigger(struct device *s, struct device_attribute *attr, char *buf) +{ + strcpy(buf, mce_helper); + strcat(buf, "\n"); + return strlen(mce_helper) + 1; +} + +static ssize_t set_trigger(struct device *s, struct device_attribute *attr, + const char *buf, size_t siz) +{ + char *p; + + strncpy(mce_helper, buf, sizeof(mce_helper)); + mce_helper[sizeof(mce_helper)-1] = 0; + p = strchr(mce_helper, '\n'); + + if (p) + *p = 0; + + return strlen(mce_helper) + !!p; +} + +DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger); + +/* + * mce_chrdev: Character device /dev/mcelog to read and clear the MCE log. + */ + +static DEFINE_SPINLOCK(mce_chrdev_state_lock); +static int mce_chrdev_open_count; /* #times opened */ +static int mce_chrdev_open_exclu; /* already open exclusive? */ + +static int mce_chrdev_open(struct inode *inode, struct file *file) +{ + spin_lock(&mce_chrdev_state_lock); + + if (mce_chrdev_open_exclu || + (mce_chrdev_open_count && (file->f_flags & O_EXCL))) { + spin_unlock(&mce_chrdev_state_lock); + + return -EBUSY; + } + + if (file->f_flags & O_EXCL) + mce_chrdev_open_exclu = 1; + mce_chrdev_open_count++; + + spin_unlock(&mce_chrdev_state_lock); + + return nonseekable_open(inode, file); +} + +static int mce_chrdev_release(struct inode *inode, struct file *file) +{ + spin_lock(&mce_chrdev_state_lock); + + mce_chrdev_open_count--; + mce_chrdev_open_exclu = 0; + + spin_unlock(&mce_chrdev_state_lock); + + return 0; +} + +static void collect_tscs(void *data) +{ + unsigned long *cpu_tsc = (unsigned long *)data; + + cpu_tsc[smp_processor_id()] = rdtsc(); +} + +static int mce_apei_read_done; + +/* Collect MCE record of previous boot in persistent storage via APEI ERST. */ +static int __mce_read_apei(char __user **ubuf, size_t usize) +{ + int rc; + u64 record_id; + struct mce m; + + if (usize < sizeof(struct mce)) + return -EINVAL; + + rc = apei_read_mce(&m, &record_id); + /* Error or no more MCE record */ + if (rc <= 0) { + mce_apei_read_done = 1; + /* + * When ERST is disabled, mce_chrdev_read() should return + * "no record" instead of "no device." + */ + if (rc == -ENODEV) + return 0; + return rc; + } + rc = -EFAULT; + if (copy_to_user(*ubuf, &m, sizeof(struct mce))) + return rc; + /* + * In fact, we should have cleared the record after that has + * been flushed to the disk or sent to network in + * /sbin/mcelog, but we have no interface to support that now, + * so just clear it to avoid duplication. + */ + rc = apei_clear_mce(record_id); + if (rc) { + mce_apei_read_done = 1; + return rc; + } + *ubuf += sizeof(struct mce); + + return 0; +} + +static ssize_t mce_chrdev_read(struct file *filp, char __user *ubuf, + size_t usize, loff_t *off) +{ + char __user *buf = ubuf; + unsigned long *cpu_tsc; + unsigned prev, next; + int i, err; + + cpu_tsc = kmalloc(nr_cpu_ids * sizeof(long), GFP_KERNEL); + if (!cpu_tsc) + return -ENOMEM; + + mutex_lock(&mce_chrdev_read_mutex); + + if (!mce_apei_read_done) { + err = __mce_read_apei(&buf, usize); + if (err || buf != ubuf) + goto out; + } + + next = mce_log_get_idx_check(mcelog.next); + + /* Only supports full reads right now */ + err = -EINVAL; + if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) + goto out; + + err = 0; + prev = 0; + do { + for (i = prev; i < next; i++) { + unsigned long start = jiffies; + struct mce *m = &mcelog.entry[i]; + + while (!m->finished) { + if (time_after_eq(jiffies, start + 2)) { + memset(m, 0, sizeof(*m)); + goto timeout; + } + cpu_relax(); + } + smp_rmb(); + err |= copy_to_user(buf, m, sizeof(*m)); + buf += sizeof(*m); +timeout: + ; + } + + memset(mcelog.entry + prev, 0, + (next - prev) * sizeof(struct mce)); + prev = next; + next = cmpxchg(&mcelog.next, prev, 0); + } while (next != prev); + + synchronize_sched(); + + /* + * Collect entries that were still getting written before the + * synchronize. + */ + on_each_cpu(collect_tscs, cpu_tsc, 1); + + for (i = next; i < MCE_LOG_LEN; i++) { + struct mce *m = &mcelog.entry[i]; + + if (m->finished && m->tsc < cpu_tsc[m->cpu]) { + err |= copy_to_user(buf, m, sizeof(*m)); + smp_rmb(); + buf += sizeof(*m); + memset(m, 0, sizeof(*m)); + } + } + + if (err) + err = -EFAULT; + +out: + mutex_unlock(&mce_chrdev_read_mutex); + kfree(cpu_tsc); + + return err ? err : buf - ubuf; +} + +static unsigned int mce_chrdev_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &mce_chrdev_wait, wait); + if (READ_ONCE(mcelog.next)) + return POLLIN | POLLRDNORM; + if (!mce_apei_read_done && apei_check_mce()) + return POLLIN | POLLRDNORM; + return 0; +} + +static long mce_chrdev_ioctl(struct file *f, unsigned int cmd, + unsigned long arg) +{ + int __user *p = (int __user *)arg; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + switch (cmd) { + case MCE_GET_RECORD_LEN: + return put_user(sizeof(struct mce), p); + case MCE_GET_LOG_LEN: + return put_user(MCE_LOG_LEN, p); + case MCE_GETCLEAR_FLAGS: { + unsigned flags; + + do { + flags = mcelog.flags; + } while (cmpxchg(&mcelog.flags, flags, 0) != flags); + + return put_user(flags, p); + } + default: + return -ENOTTY; + } +} + +static ssize_t (*mce_write)(struct file *filp, const char __user *ubuf, + size_t usize, loff_t *off); + +void register_mce_write_callback(ssize_t (*fn)(struct file *filp, + const char __user *ubuf, + size_t usize, loff_t *off)) +{ + mce_write = fn; +} +EXPORT_SYMBOL_GPL(register_mce_write_callback); + +static ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf, + size_t usize, loff_t *off) +{ + if (mce_write) + return mce_write(filp, ubuf, usize, off); + else + return -EINVAL; +} + +static const struct file_operations mce_chrdev_ops = { + .open = mce_chrdev_open, + .release = mce_chrdev_release, + .read = mce_chrdev_read, + .write = mce_chrdev_write, + .poll = mce_chrdev_poll, + .unlocked_ioctl = mce_chrdev_ioctl, + .llseek = no_llseek, +}; + +static struct miscdevice mce_chrdev_device = { + MISC_MCELOG_MINOR, + "mcelog", + &mce_chrdev_ops, +}; + +static __init int dev_mcelog_init_device(void) +{ + int err; + + /* register character device /dev/mcelog */ + err = misc_register(&mce_chrdev_device); + if (err) { + pr_err("Unable to init device /dev/mcelog (rc: %d)\n", err); + return err; + } + mce_register_decode_chain(&dev_mcelog_nb); + return 0; +} +device_initcall_sync(dev_mcelog_init_device); diff --git a/arch/x86/kernel/cpu/mcheck/mce-genpool.c b/arch/x86/kernel/cpu/mcheck/mce-genpool.c index 1e5a50c11d3c..217cd4449bc9 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-genpool.c +++ b/arch/x86/kernel/cpu/mcheck/mce-genpool.c @@ -85,7 +85,7 @@ void mce_gen_pool_process(struct work_struct *__unused) head = llist_reverse_order(head); llist_for_each_entry_safe(node, tmp, head, llnode) { mce = &node->mce; - atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce); + blocking_notifier_call_chain(&x86_mce_decoder_chain, 0, mce); gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node)); } } diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h index 903043e6a62b..654ad0668d72 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-internal.h +++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h @@ -13,7 +13,7 @@ enum severity_level { MCE_PANIC_SEVERITY, }; -extern struct atomic_notifier_head x86_mce_decoder_chain; +extern struct blocking_notifier_head x86_mce_decoder_chain; #define ATTR_LEN 16 #define INITIAL_CHECK_INTERVAL 5 * 60 /* 5 minutes */ @@ -96,3 +96,11 @@ static inline bool mce_cmp(struct mce *m1, struct mce *m2) m1->addr != m2->addr || m1->misc != m2->misc; } + +extern struct device_attribute dev_attr_trigger; + +#ifdef CONFIG_X86_MCELOG_LEGACY +extern void mce_work_trigger(void); +#else +static inline void mce_work_trigger(void) { } +#endif diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 8e9725c607ea..5abd4bf73d6e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -35,6 +35,7 @@ #include <linux/poll.h> #include <linux/nmi.h> #include <linux/cpu.h> +#include <linux/ras.h> #include <linux/smp.h> #include <linux/fs.h> #include <linux/mm.h> @@ -49,18 +50,11 @@ #include <asm/tlbflush.h> #include <asm/mce.h> #include <asm/msr.h> +#include <asm/reboot.h> #include "mce-internal.h" -static DEFINE_MUTEX(mce_chrdev_read_mutex); - -#define mce_log_get_idx_check(p) \ -({ \ - RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held() && \ - !lockdep_is_held(&mce_chrdev_read_mutex), \ - "suspicious mce_log_get_idx_check() usage"); \ - smp_load_acquire(&(p)); \ -}) +static DEFINE_MUTEX(mce_log_mutex); #define CREATE_TRACE_POINTS #include <trace/events/mce.h> @@ -85,15 +79,9 @@ struct mca_config mca_cfg __read_mostly = { .monarch_timeout = -1 }; -/* User mode helper program triggered by machine check event */ -static unsigned long mce_need_notify; -static char mce_helper[128]; -static char *mce_helper_argv[2] = { mce_helper, NULL }; - -static DECLARE_WAIT_QUEUE_HEAD(mce_chrdev_wait); - static DEFINE_PER_CPU(struct mce, mces_seen); -static int cpu_missing; +static unsigned long mce_need_notify; +static int cpu_missing; /* * MCA banks polled by the period polling timer for corrected events. @@ -121,7 +109,7 @@ static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs); * CPU/chipset specific EDAC code can register a notifier call here to print * MCE errors in a human-readable form. */ -ATOMIC_NOTIFIER_HEAD(x86_mce_decoder_chain); +BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain); /* Do initial initialization of a struct mce */ void mce_setup(struct mce *m) @@ -143,82 +131,38 @@ void mce_setup(struct mce *m) DEFINE_PER_CPU(struct mce, injectm); EXPORT_PER_CPU_SYMBOL_GPL(injectm); -/* - * Lockless MCE logging infrastructure. - * This avoids deadlocks on printk locks without having to break locks. Also - * separate MCEs from kernel messages to avoid bogus bug reports. - */ - -static struct mce_log mcelog = { - .signature = MCE_LOG_SIGNATURE, - .len = MCE_LOG_LEN, - .recordlen = sizeof(struct mce), -}; - -void mce_log(struct mce *mce) +void mce_log(struct mce *m) { - unsigned next, entry; - - /* Emit the trace record: */ - trace_mce_record(mce); - - if (!mce_gen_pool_add(mce)) + if (!mce_gen_pool_add(m)) irq_work_queue(&mce_irq_work); - - wmb(); - for (;;) { - entry = mce_log_get_idx_check(mcelog.next); - for (;;) { - - /* - * When the buffer fills up discard new entries. - * Assume that the earlier errors are the more - * interesting ones: - */ - if (entry >= MCE_LOG_LEN) { - set_bit(MCE_OVERFLOW, - (unsigned long *)&mcelog.flags); - return; - } - /* Old left over entry. Skip: */ - if (mcelog.entry[entry].finished) { - entry++; - continue; - } - break; - } - smp_rmb(); - next = entry + 1; - if (cmpxchg(&mcelog.next, entry, next) == entry) - break; - } - memcpy(mcelog.entry + entry, mce, sizeof(struct mce)); - wmb(); - mcelog.entry[entry].finished = 1; - wmb(); - - set_bit(0, &mce_need_notify); } void mce_inject_log(struct mce *m) { - mutex_lock(&mce_chrdev_read_mutex); + mutex_lock(&mce_log_mutex); mce_log(m); - mutex_unlock(&mce_chrdev_read_mutex); + mutex_unlock(&mce_log_mutex); } EXPORT_SYMBOL_GPL(mce_inject_log); static struct notifier_block mce_srao_nb; +/* + * We run the default notifier if we have only the SRAO, the first and the + * default notifier registered. I.e., the mandatory NUM_DEFAULT_NOTIFIERS + * notifiers registered on the chain. + */ +#define NUM_DEFAULT_NOTIFIERS 3 static atomic_t num_notifiers; void mce_register_decode_chain(struct notifier_block *nb) { - atomic_inc(&num_notifiers); + if (WARN_ON(nb->priority > MCE_PRIO_MCELOG && nb->priority < MCE_PRIO_EDAC)) + return; - WARN_ON(nb->priority > MCE_PRIO_LOWEST && nb->priority < MCE_PRIO_EDAC); + atomic_inc(&num_notifiers); - atomic_notifier_chain_register(&x86_mce_decoder_chain, nb); + blocking_notifier_chain_register(&x86_mce_decoder_chain, nb); } EXPORT_SYMBOL_GPL(mce_register_decode_chain); @@ -226,7 +170,7 @@ void mce_unregister_decode_chain(struct notifier_block *nb) { atomic_dec(&num_notifiers); - atomic_notifier_chain_unregister(&x86_mce_decoder_chain, nb); + blocking_notifier_chain_unregister(&x86_mce_decoder_chain, nb); } EXPORT_SYMBOL_GPL(mce_unregister_decode_chain); @@ -319,18 +263,7 @@ static void __print_mce(struct mce *m) static void print_mce(struct mce *m) { - int ret = 0; - __print_mce(m); - - /* - * Print out human-readable details about the MCE error, - * (if the CPU has an implementation for that) - */ - ret = atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m); - if (ret == NOTIFY_STOP) - return; - pr_emerg_ratelimited(HW_ERR "Run the above through 'mcelog --ascii'\n"); } @@ -519,7 +452,6 @@ static void mce_schedule_work(void) static void mce_irq_work_cb(struct irq_work *entry) { - mce_notify_irq(); mce_schedule_work(); } @@ -548,20 +480,97 @@ static void mce_report_event(struct pt_regs *regs) */ static int mce_usable_address(struct mce *m) { - if (!(m->status & MCI_STATUS_MISCV) || !(m->status & MCI_STATUS_ADDRV)) + if (!(m->status & MCI_STATUS_ADDRV)) return 0; /* Checks after this one are Intel-specific: */ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) return 1; + if (!(m->status & MCI_STATUS_MISCV)) + return 0; + if (MCI_MISC_ADDR_LSB(m->misc) > PAGE_SHIFT) return 0; + if (MCI_MISC_ADDR_MODE(m->misc) != MCI_MISC_ADDR_PHYS) return 0; + return 1; } +static bool memory_error(struct mce *m) +{ + struct cpuinfo_x86 *c = &boot_cpu_data; + + if (c->x86_vendor == X86_VENDOR_AMD) { + /* ErrCodeExt[20:16] */ + u8 xec = (m->status >> 16) & 0x1f; + + return (xec == 0x0 || xec == 0x8); + } else if (c->x86_vendor == X86_VENDOR_INTEL) { + /* + * Intel SDM Volume 3B - 15.9.2 Compound Error Codes + * + * Bit 7 of the MCACOD field of IA32_MCi_STATUS is used for + * indicating a memory error. Bit 8 is used for indicating a + * cache hierarchy error. The combination of bit 2 and bit 3 + * is used for indicating a `generic' cache hierarchy error + * But we can't just blindly check the above bits, because if + * bit 11 is set, then it is a bus/interconnect error - and + * either way the above bits just gives more detail on what + * bus/interconnect error happened. Note that bit 12 can be + * ignored, as it's the "filter" bit. + */ + return (m->status & 0xef80) == BIT(7) || + (m->status & 0xef00) == BIT(8) || + (m->status & 0xeffc) == 0xc; + } + + return false; +} + +static bool cec_add_mce(struct mce *m) +{ + if (!m) + return false; + + /* We eat only correctable DRAM errors with usable addresses. */ + if (memory_error(m) && + !(m->status & MCI_STATUS_UC) && + mce_usable_address(m)) + if (!cec_add_elem(m->addr >> PAGE_SHIFT)) + return true; + + return false; +} + +static int mce_first_notifier(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct mce *m = (struct mce *)data; + + if (!m) + return NOTIFY_DONE; + + if (cec_add_mce(m)) + return NOTIFY_STOP; + + /* Emit the trace record: */ + trace_mce_record(m); + + set_bit(0, &mce_need_notify); + + mce_notify_irq(); + + return NOTIFY_DONE; +} + +static struct notifier_block first_nb = { + .notifier_call = mce_first_notifier, + .priority = MCE_PRIO_FIRST, +}; + static int srao_decode_notifier(struct notifier_block *nb, unsigned long val, void *data) { @@ -591,11 +600,7 @@ static int mce_default_notifier(struct notifier_block *nb, unsigned long val, if (!m) return NOTIFY_DONE; - /* - * Run the default notifier if we have only the SRAO - * notifier and us registered. - */ - if (atomic_read(&num_notifiers) > 2) + if (atomic_read(&num_notifiers) > NUM_DEFAULT_NOTIFIERS) return NOTIFY_DONE; __print_mce(m); @@ -648,37 +653,6 @@ static void mce_read_aux(struct mce *m, int i) } } -static bool memory_error(struct mce *m) -{ - struct cpuinfo_x86 *c = &boot_cpu_data; - - if (c->x86_vendor == X86_VENDOR_AMD) { - /* ErrCodeExt[20:16] */ - u8 xec = (m->status >> 16) & 0x1f; - - return (xec == 0x0 || xec == 0x8); - } else if (c->x86_vendor == X86_VENDOR_INTEL) { - /* - * Intel SDM Volume 3B - 15.9.2 Compound Error Codes - * - * Bit 7 of the MCACOD field of IA32_MCi_STATUS is used for - * indicating a memory error. Bit 8 is used for indicating a - * cache hierarchy error. The combination of bit 2 and bit 3 - * is used for indicating a `generic' cache hierarchy error - * But we can't just blindly check the above bits, because if - * bit 11 is set, then it is a bus/interconnect error - and - * either way the above bits just gives more detail on what - * bus/interconnect error happened. Note that bit 12 can be - * ignored, as it's the "filter" bit. - */ - return (m->status & 0xef80) == BIT(7) || - (m->status & 0xef00) == BIT(8) || - (m->status & 0xeffc) == 0xc; - } - - return false; -} - DEFINE_PER_CPU(unsigned, mce_poll_count); /* @@ -1127,9 +1101,22 @@ void do_machine_check(struct pt_regs *regs, long error_code) * on Intel. */ int lmce = 1; + int cpu = smp_processor_id(); - /* If this CPU is offline, just bail out. */ - if (cpu_is_offline(smp_processor_id())) { + /* + * Cases where we avoid rendezvous handler timeout: + * 1) If this CPU is offline. + * + * 2) If crashing_cpu was set, e.g. we're entering kdump and we need to + * skip those CPUs which remain looping in the 1st kernel - see + * crash_nmi_callback(). + * + * Note: there still is a small window between kexec-ing and the new, + * kdump kernel establishing a new #MC handler where a broadcasted MCE + * might not get handled properly. + */ + if (cpu_is_offline(cpu) || + (crashing_cpu != -1 && crashing_cpu != cpu)) { u64 mcgstatus; mcgstatus = mce_rdmsrl(MSR_IA32_MCG_STATUS); @@ -1399,13 +1386,6 @@ static void mce_timer_delete_all(void) del_timer_sync(&per_cpu(mce_timer, cpu)); } -static void mce_do_trigger(struct work_struct *work) -{ - call_usermodehelper(mce_helper, mce_helper_argv, NULL, UMH_NO_WAIT); -} - -static DECLARE_WORK(mce_trigger_work, mce_do_trigger); - /* * Notify the user(s) about new machine check events. * Can be called from interrupt context, but not from machine check/NMI @@ -1417,11 +1397,7 @@ int mce_notify_irq(void) static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2); if (test_and_clear_bit(0, &mce_need_notify)) { - /* wake processes polling /dev/mcelog */ - wake_up_interruptible(&mce_chrdev_wait); - - if (mce_helper[0]) - schedule_work(&mce_trigger_work); + mce_work_trigger(); if (__ratelimit(&ratelimit)) pr_info(HW_ERR "Machine check events logged\n"); @@ -1688,30 +1664,35 @@ static int __mcheck_cpu_ancient_init(struct cpuinfo_x86 *c) return 0; } -static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c) +/* + * Init basic CPU features needed for early decoding of MCEs. + */ +static void __mcheck_cpu_init_early(struct cpuinfo_x86 *c) { - switch (c->x86_vendor) { - case X86_VENDOR_INTEL: - mce_intel_feature_init(c); - mce_adjust_timer = cmci_intel_adjust_timer; - break; - - case X86_VENDOR_AMD: { + if (c->x86_vendor == X86_VENDOR_AMD) { mce_flags.overflow_recov = !!cpu_has(c, X86_FEATURE_OVERFLOW_RECOV); mce_flags.succor = !!cpu_has(c, X86_FEATURE_SUCCOR); mce_flags.smca = !!cpu_has(c, X86_FEATURE_SMCA); - /* - * Install proper ops for Scalable MCA enabled processors - */ if (mce_flags.smca) { msr_ops.ctl = smca_ctl_reg; msr_ops.status = smca_status_reg; msr_ops.addr = smca_addr_reg; msr_ops.misc = smca_misc_reg; } - mce_amd_feature_init(c); + } +} + +static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c) +{ + switch (c->x86_vendor) { + case X86_VENDOR_INTEL: + mce_intel_feature_init(c); + mce_adjust_timer = cmci_intel_adjust_timer; + break; + case X86_VENDOR_AMD: { + mce_amd_feature_init(c); break; } @@ -1798,6 +1779,7 @@ void mcheck_cpu_init(struct cpuinfo_x86 *c) machine_check_vector = do_machine_check; + __mcheck_cpu_init_early(c); __mcheck_cpu_init_generic(); __mcheck_cpu_init_vendor(c); __mcheck_cpu_init_clear_banks(); @@ -1823,252 +1805,6 @@ void mcheck_cpu_clear(struct cpuinfo_x86 *c) } -/* - * mce_chrdev: Character device /dev/mcelog to read and clear the MCE log. - */ - -static DEFINE_SPINLOCK(mce_chrdev_state_lock); -static int mce_chrdev_open_count; /* #times opened */ -static int mce_chrdev_open_exclu; /* already open exclusive? */ - -static int mce_chrdev_open(struct inode *inode, struct file *file) -{ - spin_lock(&mce_chrdev_state_lock); - - if (mce_chrdev_open_exclu || - (mce_chrdev_open_count && (file->f_flags & O_EXCL))) { - spin_unlock(&mce_chrdev_state_lock); - - return -EBUSY; - } - - if (file->f_flags & O_EXCL) - mce_chrdev_open_exclu = 1; - mce_chrdev_open_count++; - - spin_unlock(&mce_chrdev_state_lock); - - return nonseekable_open(inode, file); -} - -static int mce_chrdev_release(struct inode *inode, struct file *file) -{ - spin_lock(&mce_chrdev_state_lock); - - mce_chrdev_open_count--; - mce_chrdev_open_exclu = 0; - - spin_unlock(&mce_chrdev_state_lock); - - return 0; -} - -static void collect_tscs(void *data) -{ - unsigned long *cpu_tsc = (unsigned long *)data; - - cpu_tsc[smp_processor_id()] = rdtsc(); -} - -static int mce_apei_read_done; - -/* Collect MCE record of previous boot in persistent storage via APEI ERST. */ -static int __mce_read_apei(char __user **ubuf, size_t usize) -{ - int rc; - u64 record_id; - struct mce m; - - if (usize < sizeof(struct mce)) - return -EINVAL; - - rc = apei_read_mce(&m, &record_id); - /* Error or no more MCE record */ - if (rc <= 0) { - mce_apei_read_done = 1; - /* - * When ERST is disabled, mce_chrdev_read() should return - * "no record" instead of "no device." - */ - if (rc == -ENODEV) - return 0; - return rc; - } - rc = -EFAULT; - if (copy_to_user(*ubuf, &m, sizeof(struct mce))) - return rc; - /* - * In fact, we should have cleared the record after that has - * been flushed to the disk or sent to network in - * /sbin/mcelog, but we have no interface to support that now, - * so just clear it to avoid duplication. - */ - rc = apei_clear_mce(record_id); - if (rc) { - mce_apei_read_done = 1; - return rc; - } - *ubuf += sizeof(struct mce); - - return 0; -} - -static ssize_t mce_chrdev_read(struct file *filp, char __user *ubuf, - size_t usize, loff_t *off) -{ - char __user *buf = ubuf; - unsigned long *cpu_tsc; - unsigned prev, next; - int i, err; - - cpu_tsc = kmalloc(nr_cpu_ids * sizeof(long), GFP_KERNEL); - if (!cpu_tsc) - return -ENOMEM; - - mutex_lock(&mce_chrdev_read_mutex); - - if (!mce_apei_read_done) { - err = __mce_read_apei(&buf, usize); - if (err || buf != ubuf) - goto out; - } - - next = mce_log_get_idx_check(mcelog.next); - - /* Only supports full reads right now */ - err = -EINVAL; - if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) - goto out; - - err = 0; - prev = 0; - do { - for (i = prev; i < next; i++) { - unsigned long start = jiffies; - struct mce *m = &mcelog.entry[i]; - - while (!m->finished) { - if (time_after_eq(jiffies, start + 2)) { - memset(m, 0, sizeof(*m)); - goto timeout; - } - cpu_relax(); - } - smp_rmb(); - err |= copy_to_user(buf, m, sizeof(*m)); - buf += sizeof(*m); -timeout: - ; - } - - memset(mcelog.entry + prev, 0, - (next - prev) * sizeof(struct mce)); - prev = next; - next = cmpxchg(&mcelog.next, prev, 0); - } while (next != prev); - - synchronize_sched(); - - /* - * Collect entries that were still getting written before the - * synchronize. - */ - on_each_cpu(collect_tscs, cpu_tsc, 1); - - for (i = next; i < MCE_LOG_LEN; i++) { - struct mce *m = &mcelog.entry[i]; - - if (m->finished && m->tsc < cpu_tsc[m->cpu]) { - err |= copy_to_user(buf, m, sizeof(*m)); - smp_rmb(); - buf += sizeof(*m); - memset(m, 0, sizeof(*m)); - } - } - - if (err) - err = -EFAULT; - -out: - mutex_unlock(&mce_chrdev_read_mutex); - kfree(cpu_tsc); - - return err ? err : buf - ubuf; -} - -static unsigned int mce_chrdev_poll(struct file *file, poll_table *wait) -{ - poll_wait(file, &mce_chrdev_wait, wait); - if (READ_ONCE(mcelog.next)) - return POLLIN | POLLRDNORM; - if (!mce_apei_read_done && apei_check_mce()) - return POLLIN | POLLRDNORM; - return 0; -} - -static long mce_chrdev_ioctl(struct file *f, unsigned int cmd, - unsigned long arg) -{ - int __user *p = (int __user *)arg; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - switch (cmd) { - case MCE_GET_RECORD_LEN: - return put_user(sizeof(struct mce), p); - case MCE_GET_LOG_LEN: - return put_user(MCE_LOG_LEN, p); - case MCE_GETCLEAR_FLAGS: { - unsigned flags; - - do { - flags = mcelog.flags; - } while (cmpxchg(&mcelog.flags, flags, 0) != flags); - - return put_user(flags, p); - } - default: - return -ENOTTY; - } -} - -static ssize_t (*mce_write)(struct file *filp, const char __user *ubuf, - size_t usize, loff_t *off); - -void register_mce_write_callback(ssize_t (*fn)(struct file *filp, - const char __user *ubuf, - size_t usize, loff_t *off)) -{ - mce_write = fn; -} -EXPORT_SYMBOL_GPL(register_mce_write_callback); - -static ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf, - size_t usize, loff_t *off) -{ - if (mce_write) - return mce_write(filp, ubuf, usize, off); - else - return -EINVAL; -} - -static const struct file_operations mce_chrdev_ops = { - .open = mce_chrdev_open, - .release = mce_chrdev_release, - .read = mce_chrdev_read, - .write = mce_chrdev_write, - .poll = mce_chrdev_poll, - .unlocked_ioctl = mce_chrdev_ioctl, - .llseek = no_llseek, -}; - -static struct miscdevice mce_chrdev_device = { - MISC_MCELOG_MINOR, - "mcelog", - &mce_chrdev_ops, -}; - static void __mce_disable_bank(void *arg) { int bank = *((int *)arg); @@ -2142,6 +1878,7 @@ __setup("mce", mcheck_enable); int __init mcheck_init(void) { mcheck_intel_therm_init(); + mce_register_decode_chain(&first_nb); mce_register_decode_chain(&mce_srao_nb); mce_register_decode_chain(&mce_default_nb); mcheck_vendor_init_severity(); @@ -2286,29 +2023,6 @@ static ssize_t set_bank(struct device *s, struct device_attribute *attr, return size; } -static ssize_t -show_trigger(struct device *s, struct device_attribute *attr, char *buf) -{ - strcpy(buf, mce_helper); - strcat(buf, "\n"); - return strlen(mce_helper) + 1; -} - -static ssize_t set_trigger(struct device *s, struct device_attribute *attr, - const char *buf, size_t siz) -{ - char *p; - - strncpy(mce_helper, buf, sizeof(mce_helper)); - mce_helper[sizeof(mce_helper)-1] = 0; - p = strchr(mce_helper, '\n'); - - if (p) - *p = 0; - - return strlen(mce_helper) + !!p; -} - static ssize_t set_ignore_ce(struct device *s, struct device_attribute *attr, const char *buf, size_t size) @@ -2365,7 +2079,6 @@ static ssize_t store_int_with_restart(struct device *s, return ret; } -static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger); static DEVICE_INT_ATTR(tolerant, 0644, mca_cfg.tolerant); static DEVICE_INT_ATTR(monarch_timeout, 0644, mca_cfg.monarch_timeout); static DEVICE_BOOL_ATTR(dont_log_ce, 0644, mca_cfg.dont_log_ce); @@ -2388,7 +2101,9 @@ static struct dev_ext_attribute dev_attr_cmci_disabled = { static struct device_attribute *mce_device_attrs[] = { &dev_attr_tolerant.attr, &dev_attr_check_interval.attr, +#ifdef CONFIG_X86_MCELOG_LEGACY &dev_attr_trigger, +#endif &dev_attr_monarch_timeout.attr, &dev_attr_dont_log_ce.attr, &dev_attr_ignore_ce.attr, @@ -2562,7 +2277,6 @@ static __init void mce_init_banks(void) static __init int mcheck_init_device(void) { - enum cpuhp_state hp_online; int err; if (!mce_available(&boot_cpu_data)) { @@ -2590,21 +2304,11 @@ static __init int mcheck_init_device(void) mce_cpu_online, mce_cpu_pre_down); if (err < 0) goto err_out_online; - hp_online = err; register_syscore_ops(&mce_syscore_ops); - /* register character device /dev/mcelog */ - err = misc_register(&mce_chrdev_device); - if (err) - goto err_register; - return 0; -err_register: - unregister_syscore_ops(&mce_syscore_ops); - cpuhp_remove_state(hp_online); - err_out_online: cpuhp_remove_state(CPUHP_X86_MCE_DEAD); @@ -2612,7 +2316,7 @@ err_out_mem: free_cpumask_var(mce_device_initialized); err_out: - pr_err("Unable to init device /dev/mcelog (rc: %d)\n", err); + pr_err("Unable to init MCE device (rc: %d)\n", err); return err; } @@ -2691,6 +2395,7 @@ static int __init mcheck_late_init(void) static_branch_inc(&mcsafe_key); mcheck_debugfs_init(); + cec_init(); /* * Flush out everything that has been logged during early boot, now that diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 524cc5780a77..6e4a047e4b68 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -60,7 +60,7 @@ static const char * const th_names[] = { "load_store", "insn_fetch", "combined_unit", - "", + "decode_unit", "northbridge", "execution_unit", }; diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index 190b3e6cef4d..e84db79ef272 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c @@ -481,6 +481,9 @@ static void intel_ppin_init(struct cpuinfo_x86 *c) case INTEL_FAM6_BROADWELL_XEON_D: case INTEL_FAM6_BROADWELL_X: case INTEL_FAM6_SKYLAKE_X: + case INTEL_FAM6_XEON_PHI_KNL: + case INTEL_FAM6_XEON_PHI_KNM: + if (rdmsrl_safe(MSR_PPIN_CTL, &val)) return; diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c index 3b442b64c72d..765afd599039 100644 --- a/arch/x86/kernel/cpu/mtrr/cleanup.c +++ b/arch/x86/kernel/cpu/mtrr/cleanup.c @@ -27,7 +27,7 @@ #include <linux/range.h> #include <asm/processor.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/mtrr.h> #include <asm/msr.h> @@ -860,7 +860,7 @@ real_trim_memory(unsigned long start_pfn, unsigned long limit_pfn) trim_size <<= PAGE_SHIFT; trim_size -= trim_start; - return e820_update_range(trim_start, trim_size, E820_RAM, E820_RESERVED); + return e820__range_update(trim_start, trim_size, E820_TYPE_RAM, E820_TYPE_RESERVED); } /** @@ -978,7 +978,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) WARN_ON(1); pr_info("update e820 for mtrr\n"); - update_e820(); + e820__update_table_print(); return 1; } diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 24e87e74990d..2bce84d91c2b 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -48,7 +48,7 @@ #include <linux/syscore_ops.h> #include <asm/cpufeature.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/mtrr.h> #include <asm/msr.h> #include <asm/pat.h> diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index 18ca99f2798b..6df621ae62a7 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c @@ -31,14 +31,13 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) "fpu\t\t: %s\n" "fpu_exception\t: %s\n" "cpuid level\t: %d\n" - "wp\t\t: %s\n", + "wp\t\t: yes\n", static_cpu_has_bug(X86_BUG_FDIV) ? "yes" : "no", static_cpu_has_bug(X86_BUG_F00F) ? "yes" : "no", static_cpu_has_bug(X86_BUG_COMA) ? "yes" : "no", static_cpu_has(X86_FEATURE_FPU) ? "yes" : "no", static_cpu_has(X86_FEATURE_FPU) ? "yes" : "no", - c->cpuid_level, - c->wp_works_ok ? "yes" : "no"); + c->cpuid_level); } #else static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index d9794060fe22..23c23508c012 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -27,6 +27,7 @@ static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_CAT_L3, CPUID_EBX, 1, 0x00000010, 0 }, { X86_FEATURE_CAT_L2, CPUID_EBX, 2, 0x00000010, 0 }, { X86_FEATURE_CDP_L3, CPUID_ECX, 2, 0x00000010, 1 }, + { X86_FEATURE_MBA, CPUID_EBX, 3, 0x00000010, 0 }, { X86_FEATURE_HW_PSTATE, CPUID_EDX, 7, 0x80000007, 0 }, { X86_FEATURE_CPB, CPUID_EDX, 9, 0x80000007, 0 }, { X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 }, diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 3741461c63a0..22217ece26c8 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -29,6 +29,7 @@ #include <asm/nmi.h> #include <asm/hw_irq.h> #include <asm/apic.h> +#include <asm/e820/types.h> #include <asm/io_apic.h> #include <asm/hpet.h> #include <linux/kdebug.h> @@ -503,16 +504,16 @@ static int prepare_elf_headers(struct kimage *image, void **addr, return ret; } -static int add_e820_entry(struct boot_params *params, struct e820entry *entry) +static int add_e820_entry(struct boot_params *params, struct e820_entry *entry) { unsigned int nr_e820_entries; nr_e820_entries = params->e820_entries; - if (nr_e820_entries >= E820MAX) + if (nr_e820_entries >= E820_MAX_ENTRIES_ZEROPAGE) return 1; - memcpy(¶ms->e820_map[nr_e820_entries], entry, - sizeof(struct e820entry)); + memcpy(¶ms->e820_table[nr_e820_entries], entry, + sizeof(struct e820_entry)); params->e820_entries++; return 0; } @@ -521,7 +522,7 @@ static int memmap_entry_callback(u64 start, u64 end, void *arg) { struct crash_memmap_data *cmd = arg; struct boot_params *params = cmd->params; - struct e820entry ei; + struct e820_entry ei; ei.addr = start; ei.size = end - start + 1; @@ -560,7 +561,7 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) { int i, ret = 0; unsigned long flags; - struct e820entry ei; + struct e820_entry ei; struct crash_memmap_data cmd; struct crash_mem *cmem; @@ -574,17 +575,17 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) /* Add first 640K segment */ ei.addr = image->arch.backup_src_start; ei.size = image->arch.backup_src_sz; - ei.type = E820_RAM; + ei.type = E820_TYPE_RAM; add_e820_entry(params, &ei); /* Add ACPI tables */ - cmd.type = E820_ACPI; + cmd.type = E820_TYPE_ACPI; flags = IORESOURCE_MEM | IORESOURCE_BUSY; walk_iomem_res_desc(IORES_DESC_ACPI_TABLES, flags, 0, -1, &cmd, memmap_entry_callback); /* Add ACPI Non-volatile Storage */ - cmd.type = E820_NVS; + cmd.type = E820_TYPE_NVS; walk_iomem_res_desc(IORES_DESC_ACPI_NV_STORAGE, flags, 0, -1, &cmd, memmap_entry_callback); @@ -592,7 +593,7 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) if (crashk_low_res.end) { ei.addr = crashk_low_res.start; ei.size = crashk_low_res.end - crashk_low_res.start + 1; - ei.type = E820_RAM; + ei.type = E820_TYPE_RAM; add_e820_entry(params, &ei); } @@ -609,7 +610,7 @@ int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params) if (ei.size < PAGE_SIZE) continue; ei.addr = cmem->ranges[i].start; - ei.type = E820_RAM; + ei.type = E820_TYPE_RAM; add_e820_entry(params, &ei); } diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 09d4ac0d2661..dbce3cca94cb 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -77,7 +77,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, * - softirq stack * - hardirq stack */ - for (regs = NULL; stack; stack = stack_info.next_sp) { + for (regs = NULL; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { const char *stack_name; /* @@ -289,9 +289,6 @@ void die(const char *str, struct pt_regs *regs, long err) unsigned long flags = oops_begin(); int sig = SIGSEGV; - if (!user_mode(regs)) - report_bug(regs->ip, regs); - if (__die(str, regs, err)) sig = 0; oops_end(flags, regs, sig); diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index b0b3a3df7c20..e5f0b40e66d2 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c @@ -162,15 +162,3 @@ void show_regs(struct pt_regs *regs) } pr_cont("\n"); } - -int is_valid_bugaddr(unsigned long ip) -{ - unsigned short ud2; - - if (ip < PAGE_OFFSET) - return 0; - if (probe_kernel_address((unsigned short *)ip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index a8b117e93b46..3e1471d57487 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -178,13 +178,3 @@ void show_regs(struct pt_regs *regs) } pr_cont("\n"); } - -int is_valid_bugaddr(unsigned long ip) -{ - unsigned short ud2; - - if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2))) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index b2bbad6ebe4d..6e9b26fa6d05 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1,49 +1,55 @@ /* - * Handle the memory map. - * The functions here do the job until bootmem takes over. + * Low level x86 E820 memory map handling functions. * - * Getting sanitize_e820_map() in sync with i386 version by applying change: - * - Provisions for empty E820 memory regions (reported by certain BIOSes). - * Alex Achenbach <xela@slit.de>, December 2002. - * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> + * The firmware and bootloader passes us the "E820 table", which is the primary + * physical memory layout description available about x86 systems. * + * The kernel takes the E820 memory layout and optionally modifies it with + * quirks and other tweaks, and feeds that into the generic Linux memory + * allocation code routines via a platform independent interface (memblock, etc.). */ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/init.h> #include <linux/crash_dump.h> -#include <linux/export.h> #include <linux/bootmem.h> -#include <linux/pfn.h> #include <linux/suspend.h> #include <linux/acpi.h> #include <linux/firmware-map.h> #include <linux/memblock.h> #include <linux/sort.h> -#include <asm/e820.h> -#include <asm/proto.h> +#include <asm/e820/api.h> #include <asm/setup.h> -#include <asm/cpufeature.h> /* - * The e820 map is the map that gets modified e.g. with command line parameters - * and that is also registered with modifications in the kernel resource tree - * with the iomem_resource as parent. + * We organize the E820 table into two main data structures: * - * The e820_saved is directly saved after the BIOS-provided memory map is - * copied. It doesn't get modified afterwards. It's registered for the - * /sys/firmware/memmap interface. + * - 'e820_table_firmware': the original firmware version passed to us by the + * bootloader - not modified by the kernel. We use this to: * - * That memory map is not modified and is used as base for kexec. The kexec'd - * kernel should get the same memory map as the firmware provides. Then the - * user can e.g. boot the original kernel with mem=1G while still booting the - * next kernel with full memory. + * - inform the user about the firmware's notion of memory layout + * via /sys/firmware/memmap + * + * - the hibernation code uses it to generate a kernel-independent MD5 + * fingerprint of the physical memory layout of a system. + * + * - kexec, which is a bootloader in disguise, uses the original E820 + * layout to pass to the kexec-ed kernel. This way the original kernel + * can have a restricted E820 map while the kexec()-ed kexec-kernel + * can have access to full memory - etc. + * + * - 'e820_table': this is the main E820 table that is massaged by the + * low level x86 platform code, or modified by boot parameters, before + * passed on to higher level MM layers. + * + * Once the E820 map has been converted to the standard Linux memory layout + * information its role stops - modifying it has no effect and does not get + * re-propagated. So itsmain role is a temporary bootstrap storage of firmware + * specific memory layout data during early bootup. */ -static struct e820map initial_e820 __initdata; -static struct e820map initial_e820_saved __initdata; -struct e820map *e820 __refdata = &initial_e820; -struct e820map *e820_saved __refdata = &initial_e820_saved; +static struct e820_table e820_table_init __initdata; +static struct e820_table e820_table_firmware_init __initdata; + +struct e820_table *e820_table __refdata = &e820_table_init; +struct e820_table *e820_table_firmware __refdata = &e820_table_firmware_init; /* For PCI or other memory-mapped resources */ unsigned long pci_mem_start = 0xaeedbabe; @@ -55,51 +61,53 @@ EXPORT_SYMBOL(pci_mem_start); * This function checks if any part of the range <start,end> is mapped * with type. */ -int -e820_any_mapped(u64 start, u64 end, unsigned type) +bool e820__mapped_any(u64 start, u64 end, enum e820_type type) { int i; - for (i = 0; i < e820->nr_map; i++) { - struct e820entry *ei = &e820->map[i]; + for (i = 0; i < e820_table->nr_entries; i++) { + struct e820_entry *entry = &e820_table->entries[i]; - if (type && ei->type != type) + if (type && entry->type != type) continue; - if (ei->addr >= end || ei->addr + ei->size <= start) + if (entry->addr >= end || entry->addr + entry->size <= start) continue; return 1; } return 0; } -EXPORT_SYMBOL_GPL(e820_any_mapped); +EXPORT_SYMBOL_GPL(e820__mapped_any); /* - * This function checks if the entire range <start,end> is mapped with type. + * This function checks if the entire <start,end> range is mapped with 'type'. * - * Note: this function only works correct if the e820 table is sorted and - * not-overlapping, which is the case + * Note: this function only works correctly once the E820 table is sorted and + * not-overlapping (at least for the range specified), which is the case normally. */ -int __init e820_all_mapped(u64 start, u64 end, unsigned type) +bool __init e820__mapped_all(u64 start, u64 end, enum e820_type type) { int i; - for (i = 0; i < e820->nr_map; i++) { - struct e820entry *ei = &e820->map[i]; + for (i = 0; i < e820_table->nr_entries; i++) { + struct e820_entry *entry = &e820_table->entries[i]; - if (type && ei->type != type) + if (type && entry->type != type) continue; - /* is the region (part) in overlap with the current region ?*/ - if (ei->addr >= end || ei->addr + ei->size <= start) + + /* Is the region (part) in overlap with the current region? */ + if (entry->addr >= end || entry->addr + entry->size <= start) continue; - /* if the region is at the beginning of <start,end> we move - * start to the end of the region since it's ok until there + /* + * If the region is at the beginning of <start,end> we move + * 'start' to the end of the region since it's ok until there */ - if (ei->addr <= start) - start = ei->addr + ei->size; + if (entry->addr <= start) + start = entry->addr + entry->size; + /* - * if start is now at or beyond end, we're done, full - * coverage + * If 'start' is now at or beyond 'end', we're done, full + * coverage of the desired range exists: */ if (start >= end) return 1; @@ -108,94 +116,77 @@ int __init e820_all_mapped(u64 start, u64 end, unsigned type) } /* - * Add a memory region to the kernel e820 map. + * Add a memory region to the kernel E820 map. */ -static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size, - int type) +static void __init __e820__range_add(struct e820_table *table, u64 start, u64 size, enum e820_type type) { - int x = e820x->nr_map; + int x = table->nr_entries; - if (x >= ARRAY_SIZE(e820x->map)) { - printk(KERN_ERR "e820: too many entries; ignoring [mem %#010llx-%#010llx]\n", - (unsigned long long) start, - (unsigned long long) (start + size - 1)); + if (x >= ARRAY_SIZE(table->entries)) { + pr_err("e820: too many entries; ignoring [mem %#010llx-%#010llx]\n", start, start + size - 1); return; } - e820x->map[x].addr = start; - e820x->map[x].size = size; - e820x->map[x].type = type; - e820x->nr_map++; + table->entries[x].addr = start; + table->entries[x].size = size; + table->entries[x].type = type; + table->nr_entries++; } -void __init e820_add_region(u64 start, u64 size, int type) +void __init e820__range_add(u64 start, u64 size, enum e820_type type) { - __e820_add_region(e820, start, size, type); + __e820__range_add(e820_table, start, size, type); } -static void __init e820_print_type(u32 type) +static void __init e820_print_type(enum e820_type type) { switch (type) { - case E820_RAM: - case E820_RESERVED_KERN: - printk(KERN_CONT "usable"); - break; - case E820_RESERVED: - printk(KERN_CONT "reserved"); - break; - case E820_ACPI: - printk(KERN_CONT "ACPI data"); - break; - case E820_NVS: - printk(KERN_CONT "ACPI NVS"); - break; - case E820_UNUSABLE: - printk(KERN_CONT "unusable"); - break; - case E820_PMEM: - case E820_PRAM: - printk(KERN_CONT "persistent (type %u)", type); - break; - default: - printk(KERN_CONT "type %u", type); - break; + case E820_TYPE_RAM: /* Fall through: */ + case E820_TYPE_RESERVED_KERN: pr_cont("usable"); break; + case E820_TYPE_RESERVED: pr_cont("reserved"); break; + case E820_TYPE_ACPI: pr_cont("ACPI data"); break; + case E820_TYPE_NVS: pr_cont("ACPI NVS"); break; + case E820_TYPE_UNUSABLE: pr_cont("unusable"); break; + case E820_TYPE_PMEM: /* Fall through: */ + case E820_TYPE_PRAM: pr_cont("persistent (type %u)", type); break; + default: pr_cont("type %u", type); break; } } -void __init e820_print_map(char *who) +void __init e820__print_table(char *who) { int i; - for (i = 0; i < e820->nr_map; i++) { - printk(KERN_INFO "%s: [mem %#018Lx-%#018Lx] ", who, - (unsigned long long) e820->map[i].addr, - (unsigned long long) - (e820->map[i].addr + e820->map[i].size - 1)); - e820_print_type(e820->map[i].type); - printk(KERN_CONT "\n"); + for (i = 0; i < e820_table->nr_entries; i++) { + pr_info("%s: [mem %#018Lx-%#018Lx] ", who, + e820_table->entries[i].addr, + e820_table->entries[i].addr + e820_table->entries[i].size - 1); + + e820_print_type(e820_table->entries[i].type); + pr_cont("\n"); } } /* - * Sanitize the BIOS e820 map. + * Sanitize an E820 map. * - * Some e820 responses include overlapping entries. The following - * replaces the original e820 map with a new one, removing overlaps, + * Some E820 layouts include overlapping entries. The following + * replaces the original E820 map with a new one, removing overlaps, * and resolving conflicting memory types in favor of highest * numbered type. * - * The input parameter biosmap points to an array of 'struct - * e820entry' which on entry has elements in the range [0, *pnr_map) - * valid, and which has space for up to max_nr_map entries. - * On return, the resulting sanitized e820 map entries will be in - * overwritten in the same location, starting at biosmap. + * The input parameter 'entries' points to an array of 'struct + * e820_entry' which on entry has elements in the range [0, *nr_entries) + * valid, and which has space for up to max_nr_entries entries. + * On return, the resulting sanitized E820 map entries will be in + * overwritten in the same location, starting at 'entries'. * - * The integer pointed to by pnr_map must be valid on entry (the - * current number of valid entries located at biosmap). If the - * sanitizing succeeds the *pnr_map will be updated with the new - * number of valid entries (something no more than max_nr_map). + * The integer pointed to by nr_entries must be valid on entry (the + * current number of valid entries located at 'entries'). If the + * sanitizing succeeds the *nr_entries will be updated with the new + * number of valid entries (something no more than max_nr_entries). * - * The return value from sanitize_e820_map() is zero if it + * The return value from e820__update_table() is zero if it * successfully 'sanitized' the map entries passed in, and is -1 * if it did nothing, which can happen if either of (1) it was * only passed one map entry, or (2) any of the input map entries @@ -238,10 +229,17 @@ void __init e820_print_map(char *who) * ______________________4_ */ struct change_member { - struct e820entry *pbios; /* pointer to original bios entry */ - unsigned long long addr; /* address for this change point */ + /* Pointer to the original entry: */ + struct e820_entry *entry; + /* Address for this change point: */ + unsigned long long addr; }; +static struct change_member change_point_list[2*E820_MAX_ENTRIES] __initdata; +static struct change_member *change_point[2*E820_MAX_ENTRIES] __initdata; +static struct e820_entry *overlap_list[E820_MAX_ENTRIES] __initdata; +static struct e820_entry new_entries[E820_MAX_ENTRIES] __initdata; + static int __init cpcompare(const void *a, const void *b) { struct change_member * const *app = a, * const *bpp = b; @@ -249,164 +247,141 @@ static int __init cpcompare(const void *a, const void *b) /* * Inputs are pointers to two elements of change_point[]. If their - * addresses are unequal, their difference dominates. If the addresses + * addresses are not equal, their difference dominates. If the addresses * are equal, then consider one that represents the end of its region * to be greater than one that does not. */ if (ap->addr != bp->addr) return ap->addr > bp->addr ? 1 : -1; - return (ap->addr != ap->pbios->addr) - (bp->addr != bp->pbios->addr); + return (ap->addr != ap->entry->addr) - (bp->addr != bp->entry->addr); } -int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, - u32 *pnr_map) +int __init e820__update_table(struct e820_table *table) { - static struct change_member change_point_list[2*E820_X_MAX] __initdata; - static struct change_member *change_point[2*E820_X_MAX] __initdata; - static struct e820entry *overlap_list[E820_X_MAX] __initdata; - static struct e820entry new_bios[E820_X_MAX] __initdata; - unsigned long current_type, last_type; + struct e820_entry *entries = table->entries; + u32 max_nr_entries = ARRAY_SIZE(table->entries); + enum e820_type current_type, last_type; unsigned long long last_addr; - int chgidx; - int overlap_entries; - int new_bios_entry; - int old_nr, new_nr, chg_nr; - int i; + u32 new_nr_entries, overlap_entries; + u32 i, chg_idx, chg_nr; - /* if there's only one memory region, don't bother */ - if (*pnr_map < 2) + /* If there's only one memory region, don't bother: */ + if (table->nr_entries < 2) return -1; - old_nr = *pnr_map; - BUG_ON(old_nr > max_nr_map); + table->nr_entries = table->nr_entries; + BUG_ON(table->nr_entries > max_nr_entries); - /* bail out if we find any unreasonable addresses in bios map */ - for (i = 0; i < old_nr; i++) - if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr) + /* Bail out if we find any unreasonable addresses in the map: */ + for (i = 0; i < table->nr_entries; i++) { + if (entries[i].addr + entries[i].size < entries[i].addr) return -1; + } - /* create pointers for initial change-point information (for sorting) */ - for (i = 0; i < 2 * old_nr; i++) + /* Create pointers for initial change-point information (for sorting): */ + for (i = 0; i < 2 * table->nr_entries; i++) change_point[i] = &change_point_list[i]; - /* record all known change-points (starting and ending addresses), - omitting those that are for empty memory regions */ - chgidx = 0; - for (i = 0; i < old_nr; i++) { - if (biosmap[i].size != 0) { - change_point[chgidx]->addr = biosmap[i].addr; - change_point[chgidx++]->pbios = &biosmap[i]; - change_point[chgidx]->addr = biosmap[i].addr + - biosmap[i].size; - change_point[chgidx++]->pbios = &biosmap[i]; + /* + * Record all known change-points (starting and ending addresses), + * omitting empty memory regions: + */ + chg_idx = 0; + for (i = 0; i < table->nr_entries; i++) { + if (entries[i].size != 0) { + change_point[chg_idx]->addr = entries[i].addr; + change_point[chg_idx++]->entry = &entries[i]; + change_point[chg_idx]->addr = entries[i].addr + entries[i].size; + change_point[chg_idx++]->entry = &entries[i]; } } - chg_nr = chgidx; - - /* sort change-point list by memory addresses (low -> high) */ - sort(change_point, chg_nr, sizeof *change_point, cpcompare, NULL); - - /* create a new bios memory map, removing overlaps */ - overlap_entries = 0; /* number of entries in the overlap table */ - new_bios_entry = 0; /* index for creating new bios map entries */ - last_type = 0; /* start with undefined memory type */ - last_addr = 0; /* start with 0 as last starting address */ - - /* loop through change-points, determining affect on the new bios map */ - for (chgidx = 0; chgidx < chg_nr; chgidx++) { - /* keep track of all overlapping bios entries */ - if (change_point[chgidx]->addr == - change_point[chgidx]->pbios->addr) { - /* - * add map entry to overlap list (> 1 entry - * implies an overlap) - */ - overlap_list[overlap_entries++] = - change_point[chgidx]->pbios; + chg_nr = chg_idx; + + /* Sort change-point list by memory addresses (low -> high): */ + sort(change_point, chg_nr, sizeof(*change_point), cpcompare, NULL); + + /* Create a new memory map, removing overlaps: */ + overlap_entries = 0; /* Number of entries in the overlap table */ + new_nr_entries = 0; /* Index for creating new map entries */ + last_type = 0; /* Start with undefined memory type */ + last_addr = 0; /* Start with 0 as last starting address */ + + /* Loop through change-points, determining effect on the new map: */ + for (chg_idx = 0; chg_idx < chg_nr; chg_idx++) { + /* Keep track of all overlapping entries */ + if (change_point[chg_idx]->addr == change_point[chg_idx]->entry->addr) { + /* Add map entry to overlap list (> 1 entry implies an overlap) */ + overlap_list[overlap_entries++] = change_point[chg_idx]->entry; } else { - /* - * remove entry from list (order independent, - * so swap with last) - */ + /* Remove entry from list (order independent, so swap with last): */ for (i = 0; i < overlap_entries; i++) { - if (overlap_list[i] == - change_point[chgidx]->pbios) - overlap_list[i] = - overlap_list[overlap_entries-1]; + if (overlap_list[i] == change_point[chg_idx]->entry) + overlap_list[i] = overlap_list[overlap_entries-1]; } overlap_entries--; } /* - * if there are overlapping entries, decide which + * If there are overlapping entries, decide which * "type" to use (larger value takes precedence -- * 1=usable, 2,3,4,4+=unusable) */ current_type = 0; - for (i = 0; i < overlap_entries; i++) + for (i = 0; i < overlap_entries; i++) { if (overlap_list[i]->type > current_type) current_type = overlap_list[i]->type; - /* - * continue building up new bios map based on this - * information - */ - if (current_type != last_type || current_type == E820_PRAM) { + } + + /* Continue building up new map based on this information: */ + if (current_type != last_type || current_type == E820_TYPE_PRAM) { if (last_type != 0) { - new_bios[new_bios_entry].size = - change_point[chgidx]->addr - last_addr; - /* - * move forward only if the new size - * was non-zero - */ - if (new_bios[new_bios_entry].size != 0) - /* - * no more space left for new - * bios entries ? - */ - if (++new_bios_entry >= max_nr_map) + new_entries[new_nr_entries].size = change_point[chg_idx]->addr - last_addr; + /* Move forward only if the new size was non-zero: */ + if (new_entries[new_nr_entries].size != 0) + /* No more space left for new entries? */ + if (++new_nr_entries >= max_nr_entries) break; } if (current_type != 0) { - new_bios[new_bios_entry].addr = - change_point[chgidx]->addr; - new_bios[new_bios_entry].type = current_type; - last_addr = change_point[chgidx]->addr; + new_entries[new_nr_entries].addr = change_point[chg_idx]->addr; + new_entries[new_nr_entries].type = current_type; + last_addr = change_point[chg_idx]->addr; } last_type = current_type; } } - /* retain count for new bios entries */ - new_nr = new_bios_entry; - /* copy new bios mapping into original location */ - memcpy(biosmap, new_bios, new_nr * sizeof(struct e820entry)); - *pnr_map = new_nr; + /* Copy the new entries into the original location: */ + memcpy(entries, new_entries, new_nr_entries*sizeof(*entries)); + table->nr_entries = new_nr_entries; return 0; } -static int __init __append_e820_map(struct e820entry *biosmap, int nr_map) +static int __init __append_e820_table(struct boot_e820_entry *entries, u32 nr_entries) { - while (nr_map) { - u64 start = biosmap->addr; - u64 size = biosmap->size; + struct boot_e820_entry *entry = entries; + + while (nr_entries) { + u64 start = entry->addr; + u64 size = entry->size; u64 end = start + size - 1; - u32 type = biosmap->type; + u32 type = entry->type; - /* Overflow in 64 bits? Ignore the memory map. */ + /* Ignore the entry on 64-bit overflow: */ if (start > end && likely(size)) return -1; - e820_add_region(start, size, type); + e820__range_add(start, size, type); - biosmap++; - nr_map--; + entry++; + nr_entries--; } return 0; } /* - * Copy the BIOS e820 map into a safe place. + * Copy the BIOS E820 map into a safe place. * * Sanity-check it while we're at it.. * @@ -414,18 +389,17 @@ static int __init __append_e820_map(struct e820entry *biosmap, int nr_map) * will have given us a memory map that we can use to properly * set up memory. If we aren't, we'll fake a memory map. */ -static int __init append_e820_map(struct e820entry *biosmap, int nr_map) +static int __init append_e820_table(struct boot_e820_entry *entries, u32 nr_entries) { /* Only one memory region (or negative)? Ignore it */ - if (nr_map < 2) + if (nr_entries < 2) return -1; - return __append_e820_map(biosmap, nr_map); + return __append_e820_table(entries, nr_entries); } -static u64 __init __e820_update_range(struct e820map *e820x, u64 start, - u64 size, unsigned old_type, - unsigned new_type) +static u64 __init +__e820__range_update(struct e820_table *table, u64 start, u64 size, enum e820_type old_type, enum e820_type new_type) { u64 end; unsigned int i; @@ -437,77 +411,73 @@ static u64 __init __e820_update_range(struct e820map *e820x, u64 start, size = ULLONG_MAX - start; end = start + size; - printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ", - (unsigned long long) start, (unsigned long long) (end - 1)); + printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ", start, end - 1); e820_print_type(old_type); - printk(KERN_CONT " ==> "); + pr_cont(" ==> "); e820_print_type(new_type); - printk(KERN_CONT "\n"); + pr_cont("\n"); - for (i = 0; i < e820x->nr_map; i++) { - struct e820entry *ei = &e820x->map[i]; + for (i = 0; i < table->nr_entries; i++) { + struct e820_entry *entry = &table->entries[i]; u64 final_start, final_end; - u64 ei_end; + u64 entry_end; - if (ei->type != old_type) + if (entry->type != old_type) continue; - ei_end = ei->addr + ei->size; - /* totally covered by new range? */ - if (ei->addr >= start && ei_end <= end) { - ei->type = new_type; - real_updated_size += ei->size; + entry_end = entry->addr + entry->size; + + /* Completely covered by new range? */ + if (entry->addr >= start && entry_end <= end) { + entry->type = new_type; + real_updated_size += entry->size; continue; } - /* new range is totally covered? */ - if (ei->addr < start && ei_end > end) { - __e820_add_region(e820x, start, size, new_type); - __e820_add_region(e820x, end, ei_end - end, ei->type); - ei->size = start - ei->addr; + /* New range is completely covered? */ + if (entry->addr < start && entry_end > end) { + __e820__range_add(table, start, size, new_type); + __e820__range_add(table, end, entry_end - end, entry->type); + entry->size = start - entry->addr; real_updated_size += size; continue; } - /* partially covered */ - final_start = max(start, ei->addr); - final_end = min(end, ei_end); + /* Partially covered: */ + final_start = max(start, entry->addr); + final_end = min(end, entry_end); if (final_start >= final_end) continue; - __e820_add_region(e820x, final_start, final_end - final_start, - new_type); + __e820__range_add(table, final_start, final_end - final_start, new_type); real_updated_size += final_end - final_start; /* - * left range could be head or tail, so need to update - * size at first. + * Left range could be head or tail, so need to update + * its size first: */ - ei->size -= final_end - final_start; - if (ei->addr < final_start) + entry->size -= final_end - final_start; + if (entry->addr < final_start) continue; - ei->addr = final_end; + + entry->addr = final_end; } return real_updated_size; } -u64 __init e820_update_range(u64 start, u64 size, unsigned old_type, - unsigned new_type) +u64 __init e820__range_update(u64 start, u64 size, enum e820_type old_type, enum e820_type new_type) { - return __e820_update_range(e820, start, size, old_type, new_type); + return __e820__range_update(e820_table, start, size, old_type, new_type); } -static u64 __init e820_update_range_saved(u64 start, u64 size, - unsigned old_type, unsigned new_type) +static u64 __init e820__range_update_firmware(u64 start, u64 size, enum e820_type old_type, enum e820_type new_type) { - return __e820_update_range(e820_saved, start, size, old_type, - new_type); + return __e820__range_update(e820_table_firmware, start, size, old_type, new_type); } -/* make e820 not cover the range */ -u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, - int checktype) +/* Remove a range of memory from the E820 table: */ +u64 __init e820__range_remove(u64 start, u64 size, enum e820_type old_type, bool check_type) { int i; u64 end; @@ -517,85 +487,89 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, size = ULLONG_MAX - start; end = start + size; - printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ", - (unsigned long long) start, (unsigned long long) (end - 1)); - if (checktype) + printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ", start, end - 1); + if (check_type) e820_print_type(old_type); - printk(KERN_CONT "\n"); + pr_cont("\n"); - for (i = 0; i < e820->nr_map; i++) { - struct e820entry *ei = &e820->map[i]; + for (i = 0; i < e820_table->nr_entries; i++) { + struct e820_entry *entry = &e820_table->entries[i]; u64 final_start, final_end; - u64 ei_end; + u64 entry_end; - if (checktype && ei->type != old_type) + if (check_type && entry->type != old_type) continue; - ei_end = ei->addr + ei->size; - /* totally covered? */ - if (ei->addr >= start && ei_end <= end) { - real_removed_size += ei->size; - memset(ei, 0, sizeof(struct e820entry)); + entry_end = entry->addr + entry->size; + + /* Completely covered? */ + if (entry->addr >= start && entry_end <= end) { + real_removed_size += entry->size; + memset(entry, 0, sizeof(*entry)); continue; } - /* new range is totally covered? */ - if (ei->addr < start && ei_end > end) { - e820_add_region(end, ei_end - end, ei->type); - ei->size = start - ei->addr; + /* Is the new range completely covered? */ + if (entry->addr < start && entry_end > end) { + e820__range_add(end, entry_end - end, entry->type); + entry->size = start - entry->addr; real_removed_size += size; continue; } - /* partially covered */ - final_start = max(start, ei->addr); - final_end = min(end, ei_end); + /* Partially covered: */ + final_start = max(start, entry->addr); + final_end = min(end, entry_end); if (final_start >= final_end) continue; + real_removed_size += final_end - final_start; /* - * left range could be head or tail, so need to update - * size at first. + * Left range could be head or tail, so need to update + * the size first: */ - ei->size -= final_end - final_start; - if (ei->addr < final_start) + entry->size -= final_end - final_start; + if (entry->addr < final_start) continue; - ei->addr = final_end; + + entry->addr = final_end; } return real_removed_size; } -void __init update_e820(void) +void __init e820__update_table_print(void) { - if (sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map)) + if (e820__update_table(e820_table)) return; - printk(KERN_INFO "e820: modified physical RAM map:\n"); - e820_print_map("modified"); + + pr_info("e820: modified physical RAM map:\n"); + e820__print_table("modified"); } -static void __init update_e820_saved(void) + +static void __init e820__update_table_firmware(void) { - sanitize_e820_map(e820_saved->map, ARRAY_SIZE(e820_saved->map), - &e820_saved->nr_map); + e820__update_table(e820_table_firmware); } + #define MAX_GAP_END 0x100000000ull + /* - * Search for a gap in the e820 memory space from 0 to MAX_GAP_END. + * Search for a gap in the E820 memory space from 0 to MAX_GAP_END (4GB). */ -static int __init e820_search_gap(unsigned long *gapstart, - unsigned long *gapsize) +static int __init e820_search_gap(unsigned long *gapstart, unsigned long *gapsize) { unsigned long long last = MAX_GAP_END; - int i = e820->nr_map; + int i = e820_table->nr_entries; int found = 0; while (--i >= 0) { - unsigned long long start = e820->map[i].addr; - unsigned long long end = start + e820->map[i].size; + unsigned long long start = e820_table->entries[i].addr; + unsigned long long end = start + e820_table->entries[i].size; /* * Since "last" is at most 4GB, we know we'll - * fit in 32 bits if this condition is true + * fit in 32 bits if this condition is true: */ if (last > end) { unsigned long gap = last - end; @@ -613,12 +587,14 @@ static int __init e820_search_gap(unsigned long *gapstart, } /* - * Search for the biggest gap in the low 32 bits of the e820 - * memory space. We pass this space to PCI to assign MMIO resources - * for hotplug or unconfigured devices in. + * Search for the biggest gap in the low 32 bits of the E820 + * memory space. We pass this space to the PCI subsystem, so + * that it can assign MMIO resources for hotplug or + * unconfigured devices in. + * * Hopefully the BIOS let enough space left. */ -__init void e820_setup_gap(void) +__init void e820__setup_pci_gap(void) { unsigned long gapstart, gapsize; int found; @@ -629,138 +605,143 @@ __init void e820_setup_gap(void) if (!found) { #ifdef CONFIG_X86_64 gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024; - printk(KERN_ERR - "e820: cannot find a gap in the 32bit address range\n" - "e820: PCI devices with unassigned 32bit BARs may break!\n"); + pr_err( + "e820: Cannot find an available gap in the 32-bit address range\n" + "e820: PCI devices with unassigned 32-bit BARs may not work!\n"); #else gapstart = 0x10000000; #endif } /* - * e820_reserve_resources_late protect stolen RAM already + * e820__reserve_resources_late() protects stolen RAM already: */ pci_mem_start = gapstart; - printk(KERN_INFO - "e820: [mem %#010lx-%#010lx] available for PCI devices\n", - gapstart, gapstart + gapsize - 1); + pr_info("e820: [mem %#010lx-%#010lx] available for PCI devices\n", gapstart, gapstart + gapsize - 1); } /* * Called late during init, in free_initmem(). * - * Initial e820 and e820_saved are largish __initdata arrays. - * Copy them to (usually much smaller) dynamically allocated area. - * This is done after all tweaks we ever do to them: - * all functions which modify them are __init functions, - * they won't exist after this point. + * Initial e820_table and e820_table_firmware are largish __initdata arrays. + * + * Copy them to a (usually much smaller) dynamically allocated area that is + * sized precisely after the number of e820 entries. + * + * This is done after we've performed all the fixes and tweaks to the tables. + * All functions which modify them are __init functions, which won't exist + * after free_initmem(). */ -__init void e820_reallocate_tables(void) +__init void e820__reallocate_tables(void) { - struct e820map *n; + struct e820_table *n; int size; - size = offsetof(struct e820map, map) + sizeof(struct e820entry) * e820->nr_map; + size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table->nr_entries; n = kmalloc(size, GFP_KERNEL); BUG_ON(!n); - memcpy(n, e820, size); - e820 = n; + memcpy(n, e820_table, size); + e820_table = n; - size = offsetof(struct e820map, map) + sizeof(struct e820entry) * e820_saved->nr_map; + size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table_firmware->nr_entries; n = kmalloc(size, GFP_KERNEL); BUG_ON(!n); - memcpy(n, e820_saved, size); - e820_saved = n; + memcpy(n, e820_table_firmware, size); + e820_table_firmware = n; } -/** - * Because of the size limitation of struct boot_params, only first - * 128 E820 memory entries are passed to kernel via - * boot_params.e820_map, others are passed via SETUP_E820_EXT node of - * linked list of struct setup_data, which is parsed here. +/* + * Because of the small fixed size of struct boot_params, only the first + * 128 E820 memory entries are passed to the kernel via boot_params.e820_table, + * the remaining (if any) entries are passed via the SETUP_E820_EXT node of + * struct setup_data, which is parsed here. */ -void __init parse_e820_ext(u64 phys_addr, u32 data_len) +void __init e820__memory_setup_extended(u64 phys_addr, u32 data_len) { int entries; - struct e820entry *extmap; + struct boot_e820_entry *extmap; struct setup_data *sdata; sdata = early_memremap(phys_addr, data_len); - entries = sdata->len / sizeof(struct e820entry); - extmap = (struct e820entry *)(sdata->data); - __append_e820_map(extmap, entries); - sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map); + entries = sdata->len / sizeof(*extmap); + extmap = (struct boot_e820_entry *)(sdata->data); + + __append_e820_table(extmap, entries); + e820__update_table(e820_table); + early_memunmap(sdata, data_len); - printk(KERN_INFO "e820: extended physical RAM map:\n"); - e820_print_map("extended"); + pr_info("e820: extended physical RAM map:\n"); + e820__print_table("extended"); } -#if defined(CONFIG_X86_64) || \ - (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) -/** +/* * Find the ranges of physical addresses that do not correspond to - * e820 RAM areas and mark the corresponding pages as nosave for - * hibernation (32 bit) or software suspend and suspend to RAM (64 bit). + * E820 RAM areas and register the corresponding pages as 'nosave' for + * hibernation (32-bit) or software suspend and suspend to RAM (64-bit). * - * This function requires the e820 map to be sorted and without any + * This function requires the E820 map to be sorted and without any * overlapping entries. */ -void __init e820_mark_nosave_regions(unsigned long limit_pfn) +void __init e820__register_nosave_regions(unsigned long limit_pfn) { int i; unsigned long pfn = 0; - for (i = 0; i < e820->nr_map; i++) { - struct e820entry *ei = &e820->map[i]; + for (i = 0; i < e820_table->nr_entries; i++) { + struct e820_entry *entry = &e820_table->entries[i]; - if (pfn < PFN_UP(ei->addr)) - register_nosave_region(pfn, PFN_UP(ei->addr)); + if (pfn < PFN_UP(entry->addr)) + register_nosave_region(pfn, PFN_UP(entry->addr)); - pfn = PFN_DOWN(ei->addr + ei->size); + pfn = PFN_DOWN(entry->addr + entry->size); - if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN) - register_nosave_region(PFN_UP(ei->addr), pfn); + if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN) + register_nosave_region(PFN_UP(entry->addr), pfn); if (pfn >= limit_pfn) break; } } -#endif #ifdef CONFIG_ACPI -/** - * Mark ACPI NVS memory region, so that we can save/restore it during - * hibernation and the subsequent resume. +/* + * Register ACPI NVS memory regions, so that we can save/restore them during + * hibernation and the subsequent resume: */ -static int __init e820_mark_nvs_memory(void) +static int __init e820__register_nvs_regions(void) { int i; - for (i = 0; i < e820->nr_map; i++) { - struct e820entry *ei = &e820->map[i]; + for (i = 0; i < e820_table->nr_entries; i++) { + struct e820_entry *entry = &e820_table->entries[i]; - if (ei->type == E820_NVS) - acpi_nvs_register(ei->addr, ei->size); + if (entry->type == E820_TYPE_NVS) + acpi_nvs_register(entry->addr, entry->size); } return 0; } -core_initcall(e820_mark_nvs_memory); +core_initcall(e820__register_nvs_regions); #endif /* - * pre allocated 4k and reserved it in memblock and e820_saved + * Allocate the requested number of bytes with the requsted alignment + * and return (the physical address) to the caller. Also register this + * range in the 'firmware' E820 table as a reserved range. + * + * This allows kexec to fake a new mptable, as if it came from the real + * system. */ -u64 __init early_reserve_e820(u64 size, u64 align) +u64 __init e820__memblock_alloc_reserved(u64 size, u64 align) { u64 addr; addr = __memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE); if (addr) { - e820_update_range_saved(addr, size, E820_RAM, E820_RESERVED); - printk(KERN_INFO "e820: update e820_saved for early_reserve_e820\n"); - update_e820_saved(); + e820__range_update_firmware(addr, size, E820_TYPE_RAM, E820_TYPE_RESERVED); + pr_info("e820: update e820_table_firmware for e820__memblock_alloc_reserved()\n"); + e820__update_table_firmware(); } return addr; @@ -779,22 +760,22 @@ u64 __init early_reserve_e820(u64 size, u64 align) /* * Find the highest page frame number we have available */ -static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) +static unsigned long __init e820_end_pfn(unsigned long limit_pfn, enum e820_type type) { int i; unsigned long last_pfn = 0; unsigned long max_arch_pfn = MAX_ARCH_PFN; - for (i = 0; i < e820->nr_map; i++) { - struct e820entry *ei = &e820->map[i]; + for (i = 0; i < e820_table->nr_entries; i++) { + struct e820_entry *entry = &e820_table->entries[i]; unsigned long start_pfn; unsigned long end_pfn; - if (ei->type != type) + if (entry->type != type) continue; - start_pfn = ei->addr >> PAGE_SHIFT; - end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT; + start_pfn = entry->addr >> PAGE_SHIFT; + end_pfn = (entry->addr + entry->size) >> PAGE_SHIFT; if (start_pfn >= limit_pfn) continue; @@ -809,18 +790,19 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) if (last_pfn > max_arch_pfn) last_pfn = max_arch_pfn; - printk(KERN_INFO "e820: last_pfn = %#lx max_arch_pfn = %#lx\n", + pr_info("e820: last_pfn = %#lx max_arch_pfn = %#lx\n", last_pfn, max_arch_pfn); return last_pfn; } -unsigned long __init e820_end_of_ram_pfn(void) + +unsigned long __init e820__end_of_ram_pfn(void) { - return e820_end_pfn(MAX_ARCH_PFN, E820_RAM); + return e820_end_pfn(MAX_ARCH_PFN, E820_TYPE_RAM); } -unsigned long __init e820_end_of_low_ram_pfn(void) +unsigned long __init e820__end_of_low_ram_pfn(void) { - return e820_end_pfn(1UL << (32 - PAGE_SHIFT), E820_RAM); + return e820_end_pfn(1UL << (32 - PAGE_SHIFT), E820_TYPE_RAM); } static void __init early_panic(char *msg) @@ -831,7 +813,7 @@ static void __init early_panic(char *msg) static int userdef __initdata; -/* "mem=nopentium" disables the 4MB page tables. */ +/* The "mem=nopentium" boot option disables 4MB page tables on 32-bit kernels: */ static int __init parse_memopt(char *p) { u64 mem_size; @@ -844,17 +826,19 @@ static int __init parse_memopt(char *p) setup_clear_cpu_cap(X86_FEATURE_PSE); return 0; #else - printk(KERN_WARNING "mem=nopentium ignored! (only supported on x86_32)\n"); + pr_warn("mem=nopentium ignored! (only supported on x86_32)\n"); return -EINVAL; #endif } userdef = 1; mem_size = memparse(p, &p); - /* don't remove all of memory when handling "mem={invalid}" param */ + + /* Don't remove all memory when getting "mem={invalid}" parameter: */ if (mem_size == 0) return -EINVAL; - e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); + + e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1); return 0; } @@ -872,12 +856,12 @@ static int __init parse_memmap_one(char *p) #ifdef CONFIG_CRASH_DUMP /* * If we are doing a crash dump, we still need to know - * the real mem size before original memory map is + * the real memory size before the original memory map is * reset. */ - saved_max_pfn = e820_end_of_ram_pfn(); + saved_max_pfn = e820__end_of_ram_pfn(); #endif - e820->nr_map = 0; + e820_table->nr_entries = 0; userdef = 1; return 0; } @@ -890,21 +874,23 @@ static int __init parse_memmap_one(char *p) userdef = 1; if (*p == '@') { start_at = memparse(p+1, &p); - e820_add_region(start_at, mem_size, E820_RAM); + e820__range_add(start_at, mem_size, E820_TYPE_RAM); } else if (*p == '#') { start_at = memparse(p+1, &p); - e820_add_region(start_at, mem_size, E820_ACPI); + e820__range_add(start_at, mem_size, E820_TYPE_ACPI); } else if (*p == '$') { start_at = memparse(p+1, &p); - e820_add_region(start_at, mem_size, E820_RESERVED); + e820__range_add(start_at, mem_size, E820_TYPE_RESERVED); } else if (*p == '!') { start_at = memparse(p+1, &p); - e820_add_region(start_at, mem_size, E820_PRAM); - } else - e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); + e820__range_add(start_at, mem_size, E820_TYPE_PRAM); + } else { + e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1); + } return *p == '\0' ? 0 : -EINVAL; } + static int __init parse_memmap_opt(char *str) { while (str) { @@ -921,68 +907,97 @@ static int __init parse_memmap_opt(char *str) } early_param("memmap", parse_memmap_opt); -void __init finish_e820_parsing(void) +/* + * Reserve all entries from the bootloader's extensible data nodes list, + * because if present we are going to use it later on to fetch e820 + * entries from it: + */ +void __init e820__reserve_setup_data(void) +{ + struct setup_data *data; + u64 pa_data; + + pa_data = boot_params.hdr.setup_data; + if (!pa_data) + return; + + while (pa_data) { + data = early_memremap(pa_data, sizeof(*data)); + e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); + pa_data = data->next; + early_memunmap(data, sizeof(*data)); + } + + e820__update_table(e820_table); + + memcpy(e820_table_firmware, e820_table, sizeof(*e820_table_firmware)); + + pr_info("extended physical RAM map:\n"); + e820__print_table("reserve setup_data"); +} + +/* + * Called after parse_early_param(), after early parameters (such as mem=) + * have been processed, in which case we already have an E820 table filled in + * via the parameter callback function(s), but it's not sorted and printed yet: + */ +void __init e820__finish_early_params(void) { if (userdef) { - if (sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), - &e820->nr_map) < 0) + if (e820__update_table(e820_table) < 0) early_panic("Invalid user supplied memory map"); - printk(KERN_INFO "e820: user-defined physical RAM map:\n"); - e820_print_map("user"); + pr_info("e820: user-defined physical RAM map:\n"); + e820__print_table("user"); } } -static const char *__init e820_type_to_string(int e820_type) +static const char *__init e820_type_to_string(struct e820_entry *entry) { - switch (e820_type) { - case E820_RESERVED_KERN: - case E820_RAM: return "System RAM"; - case E820_ACPI: return "ACPI Tables"; - case E820_NVS: return "ACPI Non-volatile Storage"; - case E820_UNUSABLE: return "Unusable memory"; - case E820_PRAM: return "Persistent Memory (legacy)"; - case E820_PMEM: return "Persistent Memory"; - default: return "reserved"; + switch (entry->type) { + case E820_TYPE_RESERVED_KERN: /* Fall-through: */ + case E820_TYPE_RAM: return "System RAM"; + case E820_TYPE_ACPI: return "ACPI Tables"; + case E820_TYPE_NVS: return "ACPI Non-volatile Storage"; + case E820_TYPE_UNUSABLE: return "Unusable memory"; + case E820_TYPE_PRAM: return "Persistent Memory (legacy)"; + case E820_TYPE_PMEM: return "Persistent Memory"; + case E820_TYPE_RESERVED: return "Reserved"; + default: return "Unknown E820 type"; } } -static unsigned long __init e820_type_to_iomem_type(int e820_type) +static unsigned long __init e820_type_to_iomem_type(struct e820_entry *entry) { - switch (e820_type) { - case E820_RESERVED_KERN: - case E820_RAM: - return IORESOURCE_SYSTEM_RAM; - case E820_ACPI: - case E820_NVS: - case E820_UNUSABLE: - case E820_PRAM: - case E820_PMEM: - default: - return IORESOURCE_MEM; + switch (entry->type) { + case E820_TYPE_RESERVED_KERN: /* Fall-through: */ + case E820_TYPE_RAM: return IORESOURCE_SYSTEM_RAM; + case E820_TYPE_ACPI: /* Fall-through: */ + case E820_TYPE_NVS: /* Fall-through: */ + case E820_TYPE_UNUSABLE: /* Fall-through: */ + case E820_TYPE_PRAM: /* Fall-through: */ + case E820_TYPE_PMEM: /* Fall-through: */ + case E820_TYPE_RESERVED: /* Fall-through: */ + default: return IORESOURCE_MEM; } } -static unsigned long __init e820_type_to_iores_desc(int e820_type) +static unsigned long __init e820_type_to_iores_desc(struct e820_entry *entry) { - switch (e820_type) { - case E820_ACPI: - return IORES_DESC_ACPI_TABLES; - case E820_NVS: - return IORES_DESC_ACPI_NV_STORAGE; - case E820_PMEM: - return IORES_DESC_PERSISTENT_MEMORY; - case E820_PRAM: - return IORES_DESC_PERSISTENT_MEMORY_LEGACY; - case E820_RESERVED_KERN: - case E820_RAM: - case E820_UNUSABLE: - default: - return IORES_DESC_NONE; + switch (entry->type) { + case E820_TYPE_ACPI: return IORES_DESC_ACPI_TABLES; + case E820_TYPE_NVS: return IORES_DESC_ACPI_NV_STORAGE; + case E820_TYPE_PMEM: return IORES_DESC_PERSISTENT_MEMORY; + case E820_TYPE_PRAM: return IORES_DESC_PERSISTENT_MEMORY_LEGACY; + case E820_TYPE_RESERVED_KERN: /* Fall-through: */ + case E820_TYPE_RAM: /* Fall-through: */ + case E820_TYPE_UNUSABLE: /* Fall-through: */ + case E820_TYPE_RESERVED: /* Fall-through: */ + default: return IORES_DESC_NONE; } } -static bool __init do_mark_busy(u32 type, struct resource *res) +static bool __init do_mark_busy(enum e820_type type, struct resource *res) { /* this is the legacy bios/dos rom-shadow + mmio region */ if (res->start < (1ULL<<20)) @@ -993,61 +1008,71 @@ static bool __init do_mark_busy(u32 type, struct resource *res) * for exclusive use of a driver */ switch (type) { - case E820_RESERVED: - case E820_PRAM: - case E820_PMEM: + case E820_TYPE_RESERVED: + case E820_TYPE_PRAM: + case E820_TYPE_PMEM: return false; + case E820_TYPE_RESERVED_KERN: + case E820_TYPE_RAM: + case E820_TYPE_ACPI: + case E820_TYPE_NVS: + case E820_TYPE_UNUSABLE: default: return true; } } /* - * Mark e820 reserved areas as busy for the resource manager. + * Mark E820 reserved areas as busy for the resource manager: */ + static struct resource __initdata *e820_res; -void __init e820_reserve_resources(void) + +void __init e820__reserve_resources(void) { int i; struct resource *res; u64 end; - res = alloc_bootmem(sizeof(struct resource) * e820->nr_map); + res = alloc_bootmem(sizeof(*res) * e820_table->nr_entries); e820_res = res; - for (i = 0; i < e820->nr_map; i++) { - end = e820->map[i].addr + e820->map[i].size - 1; + + for (i = 0; i < e820_table->nr_entries; i++) { + struct e820_entry *entry = e820_table->entries + i; + + end = entry->addr + entry->size - 1; if (end != (resource_size_t)end) { res++; continue; } - res->name = e820_type_to_string(e820->map[i].type); - res->start = e820->map[i].addr; - res->end = end; - - res->flags = e820_type_to_iomem_type(e820->map[i].type); - res->desc = e820_type_to_iores_desc(e820->map[i].type); + res->start = entry->addr; + res->end = end; + res->name = e820_type_to_string(entry); + res->flags = e820_type_to_iomem_type(entry); + res->desc = e820_type_to_iores_desc(entry); /* - * don't register the region that could be conflicted with - * pci device BAR resource and insert them later in - * pcibios_resource_survey() + * Don't register the region that could be conflicted with + * PCI device BAR resources and insert them later in + * pcibios_resource_survey(): */ - if (do_mark_busy(e820->map[i].type, res)) { + if (do_mark_busy(entry->type, res)) { res->flags |= IORESOURCE_BUSY; insert_resource(&iomem_resource, res); } res++; } - for (i = 0; i < e820_saved->nr_map; i++) { - struct e820entry *entry = &e820_saved->map[i]; - firmware_map_add_early(entry->addr, - entry->addr + entry->size, - e820_type_to_string(entry->type)); + for (i = 0; i < e820_table_firmware->nr_entries; i++) { + struct e820_entry *entry = e820_table_firmware->entries + i; + + firmware_map_add_early(entry->addr, entry->addr + entry->size, e820_type_to_string(entry)); } } -/* How much should we pad RAM ending depending on where it is? */ +/* + * How much should we pad the end of RAM, depending on where it is? + */ static unsigned long __init ram_alignment(resource_size_t pos) { unsigned long mb = pos >> 20; @@ -1066,64 +1091,59 @@ static unsigned long __init ram_alignment(resource_size_t pos) #define MAX_RESOURCE_SIZE ((resource_size_t)-1) -void __init e820_reserve_resources_late(void) +void __init e820__reserve_resources_late(void) { int i; struct resource *res; res = e820_res; - for (i = 0; i < e820->nr_map; i++) { + for (i = 0; i < e820_table->nr_entries; i++) { if (!res->parent && res->end) insert_resource_expand_to_fit(&iomem_resource, res); res++; } /* - * Try to bump up RAM regions to reasonable boundaries to + * Try to bump up RAM regions to reasonable boundaries, to * avoid stolen RAM: */ - for (i = 0; i < e820->nr_map; i++) { - struct e820entry *entry = &e820->map[i]; + for (i = 0; i < e820_table->nr_entries; i++) { + struct e820_entry *entry = &e820_table->entries[i]; u64 start, end; - if (entry->type != E820_RAM) + if (entry->type != E820_TYPE_RAM) continue; + start = entry->addr + entry->size; end = round_up(start, ram_alignment(start)) - 1; if (end > MAX_RESOURCE_SIZE) end = MAX_RESOURCE_SIZE; if (start >= end) continue; - printk(KERN_DEBUG - "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n", - start, end); - reserve_region_with_split(&iomem_resource, start, end, - "RAM buffer"); + + printk(KERN_DEBUG "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n", start, end); + reserve_region_with_split(&iomem_resource, start, end, "RAM buffer"); } } -char *__init default_machine_specific_memory_setup(void) +/* + * Pass the firmware (bootloader) E820 map to the kernel and process it: + */ +char *__init e820__memory_setup_default(void) { char *who = "BIOS-e820"; - u32 new_nr; + /* * Try to copy the BIOS-supplied E820-map. * * Otherwise fake a memory map; one section from 0k->640k, * the next section from 1mb->appropriate_mem_k */ - new_nr = boot_params.e820_entries; - sanitize_e820_map(boot_params.e820_map, - ARRAY_SIZE(boot_params.e820_map), - &new_nr); - boot_params.e820_entries = new_nr; - if (append_e820_map(boot_params.e820_map, boot_params.e820_entries) - < 0) { + if (append_e820_table(boot_params.e820_table, boot_params.e820_entries) < 0) { u64 mem_size; - /* compare results from other methods and take the greater */ - if (boot_params.alt_mem_k - < boot_params.screen_info.ext_mem_k) { + /* Compare results from other methods and take the one that gives more RAM: */ + if (boot_params.alt_mem_k < boot_params.screen_info.ext_mem_k) { mem_size = boot_params.screen_info.ext_mem_k; who = "BIOS-88"; } else { @@ -1131,84 +1151,68 @@ char *__init default_machine_specific_memory_setup(void) who = "BIOS-e801"; } - e820->nr_map = 0; - e820_add_region(0, LOWMEMSIZE(), E820_RAM); - e820_add_region(HIGH_MEMORY, mem_size << 10, E820_RAM); + e820_table->nr_entries = 0; + e820__range_add(0, LOWMEMSIZE(), E820_TYPE_RAM); + e820__range_add(HIGH_MEMORY, mem_size << 10, E820_TYPE_RAM); } - /* In case someone cares... */ + /* We just appended a lot of ranges, sanitize the table: */ + e820__update_table(e820_table); + return who; } -void __init setup_memory_map(void) +/* + * Calls e820__memory_setup_default() in essence to pick up the firmware/bootloader + * E820 map - with an optional platform quirk available for virtual platforms + * to override this method of boot environment processing: + */ +void __init e820__memory_setup(void) { char *who; + /* This is a firmware interface ABI - make sure we don't break it: */ + BUILD_BUG_ON(sizeof(struct boot_e820_entry) != 20); + who = x86_init.resources.memory_setup(); - memcpy(e820_saved, e820, sizeof(struct e820map)); - printk(KERN_INFO "e820: BIOS-provided physical RAM map:\n"); - e820_print_map(who); + + memcpy(e820_table_firmware, e820_table, sizeof(*e820_table_firmware)); + + pr_info("e820: BIOS-provided physical RAM map:\n"); + e820__print_table(who); } -void __init memblock_x86_fill(void) +void __init e820__memblock_setup(void) { int i; u64 end; /* - * EFI may have more than 128 entries - * We are safe to enable resizing, beause memblock_x86_fill() - * is rather later for x86 + * The bootstrap memblock region count maximum is 128 entries + * (INIT_MEMBLOCK_REGIONS), but EFI might pass us more E820 entries + * than that - so allow memblock resizing. + * + * This is safe, because this call happens pretty late during x86 setup, + * so we know about reserved memory regions already. (This is important + * so that memblock resizing does no stomp over reserved areas.) */ memblock_allow_resize(); - for (i = 0; i < e820->nr_map; i++) { - struct e820entry *ei = &e820->map[i]; + for (i = 0; i < e820_table->nr_entries; i++) { + struct e820_entry *entry = &e820_table->entries[i]; - end = ei->addr + ei->size; + end = entry->addr + entry->size; if (end != (resource_size_t)end) continue; - if (ei->type != E820_RAM && ei->type != E820_RESERVED_KERN) + if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN) continue; - memblock_add(ei->addr, ei->size); + memblock_add(entry->addr, entry->size); } - /* throw away partial pages */ + /* Throw away partial pages: */ memblock_trim_memory(PAGE_SIZE); memblock_dump_all(); } - -void __init memblock_find_dma_reserve(void) -{ -#ifdef CONFIG_X86_64 - u64 nr_pages = 0, nr_free_pages = 0; - unsigned long start_pfn, end_pfn; - phys_addr_t start, end; - int i; - u64 u; - - /* - * need to find out used area below MAX_DMA_PFN - * need to use memblock to get free size in [0, MAX_DMA_PFN] - * at first, and assume boot_mem will not take below MAX_DMA_PFN - */ - for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) { - start_pfn = min(start_pfn, MAX_DMA_PFN); - end_pfn = min(end_pfn, MAX_DMA_PFN); - nr_pages += end_pfn - start_pfn; - } - - for_each_free_mem_range(u, NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end, - NULL) { - start_pfn = min_t(unsigned long, PFN_UP(start), MAX_DMA_PFN); - end_pfn = min_t(unsigned long, PFN_DOWN(end), MAX_DMA_PFN); - if (start_pfn < end_pfn) - nr_free_pages += end_pfn - start_pfn; - } - - set_dma_reserve(nr_pages - nr_free_pages); -#endif -} diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 6a08e25a48d8..ff7e4b3988ed 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -546,8 +546,8 @@ intel_graphics_stolen(int num, int slot, int func, &base, &end); /* Mark this space as reserved */ - e820_add_region(base, size, E820_RESERVED); - sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map); + e820__range_add(base, size, E820_TYPE_RESERVED); + e820__update_table(e820_table); } static void __init intel_graphics_quirks(int num, int slot, int func) diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 8f3d9cf26ff9..5b7153540727 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -983,6 +983,18 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, unsigned long return_hooker = (unsigned long) &return_to_handler; + /* + * When resuming from suspend-to-ram, this function can be indirectly + * called from early CPU startup code while the CPU is in real mode, + * which would fail miserably. Make sure the stack pointer is a + * virtual address. + * + * This check isn't as accurate as virt_addr_valid(), but it should be + * good enough for this purpose, and it's fast. + */ + if (unlikely((long)__builtin_frame_address(0) >= 0)) + return; + if (unlikely(ftrace_graph_is_dead())) return; diff --git a/arch/x86/kernel/ftrace_32.S b/arch/x86/kernel/ftrace_32.S new file mode 100644 index 000000000000..722a145b4139 --- /dev/null +++ b/arch/x86/kernel/ftrace_32.S @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2017 Steven Rostedt, VMware Inc. + */ + +#include <linux/linkage.h> +#include <asm/page_types.h> +#include <asm/segment.h> +#include <asm/export.h> +#include <asm/ftrace.h> + +#ifdef CC_USING_FENTRY +# define function_hook __fentry__ +EXPORT_SYMBOL(__fentry__) +#else +# define function_hook mcount +EXPORT_SYMBOL(mcount) +#endif + +#ifdef CONFIG_DYNAMIC_FTRACE + +/* mcount uses a frame pointer even if CONFIG_FRAME_POINTER is not set */ +#if !defined(CC_USING_FENTRY) || defined(CONFIG_FRAME_POINTER) +# define USING_FRAME_POINTER +#endif + +#ifdef USING_FRAME_POINTER +# define MCOUNT_FRAME 1 /* using frame = true */ +#else +# define MCOUNT_FRAME 0 /* using frame = false */ +#endif + +ENTRY(function_hook) + ret +END(function_hook) + +ENTRY(ftrace_caller) + +#ifdef USING_FRAME_POINTER +# ifdef CC_USING_FENTRY + /* + * Frame pointers are of ip followed by bp. + * Since fentry is an immediate jump, we are left with + * parent-ip, function-ip. We need to add a frame with + * parent-ip followed by ebp. + */ + pushl 4(%esp) /* parent ip */ + pushl %ebp + movl %esp, %ebp + pushl 2*4(%esp) /* function ip */ +# endif + /* For mcount, the function ip is directly above */ + pushl %ebp + movl %esp, %ebp +#endif + pushl %eax + pushl %ecx + pushl %edx + pushl $0 /* Pass NULL as regs pointer */ + +#ifdef USING_FRAME_POINTER + /* Load parent ebp into edx */ + movl 4*4(%esp), %edx +#else + /* There's no frame pointer, load the appropriate stack addr instead */ + lea 4*4(%esp), %edx +#endif + + movl (MCOUNT_FRAME+4)*4(%esp), %eax /* load the rip */ + /* Get the parent ip */ + movl 4(%edx), %edx /* edx has ebp */ + + movl function_trace_op, %ecx + subl $MCOUNT_INSN_SIZE, %eax + +.globl ftrace_call +ftrace_call: + call ftrace_stub + + addl $4, %esp /* skip NULL pointer */ + popl %edx + popl %ecx + popl %eax +#ifdef USING_FRAME_POINTER + popl %ebp +# ifdef CC_USING_FENTRY + addl $4,%esp /* skip function ip */ + popl %ebp /* this is the orig bp */ + addl $4, %esp /* skip parent ip */ +# endif +#endif +.Lftrace_ret: +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +.globl ftrace_graph_call +ftrace_graph_call: + jmp ftrace_stub +#endif + +/* This is weak to keep gas from relaxing the jumps */ +WEAK(ftrace_stub) + ret +END(ftrace_caller) + +ENTRY(ftrace_regs_caller) + /* + * i386 does not save SS and ESP when coming from kernel. + * Instead, to get sp, ®s->sp is used (see ptrace.h). + * Unfortunately, that means eflags must be at the same location + * as the current return ip is. We move the return ip into the + * regs->ip location, and move flags into the return ip location. + */ + pushl $__KERNEL_CS + pushl 4(%esp) /* Save the return ip */ + pushl $0 /* Load 0 into orig_ax */ + pushl %gs + pushl %fs + pushl %es + pushl %ds + pushl %eax + + /* Get flags and place them into the return ip slot */ + pushf + popl %eax + movl %eax, 8*4(%esp) + + pushl %ebp + pushl %edi + pushl %esi + pushl %edx + pushl %ecx + pushl %ebx + + movl 12*4(%esp), %eax /* Load ip (1st parameter) */ + subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */ +#ifdef CC_USING_FENTRY + movl 15*4(%esp), %edx /* Load parent ip (2nd parameter) */ +#else + movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */ +#endif + movl function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */ + pushl %esp /* Save pt_regs as 4th parameter */ + +GLOBAL(ftrace_regs_call) + call ftrace_stub + + addl $4, %esp /* Skip pt_regs */ + + /* restore flags */ + push 14*4(%esp) + popf + + /* Move return ip back to its original location */ + movl 12*4(%esp), %eax + movl %eax, 14*4(%esp) + + popl %ebx + popl %ecx + popl %edx + popl %esi + popl %edi + popl %ebp + popl %eax + popl %ds + popl %es + popl %fs + popl %gs + + /* use lea to not affect flags */ + lea 3*4(%esp), %esp /* Skip orig_ax, ip and cs */ + + jmp .Lftrace_ret +#else /* ! CONFIG_DYNAMIC_FTRACE */ + +ENTRY(function_hook) + cmpl $__PAGE_OFFSET, %esp + jb ftrace_stub /* Paging not enabled yet? */ + + cmpl $ftrace_stub, ftrace_trace_function + jnz .Ltrace +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + cmpl $ftrace_stub, ftrace_graph_return + jnz ftrace_graph_caller + + cmpl $ftrace_graph_entry_stub, ftrace_graph_entry + jnz ftrace_graph_caller +#endif +.globl ftrace_stub +ftrace_stub: + ret + + /* taken from glibc */ +.Ltrace: + pushl %eax + pushl %ecx + pushl %edx + movl 0xc(%esp), %eax + movl 0x4(%ebp), %edx + subl $MCOUNT_INSN_SIZE, %eax + + call *ftrace_trace_function + + popl %edx + popl %ecx + popl %eax + jmp ftrace_stub +END(function_hook) +#endif /* CONFIG_DYNAMIC_FTRACE */ + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +ENTRY(ftrace_graph_caller) + pushl %eax + pushl %ecx + pushl %edx + movl 3*4(%esp), %eax + /* Even with frame pointers, fentry doesn't have one here */ +#ifdef CC_USING_FENTRY + lea 4*4(%esp), %edx + movl $0, %ecx +#else + lea 0x4(%ebp), %edx + movl (%ebp), %ecx +#endif + subl $MCOUNT_INSN_SIZE, %eax + call prepare_ftrace_return + popl %edx + popl %ecx + popl %eax + ret +END(ftrace_graph_caller) + +.globl return_to_handler +return_to_handler: + pushl %eax + pushl %edx +#ifdef CC_USING_FENTRY + movl $0, %eax +#else + movl %ebp, %eax +#endif + call ftrace_return_to_handler + movl %eax, %ecx + popl %edx + popl %eax + jmp *%ecx +#endif diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/ftrace_64.S index 7b0d3da52fb4..1dfac634bbf7 100644 --- a/arch/x86/kernel/mcount_64.S +++ b/arch/x86/kernel/ftrace_64.S @@ -1,6 +1,4 @@ /* - * linux/arch/x86_64/mcount_64.S - * * Copyright (C) 2014 Steven Rostedt, Red Hat Inc */ @@ -13,9 +11,6 @@ .code64 .section .entry.text, "ax" - -#ifdef CONFIG_FUNCTION_TRACER - #ifdef CC_USING_FENTRY # define function_hook __fentry__ EXPORT_SYMBOL(__fentry__) @@ -297,7 +292,6 @@ trace: jmp fgraph_trace END(function_hook) #endif /* CONFIG_DYNAMIC_FTRACE */ -#endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER ENTRY(ftrace_graph_caller) diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index e5fb436a6548..538ec012b371 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c @@ -12,7 +12,7 @@ #include <asm/setup.h> #include <asm/sections.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/page.h> #include <asm/apic.h> #include <asm/io_apic.h> diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index b5785c197e53..43b7002f44fb 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -24,7 +24,7 @@ #include <asm/tlbflush.h> #include <asm/sections.h> #include <asm/kdebug.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/bios_ebda.h> #include <asm/bootparam_utils.h> #include <asm/microcode.h> diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index b467b14b03eb..ac9d327d2e42 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -269,10 +269,8 @@ ENTRY(secondary_startup_64) /* rsi is pointer to real mode structure with interesting info. pass it to C */ movq %rsi, %rdi - jmp start_cpu -ENDPROC(secondary_startup_64) -ENTRY(start_cpu) +.Ljump_to_C_code: /* * Jump to run C code and to be on a real kernel address. * Since we are running on identity-mapped space we have to jump @@ -305,7 +303,7 @@ ENTRY(start_cpu) pushq %rax # target address in negative space lretq .Lafter_lret: -ENDPROC(start_cpu) +ENDPROC(secondary_startup_64) #include "verify_cpu.S" @@ -313,11 +311,11 @@ ENDPROC(start_cpu) /* * Boot CPU0 entry point. It's called from play_dead(). Everything has been set * up already except stack. We just set up stack here. Then call - * start_secondary() via start_cpu(). + * start_secondary() via .Ljump_to_C_code. */ ENTRY(start_cpu0) movq initial_stack(%rip), %rsp - jmp start_cpu + jmp .Ljump_to_C_code ENDPROC(start_cpu0) #endif diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c index d0a814a9d96a..9d7fd5e6689a 100644 --- a/arch/x86/kernel/kexec-bzimage64.c +++ b/arch/x86/kernel/kexec-bzimage64.c @@ -25,6 +25,7 @@ #include <asm/setup.h> #include <asm/crash.h> #include <asm/efi.h> +#include <asm/e820/api.h> #include <asm/kexec-bzimage64.h> #define MAX_ELFCOREHDR_STR_LEN 30 /* elfcorehdr=0x<64bit-value> */ @@ -99,15 +100,14 @@ static int setup_e820_entries(struct boot_params *params) { unsigned int nr_e820_entries; - nr_e820_entries = e820_saved->nr_map; + nr_e820_entries = e820_table_firmware->nr_entries; - /* TODO: Pass entries more than E820MAX in bootparams setup data */ - if (nr_e820_entries > E820MAX) - nr_e820_entries = E820MAX; + /* TODO: Pass entries more than E820_MAX_ENTRIES_ZEROPAGE in bootparams setup data */ + if (nr_e820_entries > E820_MAX_ENTRIES_ZEROPAGE) + nr_e820_entries = E820_MAX_ENTRIES_ZEROPAGE; params->e820_entries = nr_e820_entries; - memcpy(¶ms->e820_map, &e820_saved->map, - nr_e820_entries * sizeof(struct e820entry)); + memcpy(¶ms->e820_table, &e820_table_firmware->entries, nr_e820_entries*sizeof(struct e820_entry)); return 0; } @@ -232,10 +232,10 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params, nr_e820_entries = params->e820_entries; for (i = 0; i < nr_e820_entries; i++) { - if (params->e820_map[i].type != E820_RAM) + if (params->e820_table[i].type != E820_TYPE_RAM) continue; - start = params->e820_map[i].addr; - end = params->e820_map[i].addr + params->e820_map[i].size - 1; + start = params->e820_table[i].addr; + end = params->e820_table[i].addr + params->e820_table[i].size - 1; if ((start <= 0x100000) && end > 0x100000) { mem_k = (end >> 10) - (0x100000 >> 10); diff --git a/arch/x86/kernel/kprobes/common.h b/arch/x86/kernel/kprobes/common.h index d688826e5736..db2182d63ed0 100644 --- a/arch/x86/kernel/kprobes/common.h +++ b/arch/x86/kernel/kprobes/common.h @@ -67,7 +67,7 @@ #endif /* Ensure if the instruction can be boostable */ -extern int can_boost(kprobe_opcode_t *instruction, void *addr); +extern int can_boost(struct insn *insn, void *orig_addr); /* Recover instruction if given address is probed */ extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr); @@ -75,7 +75,7 @@ extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf, * Copy an instruction and adjust the displacement if the instruction * uses the %rip-relative addressing mode. */ -extern int __copy_instruction(u8 *dest, u8 *src); +extern int __copy_instruction(u8 *dest, u8 *src, struct insn *insn); /* Generate a relative-jump/call instruction */ extern void synthesize_reljump(void *from, void *to); diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 993fa4fe4f68..19e1f2a6d7b0 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -164,42 +164,38 @@ static kprobe_opcode_t *skip_prefixes(kprobe_opcode_t *insn) NOKPROBE_SYMBOL(skip_prefixes); /* - * Returns non-zero if opcode is boostable. + * Returns non-zero if INSN is boostable. * RIP relative instructions are adjusted at copying time in 64 bits mode */ -int can_boost(kprobe_opcode_t *opcodes, void *addr) +int can_boost(struct insn *insn, void *addr) { kprobe_opcode_t opcode; - kprobe_opcode_t *orig_opcodes = opcodes; if (search_exception_tables((unsigned long)addr)) return 0; /* Page fault may occur on this address. */ -retry: - if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) - return 0; - opcode = *(opcodes++); - /* 2nd-byte opcode */ - if (opcode == 0x0f) { - if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) - return 0; - return test_bit(*opcodes, + if (insn->opcode.nbytes == 2) + return test_bit(insn->opcode.bytes[1], (unsigned long *)twobyte_is_boostable); - } + + if (insn->opcode.nbytes != 1) + return 0; + + /* Can't boost Address-size override prefix */ + if (unlikely(inat_is_address_size_prefix(insn->attr))) + return 0; + + opcode = insn->opcode.bytes[0]; switch (opcode & 0xf0) { -#ifdef CONFIG_X86_64 - case 0x40: - goto retry; /* REX prefix is boostable */ -#endif case 0x60: - if (0x63 < opcode && opcode < 0x67) - goto retry; /* prefixes */ - /* can't boost Address-size override and bound */ - return (opcode != 0x62 && opcode != 0x67); + /* can't boost "bound" */ + return (opcode != 0x62); case 0x70: return 0; /* can't boost conditional jump */ + case 0x90: + return opcode != 0x9a; /* can't boost call far */ case 0xc0: /* can't boost software-interruptions */ return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf; @@ -210,14 +206,9 @@ retry: /* can boost in/out and absolute jmps */ return ((opcode & 0x04) || opcode == 0xea); case 0xf0: - if ((opcode & 0x0c) == 0 && opcode != 0xf1) - goto retry; /* lock/rep(ne) prefix */ /* clear and set flags are boostable */ return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe)); default: - /* segment override prefixes are boostable */ - if (opcode == 0x26 || opcode == 0x36 || opcode == 0x3e) - goto retry; /* prefixes */ /* CS override prefix and call are not boostable */ return (opcode != 0x2e && opcode != 0x9a); } @@ -264,7 +255,10 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) * Fortunately, we know that the original code is the ideal 5-byte * long NOP. */ - memcpy(buf, (void *)addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); + if (probe_kernel_read(buf, (void *)addr, + MAX_INSN_SIZE * sizeof(kprobe_opcode_t))) + return 0UL; + if (faddr) memcpy(buf, ideal_nops[NOP_ATOMIC5], 5); else @@ -276,7 +270,7 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr) * Recover the probed instruction at addr for further analysis. * Caller must lock kprobes by kprobe_mutex, or disable preemption * for preventing to release referencing kprobes. - * Returns zero if the instruction can not get recovered. + * Returns zero if the instruction can not get recovered (or access failed). */ unsigned long recover_probed_instruction(kprobe_opcode_t *buf, unsigned long addr) { @@ -348,37 +342,36 @@ static int is_IF_modifier(kprobe_opcode_t *insn) } /* - * Copy an instruction and adjust the displacement if the instruction - * uses the %rip-relative addressing mode. - * If it does, Return the address of the 32-bit displacement word. - * If not, return null. - * Only applicable to 64-bit x86. + * Copy an instruction with recovering modified instruction by kprobes + * and adjust the displacement if the instruction uses the %rip-relative + * addressing mode. + * This returns the length of copied instruction, or 0 if it has an error. */ -int __copy_instruction(u8 *dest, u8 *src) +int __copy_instruction(u8 *dest, u8 *src, struct insn *insn) { - struct insn insn; kprobe_opcode_t buf[MAX_INSN_SIZE]; - int length; unsigned long recovered_insn = recover_probed_instruction(buf, (unsigned long)src); - if (!recovered_insn) + if (!recovered_insn || !insn) + return 0; + + /* This can access kernel text if given address is not recovered */ + if (probe_kernel_read(dest, (void *)recovered_insn, MAX_INSN_SIZE)) return 0; - kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE); - insn_get_length(&insn); - length = insn.length; + + kernel_insn_init(insn, dest, MAX_INSN_SIZE); + insn_get_length(insn); /* Another subsystem puts a breakpoint, failed to recover */ - if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) + if (insn->opcode.bytes[0] == BREAKPOINT_INSTRUCTION) return 0; - memcpy(dest, insn.kaddr, length); #ifdef CONFIG_X86_64 - if (insn_rip_relative(&insn)) { + /* Only x86_64 has RIP relative instructions */ + if (insn_rip_relative(insn)) { s64 newdisp; u8 *disp; - kernel_insn_init(&insn, dest, length); - insn_get_displacement(&insn); /* * The copied instruction uses the %rip-relative addressing * mode. Adjust the displacement for the difference between @@ -391,36 +384,57 @@ int __copy_instruction(u8 *dest, u8 *src) * extension of the original signed 32-bit displacement would * have given. */ - newdisp = (u8 *) src + (s64) insn.displacement.value - (u8 *) dest; + newdisp = (u8 *) src + (s64) insn->displacement.value + - (u8 *) dest; if ((s64) (s32) newdisp != newdisp) { pr_err("Kprobes error: new displacement does not fit into s32 (%llx)\n", newdisp); - pr_err("\tSrc: %p, Dest: %p, old disp: %x\n", src, dest, insn.displacement.value); + pr_err("\tSrc: %p, Dest: %p, old disp: %x\n", + src, dest, insn->displacement.value); return 0; } - disp = (u8 *) dest + insn_offset_displacement(&insn); + disp = (u8 *) dest + insn_offset_displacement(insn); *(s32 *) disp = (s32) newdisp; } #endif - return length; + return insn->length; +} + +/* Prepare reljump right after instruction to boost */ +static void prepare_boost(struct kprobe *p, struct insn *insn) +{ + if (can_boost(insn, p->addr) && + MAX_INSN_SIZE - insn->length >= RELATIVEJUMP_SIZE) { + /* + * These instructions can be executed directly if it + * jumps back to correct address. + */ + synthesize_reljump(p->ainsn.insn + insn->length, + p->addr + insn->length); + p->ainsn.boostable = true; + } else { + p->ainsn.boostable = false; + } } static int arch_copy_kprobe(struct kprobe *p) { - int ret; + struct insn insn; + int len; + + set_memory_rw((unsigned long)p->ainsn.insn & PAGE_MASK, 1); /* Copy an instruction with recovering if other optprobe modifies it.*/ - ret = __copy_instruction(p->ainsn.insn, p->addr); - if (!ret) + len = __copy_instruction(p->ainsn.insn, p->addr, &insn); + if (!len) return -EINVAL; /* * __copy_instruction can modify the displacement of the instruction, * but it doesn't affect boostable check. */ - if (can_boost(p->ainsn.insn, p->addr)) - p->ainsn.boostable = 0; - else - p->ainsn.boostable = -1; + prepare_boost(p, &insn); + + set_memory_ro((unsigned long)p->ainsn.insn & PAGE_MASK, 1); /* Check whether the instruction modifies Interrupt Flag or not */ p->ainsn.if_modifier = is_IF_modifier(p->ainsn.insn); @@ -459,7 +473,7 @@ void arch_disarm_kprobe(struct kprobe *p) void arch_remove_kprobe(struct kprobe *p) { if (p->ainsn.insn) { - free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1)); + free_insn_slot(p->ainsn.insn, p->ainsn.boostable); p->ainsn.insn = NULL; } } @@ -531,7 +545,7 @@ static void setup_singlestep(struct kprobe *p, struct pt_regs *regs, return; #if !defined(CONFIG_PREEMPT) - if (p->ainsn.boostable == 1 && !p->post_handler) { + if (p->ainsn.boostable && !p->post_handler) { /* Boost up -- we can execute copied instructions directly */ if (!reenter) reset_current_kprobe(); @@ -851,7 +865,7 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs, case 0xcf: case 0xea: /* jmp absolute -- ip is correct */ /* ip is already adjusted, no more changes required */ - p->ainsn.boostable = 1; + p->ainsn.boostable = true; goto no_change; case 0xe8: /* call relative - Fix return addr */ *tos = orig_ip + (*tos - copy_ip); @@ -876,28 +890,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs, * jmp near and far, absolute indirect * ip is correct. And this is boostable */ - p->ainsn.boostable = 1; + p->ainsn.boostable = true; goto no_change; } default: break; } - if (p->ainsn.boostable == 0) { - if ((regs->ip > copy_ip) && - (regs->ip - copy_ip) + 5 < MAX_INSN_SIZE) { - /* - * These instructions can be executed directly if it - * jumps back to correct address. - */ - synthesize_reljump((void *)regs->ip, - (void *)orig_ip + (regs->ip - copy_ip)); - p->ainsn.boostable = 1; - } else { - p->ainsn.boostable = -1; - } - } - regs->ip += orig_ip - copy_ip; no_change: diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c index 5f8f0b3cc674..041f7b6dfa0f 100644 --- a/arch/x86/kernel/kprobes/ftrace.c +++ b/arch/x86/kernel/kprobes/ftrace.c @@ -94,6 +94,6 @@ NOKPROBE_SYMBOL(kprobe_ftrace_handler); int arch_prepare_kprobe_ftrace(struct kprobe *p) { p->ainsn.insn = NULL; - p->ainsn.boostable = -1; + p->ainsn.boostable = false; return 0; } diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index 3e7c6e5a08ff..9aadff3d0902 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c @@ -65,7 +65,10 @@ found: * overwritten by jump destination address. In this case, original * bytes must be recovered from op->optinsn.copied_insn buffer. */ - memcpy(buf, (void *)addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); + if (probe_kernel_read(buf, (void *)addr, + MAX_INSN_SIZE * sizeof(kprobe_opcode_t))) + return 0UL; + if (addr == (unsigned long)kp->addr) { buf[0] = kp->opcode; memcpy(buf + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE); @@ -174,11 +177,12 @@ NOKPROBE_SYMBOL(optimized_callback); static int copy_optimized_instructions(u8 *dest, u8 *src) { + struct insn insn; int len = 0, ret; while (len < RELATIVEJUMP_SIZE) { - ret = __copy_instruction(dest + len, src + len); - if (!ret || !can_boost(dest + len, src + len)) + ret = __copy_instruction(dest + len, src + len, &insn); + if (!ret || !can_boost(&insn, src + len)) return -EINVAL; len += ret; } @@ -350,6 +354,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, } buf = (u8 *)op->optinsn.insn; + set_memory_rw((unsigned long)buf & PAGE_MASK, 1); /* Copy instructions into the out-of-line buffer */ ret = copy_optimized_instructions(buf + TMPL_END_IDX, op->kp.addr); @@ -372,6 +377,8 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, synthesize_reljump(buf + TMPL_END_IDX + op->optinsn.size, (u8 *)op->kp.addr + op->optinsn.size); + set_memory_ro((unsigned long)buf & PAGE_MASK, 1); + flush_icache_range((unsigned long) buf, (unsigned long) buf + TMPL_END_IDX + op->optinsn.size + RELATIVEJUMP_SIZE); diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 0f8d20497383..0d904d759ff1 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -26,7 +26,7 @@ #include <asm/io_apic.h> #include <asm/proto.h> #include <asm/bios_ebda.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/setup.h> #include <asm/smp.h> @@ -826,10 +826,10 @@ static int __init parse_alloc_mptable_opt(char *p) } early_param("alloc_mptable", parse_alloc_mptable_opt); -void __init early_reserve_e820_mpc_new(void) +void __init e820__memblock_alloc_reserved_mpc_new(void) { if (enable_update_mptable && alloc_mptable) - mpc_new_phys = early_reserve_e820(mpc_new_length, 4); + mpc_new_phys = e820__memblock_alloc_reserved(mpc_new_length, 4); } static int __init update_mp_table(void) diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index a723ae9440ab..446c8aa09b9b 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -222,17 +222,6 @@ pci_serr_error(unsigned char reason, struct pt_regs *regs) pr_emerg("NMI: PCI system error (SERR) for reason %02x on CPU %d.\n", reason, smp_processor_id()); - /* - * On some machines, PCI SERR line is used to report memory - * errors. EDAC makes use of it. - */ -#if defined(CONFIG_EDAC) - if (edac_handler_set()) { - edac_atomic_assert_error(); - return; - } -#endif - if (panic_on_unrecovered_nmi) nmi_panic(regs, "NMI: Not continuing"); diff --git a/arch/x86/kernel/probe_roms.c b/arch/x86/kernel/probe_roms.c index d5f15c3f7b25..963e3fb56437 100644 --- a/arch/x86/kernel/probe_roms.c +++ b/arch/x86/kernel/probe_roms.c @@ -14,7 +14,7 @@ #include <asm/probe_roms.h> #include <asm/pci-direct.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/mmzone.h> #include <asm/setup.h> #include <asm/sections.h> diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index f67591561711..0bb88428cbf2 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -37,6 +37,7 @@ #include <asm/vm86.h> #include <asm/switch_to.h> #include <asm/desc.h> +#include <asm/prctl.h> /* * per-CPU TSS segments. Threads are completely 'soft' on Linux, @@ -124,11 +125,6 @@ void flush_thread(void) fpu__clear(&tsk->thread.fpu); } -static void hard_disable_TSC(void) -{ - cr4_set_bits(X86_CR4_TSD); -} - void disable_TSC(void) { preempt_disable(); @@ -137,15 +133,10 @@ void disable_TSC(void) * Must flip the CPU state synchronously with * TIF_NOTSC in the current running context. */ - hard_disable_TSC(); + cr4_set_bits(X86_CR4_TSD); preempt_enable(); } -static void hard_enable_TSC(void) -{ - cr4_clear_bits(X86_CR4_TSD); -} - static void enable_TSC(void) { preempt_disable(); @@ -154,7 +145,7 @@ static void enable_TSC(void) * Must flip the CPU state synchronously with * TIF_NOTSC in the current running context. */ - hard_enable_TSC(); + cr4_clear_bits(X86_CR4_TSD); preempt_enable(); } @@ -182,54 +173,129 @@ int set_tsc_mode(unsigned int val) return 0; } -void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, - struct tss_struct *tss) -{ - struct thread_struct *prev, *next; - - prev = &prev_p->thread; - next = &next_p->thread; +DEFINE_PER_CPU(u64, msr_misc_features_shadow); - if (test_tsk_thread_flag(prev_p, TIF_BLOCKSTEP) ^ - test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) { - unsigned long debugctl = get_debugctlmsr(); +static void set_cpuid_faulting(bool on) +{ + u64 msrval; - debugctl &= ~DEBUGCTLMSR_BTF; - if (test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) - debugctl |= DEBUGCTLMSR_BTF; + msrval = this_cpu_read(msr_misc_features_shadow); + msrval &= ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT; + msrval |= (on << MSR_MISC_FEATURES_ENABLES_CPUID_FAULT_BIT); + this_cpu_write(msr_misc_features_shadow, msrval); + wrmsrl(MSR_MISC_FEATURES_ENABLES, msrval); +} - update_debugctlmsr(debugctl); +static void disable_cpuid(void) +{ + preempt_disable(); + if (!test_and_set_thread_flag(TIF_NOCPUID)) { + /* + * Must flip the CPU state synchronously with + * TIF_NOCPUID in the current running context. + */ + set_cpuid_faulting(true); } + preempt_enable(); +} - if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ - test_tsk_thread_flag(next_p, TIF_NOTSC)) { - /* prev and next are different */ - if (test_tsk_thread_flag(next_p, TIF_NOTSC)) - hard_disable_TSC(); - else - hard_enable_TSC(); +static void enable_cpuid(void) +{ + preempt_disable(); + if (test_and_clear_thread_flag(TIF_NOCPUID)) { + /* + * Must flip the CPU state synchronously with + * TIF_NOCPUID in the current running context. + */ + set_cpuid_faulting(false); } + preempt_enable(); +} + +static int get_cpuid_mode(void) +{ + return !test_thread_flag(TIF_NOCPUID); +} + +static int set_cpuid_mode(struct task_struct *task, unsigned long cpuid_enabled) +{ + if (!static_cpu_has(X86_FEATURE_CPUID_FAULT)) + return -ENODEV; + + if (cpuid_enabled) + enable_cpuid(); + else + disable_cpuid(); + + return 0; +} + +/* + * Called immediately after a successful exec. + */ +void arch_setup_new_exec(void) +{ + /* If cpuid was previously disabled for this task, re-enable it. */ + if (test_thread_flag(TIF_NOCPUID)) + enable_cpuid(); +} - if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { +static inline void switch_to_bitmap(struct tss_struct *tss, + struct thread_struct *prev, + struct thread_struct *next, + unsigned long tifp, unsigned long tifn) +{ + if (tifn & _TIF_IO_BITMAP) { /* * Copy the relevant range of the IO bitmap. * Normally this is 128 bytes or less: */ memcpy(tss->io_bitmap, next->io_bitmap_ptr, max(prev->io_bitmap_max, next->io_bitmap_max)); - /* * Make sure that the TSS limit is correct for the CPU * to notice the IO bitmap. */ refresh_tss_limit(); - } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) { + } else if (tifp & _TIF_IO_BITMAP) { /* * Clear any possible leftover bits: */ memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); } +} + +void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, + struct tss_struct *tss) +{ + struct thread_struct *prev, *next; + unsigned long tifp, tifn; + + prev = &prev_p->thread; + next = &next_p->thread; + + tifn = READ_ONCE(task_thread_info(next_p)->flags); + tifp = READ_ONCE(task_thread_info(prev_p)->flags); + switch_to_bitmap(tss, prev, next, tifp, tifn); + propagate_user_return_notify(prev_p, next_p); + + if ((tifp & _TIF_BLOCKSTEP || tifn & _TIF_BLOCKSTEP) && + arch_has_block_step()) { + unsigned long debugctl, msk; + + rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); + debugctl &= ~DEBUGCTLMSR_BTF; + msk = tifn & _TIF_BLOCKSTEP; + debugctl |= (msk >> TIF_BLOCKSTEP) << DEBUGCTLMSR_BTF_SHIFT; + wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); + } + + if ((tifp ^ tifn) & _TIF_NOTSC) + cr4_toggle_bits(X86_CR4_TSD); + + if ((tifp ^ tifn) & _TIF_NOCPUID) + set_cpuid_faulting(!!(tifn & _TIF_NOCPUID)); } /* @@ -550,3 +616,16 @@ out: put_task_stack(p); return ret; } + +long do_arch_prctl_common(struct task_struct *task, int option, + unsigned long cpuid_enabled) +{ + switch (option) { + case ARCH_GET_CPUID: + return get_cpuid_mode(); + case ARCH_SET_CPUID: + return set_cpuid_mode(task, cpuid_enabled); + } + + return -EINVAL; +} diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 4c818f8bc135..ff40e74c9181 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -37,6 +37,7 @@ #include <linux/uaccess.h> #include <linux/io.h> #include <linux/kdebug.h> +#include <linux/syscalls.h> #include <asm/pgtable.h> #include <asm/ldt.h> @@ -56,6 +57,7 @@ #include <asm/switch_to.h> #include <asm/vm86.h> #include <asm/intel_rdt.h> +#include <asm/proto.h> void __show_regs(struct pt_regs *regs, int all) { @@ -304,3 +306,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) return prev_p; } + +SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) +{ + return do_arch_prctl_common(current, option, arg2); +} diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index d6b784a5520d..ea1a6180bf39 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -37,6 +37,7 @@ #include <linux/uaccess.h> #include <linux/io.h> #include <linux/ftrace.h> +#include <linux/syscalls.h> #include <asm/pgtable.h> #include <asm/processor.h> @@ -204,7 +205,7 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long sp, (struct user_desc __user *)tls, 0); else #endif - err = do_arch_prctl(p, ARCH_SET_FS, tls); + err = do_arch_prctl_64(p, ARCH_SET_FS, tls); if (err) goto out; } @@ -547,70 +548,72 @@ static long prctl_map_vdso(const struct vdso_image *image, unsigned long addr) } #endif -long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) +long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2) { int ret = 0; int doit = task == current; int cpu; - switch (code) { + switch (option) { case ARCH_SET_GS: - if (addr >= TASK_SIZE_MAX) + if (arg2 >= TASK_SIZE_MAX) return -EPERM; cpu = get_cpu(); task->thread.gsindex = 0; - task->thread.gsbase = addr; + task->thread.gsbase = arg2; if (doit) { load_gs_index(0); - ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, addr); + ret = wrmsrl_safe(MSR_KERNEL_GS_BASE, arg2); } put_cpu(); break; case ARCH_SET_FS: /* Not strictly needed for fs, but do it for symmetry with gs */ - if (addr >= TASK_SIZE_MAX) + if (arg2 >= TASK_SIZE_MAX) return -EPERM; cpu = get_cpu(); task->thread.fsindex = 0; - task->thread.fsbase = addr; + task->thread.fsbase = arg2; if (doit) { /* set the selector to 0 to not confuse __switch_to */ loadsegment(fs, 0); - ret = wrmsrl_safe(MSR_FS_BASE, addr); + ret = wrmsrl_safe(MSR_FS_BASE, arg2); } put_cpu(); break; case ARCH_GET_FS: { unsigned long base; + if (doit) rdmsrl(MSR_FS_BASE, base); else base = task->thread.fsbase; - ret = put_user(base, (unsigned long __user *)addr); + ret = put_user(base, (unsigned long __user *)arg2); break; } case ARCH_GET_GS: { unsigned long base; + if (doit) rdmsrl(MSR_KERNEL_GS_BASE, base); else base = task->thread.gsbase; - ret = put_user(base, (unsigned long __user *)addr); + ret = put_user(base, (unsigned long __user *)arg2); break; } #ifdef CONFIG_CHECKPOINT_RESTORE # ifdef CONFIG_X86_X32_ABI case ARCH_MAP_VDSO_X32: - return prctl_map_vdso(&vdso_image_x32, addr); + return prctl_map_vdso(&vdso_image_x32, arg2); # endif # if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION case ARCH_MAP_VDSO_32: - return prctl_map_vdso(&vdso_image_32, addr); + return prctl_map_vdso(&vdso_image_32, arg2); # endif case ARCH_MAP_VDSO_64: - return prctl_map_vdso(&vdso_image_64, addr); + return prctl_map_vdso(&vdso_image_64, arg2); #endif default: @@ -621,10 +624,23 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) return ret; } -long sys_arch_prctl(int code, unsigned long addr) +SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) +{ + long ret; + + ret = do_arch_prctl_64(current, option, arg2); + if (ret == -EINVAL) + ret = do_arch_prctl_common(current, option, arg2); + + return ret; +} + +#ifdef CONFIG_IA32_EMULATION +COMPAT_SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) { - return do_arch_prctl(current, code, addr); + return do_arch_prctl_common(current, option, arg2); } +#endif unsigned long KSTK_ESP(struct task_struct *task) { diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 2364b23ea3e5..f37d18124648 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -396,12 +396,12 @@ static int putreg(struct task_struct *child, if (value >= TASK_SIZE_MAX) return -EIO; /* - * When changing the segment base, use do_arch_prctl + * When changing the segment base, use do_arch_prctl_64 * to set either thread.fs or thread.fsindex and the * corresponding GDT slot. */ if (child->thread.fsbase != value) - return do_arch_prctl(child, ARCH_SET_FS, value); + return do_arch_prctl_64(child, ARCH_SET_FS, value); return 0; case offsetof(struct user_regs_struct,gs_base): /* @@ -410,7 +410,7 @@ static int putreg(struct task_struct *child, if (value >= TASK_SIZE_MAX) return -EIO; if (child->thread.gsbase != value) - return do_arch_prctl(child, ARCH_SET_GS, value); + return do_arch_prctl_64(child, ARCH_SET_GS, value); return 0; #endif } @@ -869,7 +869,7 @@ long arch_ptrace(struct task_struct *child, long request, Works just like arch_prctl, except that the arguments are reversed. */ case PTRACE_ARCH_PRCTL: - ret = do_arch_prctl(child, data, addr); + ret = do_arch_prctl_64(child, data, addr); break; #endif diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 067f9813fd2c..2544700a2a87 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -765,10 +765,11 @@ void machine_crash_shutdown(struct pt_regs *regs) #endif +/* This is the CPU performing the emergency shutdown work. */ +int crashing_cpu = -1; + #if defined(CONFIG_SMP) -/* This keeps a track of which one is crashing cpu. */ -static int crashing_cpu; static nmi_shootdown_cb shootdown_callback; static atomic_t waiting_for_crash_ipi; diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c index 2408c1603438..5ab3895516ac 100644 --- a/arch/x86/kernel/resource.c +++ b/arch/x86/kernel/resource.c @@ -1,5 +1,5 @@ #include <linux/ioport.h> -#include <asm/e820.h> +#include <asm/e820/api.h> static void resource_clip(struct resource *res, resource_size_t start, resource_size_t end) @@ -25,10 +25,10 @@ static void resource_clip(struct resource *res, resource_size_t start, static void remove_e820_regions(struct resource *avail) { int i; - struct e820entry *entry; + struct e820_entry *entry; - for (i = 0; i < e820->nr_map; i++) { - entry = &e820->map[i]; + for (i = 0; i < e820_table->nr_entries; i++) { + entry = &e820_table->entries[i]; resource_clip(avail, entry->addr, entry->addr + entry->size - 1); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 4bf0c8926a1c..62a1c74855e5 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -75,7 +75,7 @@ #include <asm/mtrr.h> #include <asm/apic.h> #include <asm/realmode.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/mpspec.h> #include <asm/setup.h> #include <asm/efi.h> @@ -119,7 +119,7 @@ * max_low_pfn_mapped: highest direct mapped pfn under 4GB * max_pfn_mapped: highest direct mapped pfn over 4GB * - * The direct mapping only covers E820_RAM regions, so the ranges and gaps are + * The direct mapping only covers E820_TYPE_RAM regions, so the ranges and gaps are * represented by pfn_mapped */ unsigned long max_low_pfn_mapped; @@ -173,14 +173,11 @@ static struct resource bss_resource = { #ifdef CONFIG_X86_32 -/* cpu data as detected by the assembly code in head.S */ -struct cpuinfo_x86 new_cpu_data = { - .wp_works_ok = -1, -}; +/* cpu data as detected by the assembly code in head_32.S */ +struct cpuinfo_x86 new_cpu_data; + /* common cpu data for all cpus */ -struct cpuinfo_x86 boot_cpu_data __read_mostly = { - .wp_works_ok = -1, -}; +struct cpuinfo_x86 boot_cpu_data __read_mostly; EXPORT_SYMBOL(boot_cpu_data); unsigned int def_to_bigsmp; @@ -426,7 +423,7 @@ static void __init parse_setup_data(void) switch (data_type) { case SETUP_E820_EXT: - parse_e820_ext(pa_data, data_len); + e820__memory_setup_extended(pa_data, data_len); break; case SETUP_DTB: add_dtb(pa_data); @@ -441,29 +438,6 @@ static void __init parse_setup_data(void) } } -static void __init e820_reserve_setup_data(void) -{ - struct setup_data *data; - u64 pa_data; - - pa_data = boot_params.hdr.setup_data; - if (!pa_data) - return; - - while (pa_data) { - data = early_memremap(pa_data, sizeof(*data)); - e820_update_range(pa_data, sizeof(*data)+data->len, - E820_RAM, E820_RESERVED_KERN); - pa_data = data->next; - early_memunmap(data, sizeof(*data)); - } - - sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map); - memcpy(e820_saved, e820, sizeof(struct e820map)); - printk(KERN_INFO "extended physical RAM map:\n"); - e820_print_map("reserve setup_data"); -} - static void __init memblock_x86_reserve_range_setup_data(void) { struct setup_data *data; @@ -756,16 +730,16 @@ static void __init trim_bios_range(void) * since some BIOSes are known to corrupt low memory. See the * Kconfig help text for X86_RESERVE_LOW. */ - e820_update_range(0, PAGE_SIZE, E820_RAM, E820_RESERVED); + e820__range_update(0, PAGE_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); /* * special case: Some BIOSen report the PC BIOS * area (640->1Mb) as ram even though it is not. * take them out. */ - e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1); + e820__range_remove(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_TYPE_RAM, 1); - sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map); + e820__update_table(e820_table); } /* called before trim_bios_range() to spare extra sanitize */ @@ -775,18 +749,18 @@ static void __init e820_add_kernel_range(void) u64 size = __pa_symbol(_end) - start; /* - * Complain if .text .data and .bss are not marked as E820_RAM and + * Complain if .text .data and .bss are not marked as E820_TYPE_RAM and * attempt to fix it by adding the range. We may have a confused BIOS, * or the user may have used memmap=exactmap or memmap=xxM$yyM to * exclude kernel range. If we really are running on top non-RAM, * we will crash later anyways. */ - if (e820_all_mapped(start, start + size, E820_RAM)) + if (e820__mapped_all(start, start + size, E820_TYPE_RAM)) return; - pr_warn(".text .data .bss are not marked as E820_RAM!\n"); - e820_remove_range(start, size, E820_RAM, 0); - e820_add_region(start, size, E820_RAM); + pr_warn(".text .data .bss are not marked as E820_TYPE_RAM!\n"); + e820__range_remove(start, size, E820_TYPE_RAM, 0); + e820__range_add(start, size, E820_TYPE_RAM); } static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10; @@ -939,7 +913,7 @@ void __init setup_arch(char **cmdline_p) x86_init.oem.arch_setup(); iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1; - setup_memory_map(); + e820__memory_setup(); parse_setup_data(); copy_edd(); @@ -1028,9 +1002,8 @@ void __init setup_arch(char **cmdline_p) early_dump_pci_devices(); #endif - /* update the e820_saved too */ - e820_reserve_setup_data(); - finish_e820_parsing(); + e820__reserve_setup_data(); + e820__finish_early_params(); if (efi_enabled(EFI_BOOT)) efi_init(); @@ -1056,11 +1029,11 @@ void __init setup_arch(char **cmdline_p) trim_bios_range(); #ifdef CONFIG_X86_32 if (ppro_with_ram_bug()) { - e820_update_range(0x70000000ULL, 0x40000ULL, E820_RAM, - E820_RESERVED); - sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map); + e820__range_update(0x70000000ULL, 0x40000ULL, E820_TYPE_RAM, + E820_TYPE_RESERVED); + e820__update_table(e820_table); printk(KERN_INFO "fixed physical RAM map:\n"); - e820_print_map("bad_ppro"); + e820__print_table("bad_ppro"); } #else early_gart_iommu_check(); @@ -1070,12 +1043,12 @@ void __init setup_arch(char **cmdline_p) * partially used pages are not usable - thus * we are rounding upwards: */ - max_pfn = e820_end_of_ram_pfn(); + max_pfn = e820__end_of_ram_pfn(); /* update e820 for memory not covered by WB MTRRs */ mtrr_bp_init(); if (mtrr_trim_uncached_memory(max_pfn)) - max_pfn = e820_end_of_ram_pfn(); + max_pfn = e820__end_of_ram_pfn(); max_possible_pfn = max_pfn; @@ -1094,7 +1067,7 @@ void __init setup_arch(char **cmdline_p) /* How many end-of-memory variables you have, grandma! */ /* need this before calling reserve_initrd */ if (max_pfn > (1UL<<(32 - PAGE_SHIFT))) - max_low_pfn = e820_end_of_low_ram_pfn(); + max_low_pfn = e820__end_of_low_ram_pfn(); else max_low_pfn = max_pfn; @@ -1111,7 +1084,7 @@ void __init setup_arch(char **cmdline_p) early_alloc_pgt_buf(); /* - * Need to conclude brk, before memblock_x86_fill() + * Need to conclude brk, before e820__memblock_setup() * it could use memblock_find_in_range, could overlap with * brk area. */ @@ -1120,7 +1093,7 @@ void __init setup_arch(char **cmdline_p) cleanup_highmap(); memblock_set_current_limit(ISA_END_ADDRESS); - memblock_x86_fill(); + e820__memblock_setup(); reserve_bios_regions(); @@ -1137,7 +1110,7 @@ void __init setup_arch(char **cmdline_p) } /* preallocate 4k for mptable mpc */ - early_reserve_e820_mpc_new(); + e820__memblock_alloc_reserved_mpc_new(); #ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION setup_bios_corruption_check(); @@ -1275,12 +1248,12 @@ void __init setup_arch(char **cmdline_p) kvm_guest_init(); - e820_reserve_resources(); - e820_mark_nosave_regions(max_low_pfn); + e820__reserve_resources(); + e820__register_nosave_regions(max_low_pfn); x86_init.resources.reserve_resources(); - e820_setup_gap(); + e820__setup_pci_gap(); #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 396c042e9d0e..cc30a74e4adb 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -846,7 +846,7 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where) task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, me->comm, me->pid, where, frame, regs->ip, regs->sp, regs->orig_ax); - print_vma_addr(" in ", regs->ip); + print_vma_addr(KERN_CONT " in ", regs->ip); pr_cont("\n"); } diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c index ec1f756f9dc9..71beb28600d4 100644 --- a/arch/x86/kernel/signal_compat.c +++ b/arch/x86/kernel/signal_compat.c @@ -151,8 +151,8 @@ int __copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from, if (from->si_signo == SIGSEGV) { if (from->si_code == SEGV_BNDERR) { - compat_uptr_t lower = (unsigned long)&to->si_lower; - compat_uptr_t upper = (unsigned long)&to->si_upper; + compat_uptr_t lower = (unsigned long)from->si_lower; + compat_uptr_t upper = (unsigned long)from->si_upper; put_user_ex(lower, &to->si_lower); put_user_ex(upper, &to->si_upper); } diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index d3c66a15bbde..d798c0da451c 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c @@ -33,6 +33,7 @@ #include <asm/mce.h> #include <asm/trace/irq_vectors.h> #include <asm/kexec.h> +#include <asm/virtext.h> /* * Some notes on x86 processor bugs affecting SMP operation: @@ -124,7 +125,7 @@ static bool smp_no_nmi_ipi = false; static void native_smp_send_reschedule(int cpu) { if (unlikely(cpu_is_offline(cpu))) { - WARN_ON(1); + WARN(1, "sched: Unexpected reschedule of offline CPU#%d!\n", cpu); return; } apic->send_IPI(cpu, RESCHEDULE_VECTOR); @@ -162,6 +163,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs) if (raw_smp_processor_id() == atomic_read(&stopping_cpu)) return NMI_HANDLED; + cpu_emergency_vmxoff(); stop_this_cpu(NULL); return NMI_HANDLED; @@ -174,6 +176,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs) asmlinkage __visible void smp_reboot_interrupt(void) { ipi_entering_ack_irq(); + cpu_emergency_vmxoff(); stop_this_cpu(NULL); irq_exit(); } diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index b868fa1b812b..ccccd335ae01 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c @@ -42,7 +42,7 @@ #include <asm/fixmap.h> #include <asm/proto.h> #include <asm/setup.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/io.h> #include "../realmode/rm/wakeup.h" @@ -68,9 +68,9 @@ void __init tboot_probe(void) * also verify that it is mapped as we expect it before calling * set_fixmap(), to reduce chance of garbage value causing crash */ - if (!e820_any_mapped(boot_params.tboot_addr, - boot_params.tboot_addr, E820_RESERVED)) { - pr_warning("non-0 tboot_addr but it is not of type E820_RESERVED\n"); + if (!e820__mapped_any(boot_params.tboot_addr, + boot_params.tboot_addr, E820_TYPE_RESERVED)) { + pr_warning("non-0 tboot_addr but it is not of type E820_TYPE_RESERVED\n"); return; } @@ -188,12 +188,12 @@ static int tboot_setup_sleep(void) tboot->num_mac_regions = 0; - for (i = 0; i < e820->nr_map; i++) { - if ((e820->map[i].type != E820_RAM) - && (e820->map[i].type != E820_RESERVED_KERN)) + for (i = 0; i < e820_table->nr_entries; i++) { + if ((e820_table->entries[i].type != E820_TYPE_RAM) + && (e820_table->entries[i].type != E820_TYPE_RESERVED_KERN)) continue; - add_mac_region(e820->map[i].addr, e820->map[i].size); + add_mac_region(e820_table->entries[i].addr, e820_table->entries[i].size); } tboot->acpi_sinfo.kernel_s3_resume_vector = diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 948443e115c1..3995d3a777d4 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -169,6 +169,37 @@ void ist_end_non_atomic(void) preempt_disable(); } +int is_valid_bugaddr(unsigned long addr) +{ + unsigned short ud; + + if (addr < TASK_SIZE_MAX) + return 0; + + if (probe_kernel_address((unsigned short *)addr, ud)) + return 0; + + return ud == INSN_UD0 || ud == INSN_UD2; +} + +static int fixup_bug(struct pt_regs *regs, int trapnr) +{ + if (trapnr != X86_TRAP_UD) + return 0; + + switch (report_bug(regs->ip, regs)) { + case BUG_TRAP_TYPE_NONE: + case BUG_TRAP_TYPE_BUG: + break; + + case BUG_TRAP_TYPE_WARN: + regs->ip += LEN_UD0; + return 1; + } + + return 0; +} + static nokprobe_inline int do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, struct pt_regs *regs, long error_code) @@ -187,12 +218,15 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, } if (!user_mode(regs)) { - if (!fixup_exception(regs, trapnr)) { - tsk->thread.error_code = error_code; - tsk->thread.trap_nr = trapnr; - die(str, regs, error_code); - } - return 0; + if (fixup_exception(regs, trapnr)) + return 0; + + if (fixup_bug(regs, trapnr)) + return 0; + + tsk->thread.error_code = error_code; + tsk->thread.trap_nr = trapnr; + die(str, regs, error_code); } return -1; @@ -255,7 +289,7 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx", tsk->comm, tsk->pid, str, regs->ip, regs->sp, error_code); - print_vma_addr(" in ", regs->ip); + print_vma_addr(KERN_CONT " in ", regs->ip); pr_cont("\n"); } @@ -519,7 +553,7 @@ do_general_protection(struct pt_regs *regs, long error_code) pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx", tsk->comm, task_pid_nr(tsk), regs->ip, regs->sp, error_code); - print_vma_addr(" in ", regs->ip); + print_vma_addr(KERN_CONT " in ", regs->ip); pr_cont("\n"); } diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index c73a7f9e881a..714dfba6a1e7 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -328,7 +328,7 @@ unsigned long long sched_clock(void) return paravirt_sched_clock(); } -static inline bool using_native_sched_clock(void) +bool using_native_sched_clock(void) { return pv_time_ops.sched_clock == native_sched_clock; } @@ -336,7 +336,7 @@ static inline bool using_native_sched_clock(void) unsigned long long sched_clock(void) __attribute__((alias("native_sched_clock"))); -static inline bool using_native_sched_clock(void) { return true; } +bool using_native_sched_clock(void) { return true; } #endif int check_tsc_unstable(void) diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c index 08339262b666..fec70fe3b1ec 100644 --- a/arch/x86/kernel/unwind_frame.c +++ b/arch/x86/kernel/unwind_frame.c @@ -1,6 +1,8 @@ #include <linux/sched.h> #include <linux/sched/task.h> #include <linux/sched/task_stack.h> +#include <linux/interrupt.h> +#include <asm/sections.h> #include <asm/ptrace.h> #include <asm/bitops.h> #include <asm/stacktrace.h> @@ -23,53 +25,53 @@ val; \ }) -static void unwind_dump(struct unwind_state *state, unsigned long *sp) +static void unwind_dump(struct unwind_state *state) { static bool dumped_before = false; bool prev_zero, zero = false; - unsigned long word; + unsigned long word, *sp; + struct stack_info stack_info = {0}; + unsigned long visit_mask = 0; if (dumped_before) return; dumped_before = true; - printk_deferred("unwind stack type:%d next_sp:%p mask:%lx graph_idx:%d\n", + printk_deferred("unwind stack type:%d next_sp:%p mask:0x%lx graph_idx:%d\n", state->stack_info.type, state->stack_info.next_sp, state->stack_mask, state->graph_idx); - for (sp = state->orig_sp; sp < state->stack_info.end; sp++) { - word = READ_ONCE_NOCHECK(*sp); + for (sp = state->orig_sp; sp; sp = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { + if (get_stack_info(sp, state->task, &stack_info, &visit_mask)) + break; - prev_zero = zero; - zero = word == 0; + for (; sp < stack_info.end; sp++) { - if (zero) { - if (!prev_zero) - printk_deferred("%p: %016x ...\n", sp, 0); - continue; - } + word = READ_ONCE_NOCHECK(*sp); + + prev_zero = zero; + zero = word == 0; + + if (zero) { + if (!prev_zero) + printk_deferred("%p: %0*x ...\n", + sp, BITS_PER_LONG/4, 0); + continue; + } - printk_deferred("%p: %016lx (%pB)\n", sp, word, (void *)word); + printk_deferred("%p: %0*lx (%pB)\n", + sp, BITS_PER_LONG/4, word, (void *)word); + } } } unsigned long unwind_get_return_address(struct unwind_state *state) { - unsigned long addr; - unsigned long *addr_p = unwind_get_return_address_ptr(state); - if (unwind_done(state)) return 0; - if (state->regs && user_mode(state->regs)) - return 0; - - addr = READ_ONCE_TASK_STACK(state->task, *addr_p); - addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, addr, - addr_p); - - return __kernel_text_address(addr) ? addr : 0; + return __kernel_text_address(state->ip) ? state->ip : 0; } EXPORT_SYMBOL_GPL(unwind_get_return_address); @@ -82,16 +84,41 @@ static size_t regs_size(struct pt_regs *regs) return sizeof(*regs); } +static bool in_entry_code(unsigned long ip) +{ + char *addr = (char *)ip; + + if (addr >= __entry_text_start && addr < __entry_text_end) + return true; + +#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN) + if (addr >= __irqentry_text_start && addr < __irqentry_text_end) + return true; +#endif + + return false; +} + +static inline unsigned long *last_frame(struct unwind_state *state) +{ + return (unsigned long *)task_pt_regs(state->task) - 2; +} + #ifdef CONFIG_X86_32 #define GCC_REALIGN_WORDS 3 #else #define GCC_REALIGN_WORDS 1 #endif +static inline unsigned long *last_aligned_frame(struct unwind_state *state) +{ + return last_frame(state) - GCC_REALIGN_WORDS; +} + static bool is_last_task_frame(struct unwind_state *state) { - unsigned long *last_bp = (unsigned long *)task_pt_regs(state->task) - 2; - unsigned long *aligned_bp = last_bp - GCC_REALIGN_WORDS; + unsigned long *last_bp = last_frame(state); + unsigned long *aligned_bp = last_aligned_frame(state); /* * We have to check for the last task frame at two different locations @@ -135,26 +162,70 @@ static struct pt_regs *decode_frame_pointer(unsigned long *bp) return (struct pt_regs *)(regs & ~0x1); } -static bool update_stack_state(struct unwind_state *state, void *addr, - size_t len) +static bool update_stack_state(struct unwind_state *state, + unsigned long *next_bp) { struct stack_info *info = &state->stack_info; - enum stack_type orig_type = info->type; + enum stack_type prev_type = info->type; + struct pt_regs *regs; + unsigned long *frame, *prev_frame_end, *addr_p, addr; + size_t len; + + if (state->regs) + prev_frame_end = (void *)state->regs + regs_size(state->regs); + else + prev_frame_end = (void *)state->bp + FRAME_HEADER_SIZE; + + /* Is the next frame pointer an encoded pointer to pt_regs? */ + regs = decode_frame_pointer(next_bp); + if (regs) { + frame = (unsigned long *)regs; + len = regs_size(regs); + state->got_irq = true; + } else { + frame = next_bp; + len = FRAME_HEADER_SIZE; + } /* - * If addr isn't on the current stack, switch to the next one. + * If the next bp isn't on the current stack, switch to the next one. * * We may have to traverse multiple stacks to deal with the possibility - * that 'info->next_sp' could point to an empty stack and 'addr' could - * be on a subsequent stack. + * that info->next_sp could point to an empty stack and the next bp + * could be on a subsequent stack. */ - while (!on_stack(info, addr, len)) + while (!on_stack(info, frame, len)) if (get_stack_info(info->next_sp, state->task, info, &state->stack_mask)) return false; - if (!state->orig_sp || info->type != orig_type) - state->orig_sp = addr; + /* Make sure it only unwinds up and doesn't overlap the prev frame: */ + if (state->orig_sp && state->stack_info.type == prev_type && + frame < prev_frame_end) + return false; + + /* Move state to the next frame: */ + if (regs) { + state->regs = regs; + state->bp = NULL; + } else { + state->bp = next_bp; + state->regs = NULL; + } + + /* Save the return address: */ + if (state->regs && user_mode(state->regs)) + state->ip = 0; + else { + addr_p = unwind_get_return_address_ptr(state); + addr = READ_ONCE_TASK_STACK(state->task, *addr_p); + state->ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, + addr, addr_p); + } + + /* Save the original stack pointer for unwind_dump(): */ + if (!state->orig_sp) + state->orig_sp = frame; return true; } @@ -162,14 +233,12 @@ static bool update_stack_state(struct unwind_state *state, void *addr, bool unwind_next_frame(struct unwind_state *state) { struct pt_regs *regs; - unsigned long *next_bp, *next_frame; - size_t next_len; - enum stack_type prev_type = state->stack_info.type; + unsigned long *next_bp; if (unwind_done(state)) return false; - /* have we reached the end? */ + /* Have we reached the end? */ if (state->regs && user_mode(state->regs)) goto the_end; @@ -197,54 +266,19 @@ bool unwind_next_frame(struct unwind_state *state) */ state->regs = regs; state->bp = NULL; + state->ip = 0; return true; } - /* get the next frame pointer */ + /* Get the next frame pointer: */ if (state->regs) next_bp = (unsigned long *)state->regs->bp; else - next_bp = (unsigned long *)READ_ONCE_TASK_STACK(state->task,*state->bp); - - /* is the next frame pointer an encoded pointer to pt_regs? */ - regs = decode_frame_pointer(next_bp); - if (regs) { - next_frame = (unsigned long *)regs; - next_len = sizeof(*regs); - } else { - next_frame = next_bp; - next_len = FRAME_HEADER_SIZE; - } - - /* make sure the next frame's data is accessible */ - if (!update_stack_state(state, next_frame, next_len)) { - /* - * Don't warn on bad regs->bp. An interrupt in entry code - * might cause a false positive warning. - */ - if (state->regs) - goto the_end; + next_bp = (unsigned long *)READ_ONCE_TASK_STACK(state->task, *state->bp); + /* Move to the next frame if it's safe: */ + if (!update_stack_state(state, next_bp)) goto bad_address; - } - - /* Make sure it only unwinds up and doesn't overlap the last frame: */ - if (state->stack_info.type == prev_type) { - if (state->regs && (void *)next_frame < (void *)state->regs + regs_size(state->regs)) - goto bad_address; - - if (state->bp && (void *)next_frame < (void *)state->bp + FRAME_HEADER_SIZE) - goto bad_address; - } - - /* move to the next frame */ - if (regs) { - state->regs = regs; - state->bp = NULL; - } else { - state->bp = next_bp; - state->regs = NULL; - } return true; @@ -259,18 +293,29 @@ bad_address: if (state->task != current) goto the_end; + /* + * Don't warn if the unwinder got lost due to an interrupt in entry + * code or in the C handler before the first frame pointer got set up: + */ + if (state->got_irq && in_entry_code(state->ip)) + goto the_end; + if (state->regs && + state->regs->sp >= (unsigned long)last_aligned_frame(state) && + state->regs->sp < (unsigned long)task_pt_regs(state->task)) + goto the_end; + if (state->regs) { printk_deferred_once(KERN_WARNING "WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n", state->regs, state->task->comm, - state->task->pid, next_frame); - unwind_dump(state, (unsigned long *)state->regs); + state->task->pid, next_bp); + unwind_dump(state); } else { printk_deferred_once(KERN_WARNING "WARNING: kernel stack frame pointer at %p in %s:%d has bad value %p\n", state->bp, state->task->comm, - state->task->pid, next_frame); - unwind_dump(state, state->bp); + state->task->pid, next_bp); + unwind_dump(state); } the_end: state->stack_info.type = STACK_TYPE_UNKNOWN; @@ -281,35 +326,24 @@ EXPORT_SYMBOL_GPL(unwind_next_frame); void __unwind_start(struct unwind_state *state, struct task_struct *task, struct pt_regs *regs, unsigned long *first_frame) { - unsigned long *bp, *frame; - size_t len; + unsigned long *bp; memset(state, 0, sizeof(*state)); state->task = task; + state->got_irq = (regs); - /* don't even attempt to start from user mode regs */ + /* Don't even attempt to start from user mode regs: */ if (regs && user_mode(regs)) { state->stack_info.type = STACK_TYPE_UNKNOWN; return; } - /* set up the starting stack frame */ bp = get_frame_pointer(task, regs); - regs = decode_frame_pointer(bp); - if (regs) { - state->regs = regs; - frame = (unsigned long *)regs; - len = sizeof(*regs); - } else { - state->bp = bp; - frame = bp; - len = FRAME_HEADER_SIZE; - } - /* initialize stack info and make sure the frame data is accessible */ - get_stack_info(frame, state->task, &state->stack_info, + /* Initialize stack info and make sure the frame data is accessible: */ + get_stack_info(bp, state->task, &state->stack_info, &state->stack_mask); - update_stack_state(state, frame, len); + update_stack_state(state, bp); /* * The caller can provide the address of the first frame directly diff --git a/arch/x86/kernel/unwind_guess.c b/arch/x86/kernel/unwind_guess.c index 22881ddcbb9f..039f36738e49 100644 --- a/arch/x86/kernel/unwind_guess.c +++ b/arch/x86/kernel/unwind_guess.c @@ -34,7 +34,7 @@ bool unwind_next_frame(struct unwind_state *state) return true; } - state->sp = info->next_sp; + state->sp = PTR_ALIGN(info->next_sp, sizeof(long)); } while (!get_stack_info(state->sp, state->task, info, &state->stack_mask)); @@ -49,7 +49,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, memset(state, 0, sizeof(*state)); state->task = task; - state->sp = first_frame; + state->sp = PTR_ALIGN(first_frame, sizeof(long)); get_stack_info(first_frame, state->task, &state->stack_info, &state->stack_mask); diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index c74ae9ce8dc4..c8a3b61be0aa 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -146,6 +146,7 @@ SECTIONS _edata = .; } :data + BUG_TABLE . = ALIGN(PAGE_SIZE); __vvar_page = .; diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index 11a93f005268..a088b2c47f73 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -14,7 +14,7 @@ #include <asm/mpspec.h> #include <asm/setup.h> #include <asm/apic.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/time.h> #include <asm/irq.h> #include <asm/io_apic.h> @@ -38,7 +38,7 @@ struct x86_init_ops x86_init __initdata = { .resources = { .probe_roms = probe_roms, .reserve_resources = reserve_standard_io_resources, - .memory_setup = default_machine_specific_memory_setup, + .memory_setup = e820__memory_setup_default, }, .mpparse = { diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 2ee00dbbbd51..259e9b28ccf8 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -8198,6 +8198,9 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) return nested_cpu_has2(vmcs12, SECONDARY_EXEC_XSAVES); case EXIT_REASON_PREEMPTION_TIMER: return false; + case EXIT_REASON_PML_FULL: + /* We don't expose PML support to L1. */ + return false; default: return true; } @@ -10267,6 +10270,18 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, } + if (enable_pml) { + /* + * Conceptually we want to copy the PML address and index from + * vmcs01 here, and then back to vmcs01 on nested vmexit. But, + * since we always flush the log on each vmexit, this happens + * to be equivalent to simply resetting the fields in vmcs02. + */ + ASSERT(vmx->pml_pg); + vmcs_write64(PML_ADDRESS, page_to_phys(vmx->pml_pg)); + vmcs_write16(GUEST_PML_INDEX, PML_ENTITY_NUM - 1); + } + if (nested_cpu_has_ept(vmcs12)) { kvm_mmu_unload(vcpu); nested_ept_init_mmu_context(vcpu); diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index d3289d7e78fa..99472698c931 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -67,7 +67,7 @@ #include <asm/pgtable.h> #include <asm/desc.h> #include <asm/setup.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/mce.h> #include <asm/io.h> #include <asm/fpu/api.h> @@ -994,7 +994,9 @@ static struct clock_event_device lguest_clockevent = { .mult = 1, .shift = 0, .min_delta_ns = LG_CLOCK_MIN_DELTA, + .min_delta_ticks = LG_CLOCK_MIN_DELTA, .max_delta_ns = LG_CLOCK_MAX_DELTA, + .max_delta_ticks = LG_CLOCK_MAX_DELTA, }; /* @@ -1178,9 +1180,9 @@ static __init char *lguest_memory_setup(void) * The Linux bootloader header contains an "e820" memory map: the * Launcher populated the first entry with our memory limit. */ - e820_add_region(boot_params.e820_map[0].addr, - boot_params.e820_map[0].size, - boot_params.e820_map[0].type); + e820__range_add(boot_params.e820_table[0].addr, + boot_params.e820_table[0].size, + boot_params.e820_table[0].type); /* This string is for the boot messages. */ return "LGUEST"; diff --git a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S index 5e2af3a88cf5..81b1635d67de 100644 --- a/arch/x86/lib/clear_page_64.S +++ b/arch/x86/lib/clear_page_64.S @@ -14,20 +14,15 @@ * Zero a page. * %rdi - page */ -ENTRY(clear_page) - - ALTERNATIVE_2 "jmp clear_page_orig", "", X86_FEATURE_REP_GOOD, \ - "jmp clear_page_c_e", X86_FEATURE_ERMS - +ENTRY(clear_page_rep) movl $4096/8,%ecx xorl %eax,%eax rep stosq ret -ENDPROC(clear_page) -EXPORT_SYMBOL(clear_page) +ENDPROC(clear_page_rep) +EXPORT_SYMBOL_GPL(clear_page_rep) ENTRY(clear_page_orig) - xorl %eax,%eax movl $4096/64,%ecx .p2align 4 @@ -47,10 +42,12 @@ ENTRY(clear_page_orig) nop ret ENDPROC(clear_page_orig) +EXPORT_SYMBOL_GPL(clear_page_orig) -ENTRY(clear_page_c_e) +ENTRY(clear_page_erms) movl $4096,%ecx xorl %eax,%eax rep stosb ret -ENDPROC(clear_page_c_e) +ENDPROC(clear_page_erms) +EXPORT_SYMBOL_GPL(clear_page_erms) diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c index a8e91ae89fb3..29df077cb089 100644 --- a/arch/x86/lib/delay.c +++ b/arch/x86/lib/delay.c @@ -93,6 +93,13 @@ static void delay_mwaitx(unsigned long __loops) { u64 start, end, delay, loops = __loops; + /* + * Timer value of 0 causes MWAITX to wait indefinitely, unless there + * is a store on the memory monitored by MONITORX. + */ + if (loops == 0) + return; + start = rdtsc_ordered(); for (;;) { diff --git a/arch/x86/lib/kaslr.c b/arch/x86/lib/kaslr.c index 121f59c6ee54..5761a4f19455 100644 --- a/arch/x86/lib/kaslr.c +++ b/arch/x86/lib/kaslr.c @@ -8,7 +8,7 @@ #include <asm/kaslr.h> #include <asm/msr.h> #include <asm/archrandom.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/io.h> /* diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S index 779782f58324..9a53a06e5a3e 100644 --- a/arch/x86/lib/memcpy_64.S +++ b/arch/x86/lib/memcpy_64.S @@ -290,7 +290,7 @@ EXPORT_SYMBOL_GPL(memcpy_mcsafe_unrolled) _ASM_EXTABLE_FAULT(.L_copy_leading_bytes, .L_memcpy_mcsafe_fail) _ASM_EXTABLE_FAULT(.L_cache_w0, .L_memcpy_mcsafe_fail) _ASM_EXTABLE_FAULT(.L_cache_w1, .L_memcpy_mcsafe_fail) - _ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail) + _ASM_EXTABLE_FAULT(.L_cache_w2, .L_memcpy_mcsafe_fail) _ASM_EXTABLE_FAULT(.L_cache_w3, .L_memcpy_mcsafe_fail) _ASM_EXTABLE_FAULT(.L_cache_w4, .L_memcpy_mcsafe_fail) _ASM_EXTABLE_FAULT(.L_cache_w5, .L_memcpy_mcsafe_fail) diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c index c074799bddae..c8c6ad0d58b8 100644 --- a/arch/x86/lib/usercopy.c +++ b/arch/x86/lib/usercopy.c @@ -4,12 +4,9 @@ * For licencing details see kernel-base/COPYING */ -#include <linux/highmem.h> +#include <linux/uaccess.h> #include <linux/export.h> -#include <asm/word-at-a-time.h> -#include <linux/sched.h> - /* * We rely on the nested NMI work to allow atomic faults from the NMI path; the * nested NMI paths are careful to preserve CR2. @@ -34,52 +31,3 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) return ret; } EXPORT_SYMBOL_GPL(copy_from_user_nmi); - -/** - * copy_to_user: - Copy a block of data into user space. - * @to: Destination address, in user space. - * @from: Source address, in kernel space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from kernel space to user space. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - */ -unsigned long _copy_to_user(void __user *to, const void *from, unsigned n) -{ - if (access_ok(VERIFY_WRITE, to, n)) - n = __copy_to_user(to, from, n); - return n; -} -EXPORT_SYMBOL(_copy_to_user); - -/** - * copy_from_user: - Copy a block of data from user space. - * @to: Destination address, in kernel space. - * @from: Source address, in user space. - * @n: Number of bytes to copy. - * - * Context: User context only. This function may sleep if pagefaults are - * enabled. - * - * Copy data from user space to kernel space. - * - * Returns number of bytes that could not be copied. - * On success, this will be zero. - * - * If some data could not be copied, this function will pad the copied - * data to the requested size using zero bytes. - */ -unsigned long _copy_from_user(void *to, const void __user *from, unsigned n) -{ - if (access_ok(VERIFY_READ, from, n)) - n = __copy_from_user(to, from, n); - else - memset(to, 0, n); - return n; -} -EXPORT_SYMBOL(_copy_from_user); diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c index 1f65ff6540f0..bd057a4ffe6e 100644 --- a/arch/x86/lib/usercopy_32.c +++ b/arch/x86/lib/usercopy_32.c @@ -5,12 +5,7 @@ * Copyright 1997 Andi Kleen <ak@muc.de> * Copyright 1997 Linus Torvalds */ -#include <linux/mm.h> -#include <linux/highmem.h> -#include <linux/blkdev.h> #include <linux/export.h> -#include <linux/backing-dev.h> -#include <linux/interrupt.h> #include <linux/uaccess.h> #include <asm/mmx.h> #include <asm/asm.h> @@ -201,197 +196,6 @@ __copy_user_intel(void __user *to, const void *from, unsigned long size) return size; } -static unsigned long -__copy_user_zeroing_intel(void *to, const void __user *from, unsigned long size) -{ - int d0, d1; - __asm__ __volatile__( - " .align 2,0x90\n" - "0: movl 32(%4), %%eax\n" - " cmpl $67, %0\n" - " jbe 2f\n" - "1: movl 64(%4), %%eax\n" - " .align 2,0x90\n" - "2: movl 0(%4), %%eax\n" - "21: movl 4(%4), %%edx\n" - " movl %%eax, 0(%3)\n" - " movl %%edx, 4(%3)\n" - "3: movl 8(%4), %%eax\n" - "31: movl 12(%4),%%edx\n" - " movl %%eax, 8(%3)\n" - " movl %%edx, 12(%3)\n" - "4: movl 16(%4), %%eax\n" - "41: movl 20(%4), %%edx\n" - " movl %%eax, 16(%3)\n" - " movl %%edx, 20(%3)\n" - "10: movl 24(%4), %%eax\n" - "51: movl 28(%4), %%edx\n" - " movl %%eax, 24(%3)\n" - " movl %%edx, 28(%3)\n" - "11: movl 32(%4), %%eax\n" - "61: movl 36(%4), %%edx\n" - " movl %%eax, 32(%3)\n" - " movl %%edx, 36(%3)\n" - "12: movl 40(%4), %%eax\n" - "71: movl 44(%4), %%edx\n" - " movl %%eax, 40(%3)\n" - " movl %%edx, 44(%3)\n" - "13: movl 48(%4), %%eax\n" - "81: movl 52(%4), %%edx\n" - " movl %%eax, 48(%3)\n" - " movl %%edx, 52(%3)\n" - "14: movl 56(%4), %%eax\n" - "91: movl 60(%4), %%edx\n" - " movl %%eax, 56(%3)\n" - " movl %%edx, 60(%3)\n" - " addl $-64, %0\n" - " addl $64, %4\n" - " addl $64, %3\n" - " cmpl $63, %0\n" - " ja 0b\n" - "5: movl %0, %%eax\n" - " shrl $2, %0\n" - " andl $3, %%eax\n" - " cld\n" - "6: rep; movsl\n" - " movl %%eax,%0\n" - "7: rep; movsb\n" - "8:\n" - ".section .fixup,\"ax\"\n" - "9: lea 0(%%eax,%0,4),%0\n" - "16: pushl %0\n" - " pushl %%eax\n" - " xorl %%eax,%%eax\n" - " rep; stosb\n" - " popl %%eax\n" - " popl %0\n" - " jmp 8b\n" - ".previous\n" - _ASM_EXTABLE(0b,16b) - _ASM_EXTABLE(1b,16b) - _ASM_EXTABLE(2b,16b) - _ASM_EXTABLE(21b,16b) - _ASM_EXTABLE(3b,16b) - _ASM_EXTABLE(31b,16b) - _ASM_EXTABLE(4b,16b) - _ASM_EXTABLE(41b,16b) - _ASM_EXTABLE(10b,16b) - _ASM_EXTABLE(51b,16b) - _ASM_EXTABLE(11b,16b) - _ASM_EXTABLE(61b,16b) - _ASM_EXTABLE(12b,16b) - _ASM_EXTABLE(71b,16b) - _ASM_EXTABLE(13b,16b) - _ASM_EXTABLE(81b,16b) - _ASM_EXTABLE(14b,16b) - _ASM_EXTABLE(91b,16b) - _ASM_EXTABLE(6b,9b) - _ASM_EXTABLE(7b,16b) - : "=&c"(size), "=&D" (d0), "=&S" (d1) - : "1"(to), "2"(from), "0"(size) - : "eax", "edx", "memory"); - return size; -} - -/* - * Non Temporal Hint version of __copy_user_zeroing_intel. It is cache aware. - * hyoshiok@miraclelinux.com - */ - -static unsigned long __copy_user_zeroing_intel_nocache(void *to, - const void __user *from, unsigned long size) -{ - int d0, d1; - - __asm__ __volatile__( - " .align 2,0x90\n" - "0: movl 32(%4), %%eax\n" - " cmpl $67, %0\n" - " jbe 2f\n" - "1: movl 64(%4), %%eax\n" - " .align 2,0x90\n" - "2: movl 0(%4), %%eax\n" - "21: movl 4(%4), %%edx\n" - " movnti %%eax, 0(%3)\n" - " movnti %%edx, 4(%3)\n" - "3: movl 8(%4), %%eax\n" - "31: movl 12(%4),%%edx\n" - " movnti %%eax, 8(%3)\n" - " movnti %%edx, 12(%3)\n" - "4: movl 16(%4), %%eax\n" - "41: movl 20(%4), %%edx\n" - " movnti %%eax, 16(%3)\n" - " movnti %%edx, 20(%3)\n" - "10: movl 24(%4), %%eax\n" - "51: movl 28(%4), %%edx\n" - " movnti %%eax, 24(%3)\n" - " movnti %%edx, 28(%3)\n" - "11: movl 32(%4), %%eax\n" - "61: movl 36(%4), %%edx\n" - " movnti %%eax, 32(%3)\n" - " movnti %%edx, 36(%3)\n" - "12: movl 40(%4), %%eax\n" - "71: movl 44(%4), %%edx\n" - " movnti %%eax, 40(%3)\n" - " movnti %%edx, 44(%3)\n" - "13: movl 48(%4), %%eax\n" - "81: movl 52(%4), %%edx\n" - " movnti %%eax, 48(%3)\n" - " movnti %%edx, 52(%3)\n" - "14: movl 56(%4), %%eax\n" - "91: movl 60(%4), %%edx\n" - " movnti %%eax, 56(%3)\n" - " movnti %%edx, 60(%3)\n" - " addl $-64, %0\n" - " addl $64, %4\n" - " addl $64, %3\n" - " cmpl $63, %0\n" - " ja 0b\n" - " sfence \n" - "5: movl %0, %%eax\n" - " shrl $2, %0\n" - " andl $3, %%eax\n" - " cld\n" - "6: rep; movsl\n" - " movl %%eax,%0\n" - "7: rep; movsb\n" - "8:\n" - ".section .fixup,\"ax\"\n" - "9: lea 0(%%eax,%0,4),%0\n" - "16: pushl %0\n" - " pushl %%eax\n" - " xorl %%eax,%%eax\n" - " rep; stosb\n" - " popl %%eax\n" - " popl %0\n" - " jmp 8b\n" - ".previous\n" - _ASM_EXTABLE(0b,16b) - _ASM_EXTABLE(1b,16b) - _ASM_EXTABLE(2b,16b) - _ASM_EXTABLE(21b,16b) - _ASM_EXTABLE(3b,16b) - _ASM_EXTABLE(31b,16b) - _ASM_EXTABLE(4b,16b) - _ASM_EXTABLE(41b,16b) - _ASM_EXTABLE(10b,16b) - _ASM_EXTABLE(51b,16b) - _ASM_EXTABLE(11b,16b) - _ASM_EXTABLE(61b,16b) - _ASM_EXTABLE(12b,16b) - _ASM_EXTABLE(71b,16b) - _ASM_EXTABLE(13b,16b) - _ASM_EXTABLE(81b,16b) - _ASM_EXTABLE(14b,16b) - _ASM_EXTABLE(91b,16b) - _ASM_EXTABLE(6b,9b) - _ASM_EXTABLE(7b,16b) - : "=&c"(size), "=&D" (d0), "=&S" (d1) - : "1"(to), "2"(from), "0"(size) - : "eax", "edx", "memory"); - return size; -} - static unsigned long __copy_user_intel_nocache(void *to, const void __user *from, unsigned long size) { @@ -486,12 +290,8 @@ static unsigned long __copy_user_intel_nocache(void *to, * Leave these declared but undefined. They should not be any references to * them */ -unsigned long __copy_user_zeroing_intel(void *to, const void __user *from, - unsigned long size); unsigned long __copy_user_intel(void __user *to, const void *from, unsigned long size); -unsigned long __copy_user_zeroing_intel_nocache(void *to, - const void __user *from, unsigned long size); #endif /* CONFIG_X86_INTEL_USERCOPY */ /* Generic arbitrary sized copy. */ @@ -528,47 +328,7 @@ do { \ : "memory"); \ } while (0) -#define __copy_user_zeroing(to, from, size) \ -do { \ - int __d0, __d1, __d2; \ - __asm__ __volatile__( \ - " cmp $7,%0\n" \ - " jbe 1f\n" \ - " movl %1,%0\n" \ - " negl %0\n" \ - " andl $7,%0\n" \ - " subl %0,%3\n" \ - "4: rep; movsb\n" \ - " movl %3,%0\n" \ - " shrl $2,%0\n" \ - " andl $3,%3\n" \ - " .align 2,0x90\n" \ - "0: rep; movsl\n" \ - " movl %3,%0\n" \ - "1: rep; movsb\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "5: addl %3,%0\n" \ - " jmp 6f\n" \ - "3: lea 0(%3,%0,4),%0\n" \ - "6: pushl %0\n" \ - " pushl %%eax\n" \ - " xorl %%eax,%%eax\n" \ - " rep; stosb\n" \ - " popl %%eax\n" \ - " popl %0\n" \ - " jmp 2b\n" \ - ".previous\n" \ - _ASM_EXTABLE(4b,5b) \ - _ASM_EXTABLE(0b,3b) \ - _ASM_EXTABLE(1b,6b) \ - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ - : "3"(size), "0"(size), "1"(to), "2"(from) \ - : "memory"); \ -} while (0) - -unsigned long __copy_to_user_ll(void __user *to, const void *from, - unsigned long n) +unsigned long __copy_user_ll(void *to, const void *from, unsigned long n) { stac(); if (movsl_is_ok(to, from, n)) @@ -578,51 +338,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, clac(); return n; } -EXPORT_SYMBOL(__copy_to_user_ll); - -unsigned long __copy_from_user_ll(void *to, const void __user *from, - unsigned long n) -{ - stac(); - if (movsl_is_ok(to, from, n)) - __copy_user_zeroing(to, from, n); - else - n = __copy_user_zeroing_intel(to, from, n); - clac(); - return n; -} -EXPORT_SYMBOL(__copy_from_user_ll); - -unsigned long __copy_from_user_ll_nozero(void *to, const void __user *from, - unsigned long n) -{ - stac(); - if (movsl_is_ok(to, from, n)) - __copy_user(to, from, n); - else - n = __copy_user_intel((void __user *)to, - (const void *)from, n); - clac(); - return n; -} -EXPORT_SYMBOL(__copy_from_user_ll_nozero); - -unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, - unsigned long n) -{ - stac(); -#ifdef CONFIG_X86_INTEL_USERCOPY - if (n > 64 && static_cpu_has(X86_FEATURE_XMM2)) - n = __copy_user_zeroing_intel_nocache(to, from, n); - else - __copy_user_zeroing(to, from, n); -#else - __copy_user_zeroing(to, from, n); -#endif - clac(); - return n; -} -EXPORT_SYMBOL(__copy_from_user_ll_nocache); +EXPORT_SYMBOL(__copy_user_ll); unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from, unsigned long n) diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c index 69873589c0ba..3b7c40a2e3e1 100644 --- a/arch/x86/lib/usercopy_64.c +++ b/arch/x86/lib/usercopy_64.c @@ -54,15 +54,6 @@ unsigned long clear_user(void __user *to, unsigned long n) } EXPORT_SYMBOL(clear_user); -unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len) -{ - if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { - return copy_user_generic((__force void *)to, (__force void *)from, len); - } - return len; -} -EXPORT_SYMBOL(copy_in_user); - /* * Try to copy last bytes and clear the rest if needed. * Since protection fault in copy_from/to_user is not a normal situation, @@ -80,9 +71,5 @@ copy_user_handle_tail(char *to, char *from, unsigned len) break; } clac(); - - /* If the destination is a kernel buffer, we always clear the end */ - if (!__addr_ok(to)) - memset(to, 0, len); return len; } diff --git a/arch/x86/mm/amdtopology.c b/arch/x86/mm/amdtopology.c index d1c7de095808..91f501b2da3b 100644 --- a/arch/x86/mm/amdtopology.c +++ b/arch/x86/mm/amdtopology.c @@ -19,7 +19,7 @@ #include <asm/types.h> #include <asm/mmzone.h> #include <asm/proto.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/pci-direct.h> #include <asm/numa.h> #include <asm/mpspec.h> diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 22af912d66d2..138bad2fb6bc 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -6,7 +6,7 @@ #include <linux/bootmem.h> /* for max_low_pfn */ #include <asm/cacheflush.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/init.h> #include <asm/page.h> #include <asm/page_types.h> @@ -373,14 +373,14 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range, return nr_range; } -struct range pfn_mapped[E820_X_MAX]; +struct range pfn_mapped[E820_MAX_ENTRIES]; int nr_pfn_mapped; static void add_pfn_range_mapped(unsigned long start_pfn, unsigned long end_pfn) { - nr_pfn_mapped = add_range_with_merge(pfn_mapped, E820_X_MAX, + nr_pfn_mapped = add_range_with_merge(pfn_mapped, E820_MAX_ENTRIES, nr_pfn_mapped, start_pfn, end_pfn); - nr_pfn_mapped = clean_sort_range(pfn_mapped, E820_X_MAX); + nr_pfn_mapped = clean_sort_range(pfn_mapped, E820_MAX_ENTRIES); max_pfn_mapped = max(max_pfn_mapped, end_pfn); @@ -430,7 +430,7 @@ unsigned long __ref init_memory_mapping(unsigned long start, /* * We need to iterate through the E820 memory map and create direct mappings - * for only E820_RAM and E820_KERN_RESERVED regions. We cannot simply + * for only E820_TYPE_RAM and E820_KERN_RESERVED regions. We cannot simply * create direct mappings for all pfns from [0 to max_low_pfn) and * [4GB to max_pfn) because of possible memory holes in high addresses * that cannot be marked as UC by fixed/variable range MTRRs. @@ -643,21 +643,40 @@ void __init init_mem_mapping(void) * devmem_is_allowed() checks to see if /dev/mem access to a certain address * is valid. The argument is a physical page number. * - * - * On x86, access has to be given to the first megabyte of ram because that area - * contains BIOS code and data regions used by X and dosemu and similar apps. - * Access has to be given to non-kernel-ram areas as well, these contain the PCI - * mmio resources as well as potential bios/acpi data regions. + * On x86, access has to be given to the first megabyte of RAM because that + * area traditionally contains BIOS code and data regions used by X, dosemu, + * and similar apps. Since they map the entire memory range, the whole range + * must be allowed (for mapping), but any areas that would otherwise be + * disallowed are flagged as being "zero filled" instead of rejected. + * Access has to be given to non-kernel-ram areas as well, these contain the + * PCI mmio resources as well as potential bios/acpi data regions. */ int devmem_is_allowed(unsigned long pagenr) { - if (pagenr < 256) - return 1; - if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) + if (page_is_ram(pagenr)) { + /* + * For disallowed memory regions in the low 1MB range, + * request that the page be shown as all zeros. + */ + if (pagenr < 256) + return 2; + return 0; - if (!page_is_ram(pagenr)) - return 1; - return 0; + } + + /* + * This must follow RAM test, since System RAM is considered a + * restricted resource under CONFIG_STRICT_IOMEM. + */ + if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) { + /* Low 1MB bypasses iomem restrictions. */ + if (pagenr < 256) + return 1; + + return 0; + } + + return 1; } void free_init_pages(char *what, unsigned long begin, unsigned long end) @@ -701,7 +720,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) void __ref free_initmem(void) { - e820_reallocate_tables(); + e820__reallocate_tables(); free_init_pages("unused kernel", (unsigned long)(&__init_begin), @@ -724,6 +743,53 @@ void __init free_initrd_mem(unsigned long start, unsigned long end) } #endif +/* + * Calculate the precise size of the DMA zone (first 16 MB of RAM), + * and pass it to the MM layer - to help it set zone watermarks more + * accurately. + * + * Done on 64-bit systems only for the time being, although 32-bit systems + * might benefit from this as well. + */ +void __init memblock_find_dma_reserve(void) +{ +#ifdef CONFIG_X86_64 + u64 nr_pages = 0, nr_free_pages = 0; + unsigned long start_pfn, end_pfn; + phys_addr_t start_addr, end_addr; + int i; + u64 u; + + /* + * Iterate over all memory ranges (free and reserved ones alike), + * to calculate the total number of pages in the first 16 MB of RAM: + */ + nr_pages = 0; + for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) { + start_pfn = min(start_pfn, MAX_DMA_PFN); + end_pfn = min(end_pfn, MAX_DMA_PFN); + + nr_pages += end_pfn - start_pfn; + } + + /* + * Iterate over free memory ranges to calculate the number of free + * pages in the DMA zone, while not counting potential partial + * pages at the beginning or the end of the range: + */ + nr_free_pages = 0; + for_each_free_mem_range(u, NUMA_NO_NODE, MEMBLOCK_NONE, &start_addr, &end_addr, NULL) { + start_pfn = min_t(unsigned long, PFN_UP(start_addr), MAX_DMA_PFN); + end_pfn = min_t(unsigned long, PFN_DOWN(end_addr), MAX_DMA_PFN); + + if (start_pfn < end_pfn) + nr_free_pages += end_pfn - start_pfn; + } + + set_dma_reserve(nr_pages - nr_free_pages); +#endif +} + void __init zone_sizes_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES]; diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 2b4b53e6793f..030bfed10a6c 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -38,7 +38,7 @@ #include <asm/pgtable.h> #include <asm/dma.h> #include <asm/fixmap.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/apic.h> #include <asm/bugs.h> #include <asm/tlb.h> @@ -716,15 +716,17 @@ void __init paging_init(void) */ static void __init test_wp_bit(void) { + int wp_works_ok; + printk(KERN_INFO "Checking if this processor honours the WP bit even in supervisor mode..."); /* Any page-aligned address will do, the test is non-destructive */ __set_fixmap(FIX_WP_TEST, __pa(&swapper_pg_dir), PAGE_KERNEL_RO); - boot_cpu_data.wp_works_ok = do_test_wp_bit(); + wp_works_ok = do_test_wp_bit(); clear_fixmap(FIX_WP_TEST); - if (!boot_cpu_data.wp_works_ok) { + if (!wp_works_ok) { printk(KERN_CONT "No.\n"); panic("Linux doesn't support CPUs with broken WP."); } else { @@ -811,8 +813,7 @@ void __init mem_init(void) BUG_ON(VMALLOC_START >= VMALLOC_END); BUG_ON((unsigned long)high_memory > VMALLOC_START); - if (boot_cpu_data.wp_works_ok < 0) - test_wp_bit(); + test_wp_bit(); } #ifdef CONFIG_MEMORY_HOTPLUG diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 15173d37f399..f6da869810a8 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -41,7 +41,7 @@ #include <asm/pgalloc.h> #include <asm/dma.h> #include <asm/fixmap.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/apic.h> #include <asm/tlb.h> #include <asm/mmu_context.h> @@ -337,10 +337,10 @@ phys_pte_init(pte_t *pte_page, unsigned long paddr, unsigned long paddr_end, paddr_next = (paddr & PAGE_MASK) + PAGE_SIZE; if (paddr >= paddr_end) { if (!after_bootmem && - !e820_any_mapped(paddr & PAGE_MASK, paddr_next, - E820_RAM) && - !e820_any_mapped(paddr & PAGE_MASK, paddr_next, - E820_RESERVED_KERN)) + !e820__mapped_any(paddr & PAGE_MASK, paddr_next, + E820_TYPE_RAM) && + !e820__mapped_any(paddr & PAGE_MASK, paddr_next, + E820_TYPE_RESERVED_KERN)) set_pte(pte, __pte(0)); continue; } @@ -392,10 +392,10 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end, paddr_next = (paddr & PMD_MASK) + PMD_SIZE; if (paddr >= paddr_end) { if (!after_bootmem && - !e820_any_mapped(paddr & PMD_MASK, paddr_next, - E820_RAM) && - !e820_any_mapped(paddr & PMD_MASK, paddr_next, - E820_RESERVED_KERN)) + !e820__mapped_any(paddr & PMD_MASK, paddr_next, + E820_TYPE_RAM) && + !e820__mapped_any(paddr & PMD_MASK, paddr_next, + E820_TYPE_RESERVED_KERN)) set_pmd(pmd, __pmd(0)); continue; } @@ -478,10 +478,10 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, if (paddr >= paddr_end) { if (!after_bootmem && - !e820_any_mapped(paddr & PUD_MASK, paddr_next, - E820_RAM) && - !e820_any_mapped(paddr & PUD_MASK, paddr_next, - E820_RESERVED_KERN)) + !e820__mapped_any(paddr & PUD_MASK, paddr_next, + E820_TYPE_RAM) && + !e820__mapped_any(paddr & PUD_MASK, paddr_next, + E820_TYPE_RESERVED_KERN)) set_pud(pud, __pud(0)); continue; } diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 7aaa2635862d..c43b6b33463a 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -9,12 +9,13 @@ #include <linux/bootmem.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/ioport.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/mmiotrace.h> #include <asm/cacheflush.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/fixmap.h> #include <asm/pgtable.h> #include <asm/tlbflush.h> diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c index 4c90cfdc128b..da92df32d0f1 100644 --- a/arch/x86/mm/kasan_init_64.c +++ b/arch/x86/mm/kasan_init_64.c @@ -8,11 +8,12 @@ #include <linux/sched/task.h> #include <linux/vmalloc.h> +#include <asm/e820/types.h> #include <asm/tlbflush.h> #include <asm/sections.h> extern pgd_t early_level4_pgt[PTRS_PER_PGD]; -extern struct range pfn_mapped[E820_X_MAX]; +extern struct range pfn_mapped[E820_MAX_ENTRIES]; static int __init map_range(struct range *range) { @@ -104,7 +105,7 @@ void __init kasan_init(void) kasan_populate_zero_shadow((void *)KASAN_SHADOW_START, kasan_mem_to_shadow((void *)PAGE_OFFSET)); - for (i = 0; i < E820_X_MAX; i++) { + for (i = 0; i < E820_MAX_ENTRIES; i++) { if (pfn_mapped[i].end == 0) break; diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c index 887e57182716..aed206475aa7 100644 --- a/arch/x86/mm/kaslr.c +++ b/arch/x86/mm/kaslr.c @@ -48,7 +48,7 @@ static const unsigned long vaddr_start = __PAGE_OFFSET_BASE; #if defined(CONFIG_X86_ESPFIX64) static const unsigned long vaddr_end = ESPFIX_BASE_ADDR; #elif defined(CONFIG_EFI) -static const unsigned long vaddr_end = EFI_VA_START; +static const unsigned long vaddr_end = EFI_VA_END; #else static const unsigned long vaddr_end = __START_KERNEL_map; #endif @@ -105,7 +105,7 @@ void __init kernel_randomize_memory(void) */ BUILD_BUG_ON(vaddr_start >= vaddr_end); BUILD_BUG_ON(IS_ENABLED(CONFIG_X86_ESPFIX64) && - vaddr_end >= EFI_VA_START); + vaddr_end >= EFI_VA_END); BUILD_BUG_ON((IS_ENABLED(CONFIG_X86_ESPFIX64) || IS_ENABLED(CONFIG_EFI)) && vaddr_end >= __START_KERNEL_map); diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index bef36622e408..4d434ddb75db 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -32,7 +32,7 @@ #include <linux/kallsyms.h> #include <asm/pgtable.h> #include <linux/mmiotrace.h> -#include <asm/e820.h> /* for ISA_START_ADDRESS */ +#include <asm/e820/api.h> /* for ISA_START_ADDRESS */ #include <linux/atomic.h> #include <linux/percpu.h> #include <linux/cpu.h> diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index 12dcad7297a5..f9d99535f233 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c @@ -12,7 +12,7 @@ #include <linux/sched.h> #include <linux/topology.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/proto.h> #include <asm/dma.h> #include <asm/amd_nb.h> diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 28d42130243c..a57e8e02f457 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -15,7 +15,7 @@ #include <linux/pci.h> #include <linux/vmalloc.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/processor.h> #include <asm/tlbflush.h> #include <asm/sections.h> diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index efc32bc6862b..9b78685b66e6 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -10,6 +10,7 @@ #include <linux/seq_file.h> #include <linux/bootmem.h> #include <linux/debugfs.h> +#include <linux/ioport.h> #include <linux/kernel.h> #include <linux/pfn_t.h> #include <linux/slab.h> @@ -23,7 +24,7 @@ #include <asm/x86_init.h> #include <asm/pgtable.h> #include <asm/fcntl.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/mtrr.h> #include <asm/page.h> #include <asm/msr.h> diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index 9adce776852b..de53c52551a5 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c @@ -12,7 +12,7 @@ #include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/fixmap.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/tlb.h> #include <asm/tlbflush.h> #include <asm/io.h> diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c index 35fe69529bc1..3ea20d61b523 100644 --- a/arch/x86/mm/srat.c +++ b/arch/x86/mm/srat.c @@ -18,7 +18,7 @@ #include <linux/mm.h> #include <asm/proto.h> #include <asm/numa.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/apic.h> #include <asm/uv/uv.h> diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 0a9f2caf358f..6fa84d531f4f 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -34,7 +34,7 @@ #include <linux/bootmem.h> #include <asm/pat.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/pci_x86.h> #include <asm/io_apic.h> @@ -398,7 +398,7 @@ void __init pcibios_resource_survey(void) list_for_each_entry(bus, &pci_root_buses, node) pcibios_allocate_resources(bus, 1); - e820_reserve_resources_late(); + e820__reserve_resources_late(); /* * Insert the IO APIC resources after PCI initialization has * occurred to handle IO APICS that are mapped in on a BAR in diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index dd30b7e08bc2..d1b47d5bc9c3 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -18,7 +18,7 @@ #include <linux/slab.h> #include <linux/mutex.h> #include <linux/rculist.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/pci_x86.h> #include <asm/acpi.h> @@ -423,7 +423,7 @@ static acpi_status find_mboard_resource(acpi_handle handle, u32 lvl, return AE_OK; } -static int is_acpi_reserved(u64 start, u64 end, unsigned not_used) +static bool is_acpi_reserved(u64 start, u64 end, unsigned not_used) { struct resource mcfg_res; @@ -440,11 +440,11 @@ static int is_acpi_reserved(u64 start, u64 end, unsigned not_used) return mcfg_res.flags; } -typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); +typedef bool (*check_reserved_t)(u64 start, u64 end, unsigned type); -static int __ref is_mmconf_reserved(check_reserved_t is_reserved, - struct pci_mmcfg_region *cfg, - struct device *dev, int with_e820) +static bool __ref is_mmconf_reserved(check_reserved_t is_reserved, + struct pci_mmcfg_region *cfg, + struct device *dev, int with_e820) { u64 addr = cfg->res.start; u64 size = resource_size(&cfg->res); @@ -452,7 +452,7 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved, int num_buses; char *method = with_e820 ? "E820" : "ACPI motherboard resources"; - while (!is_reserved(addr, addr + size, E820_RESERVED)) { + while (!is_reserved(addr, addr + size, E820_TYPE_RESERVED)) { size >>= 1; if (size < (16UL<<20)) break; @@ -494,8 +494,8 @@ static int __ref is_mmconf_reserved(check_reserved_t is_reserved, return 1; } -static int __ref pci_mmcfg_check_reserved(struct device *dev, - struct pci_mmcfg_region *cfg, int early) +static bool __ref +pci_mmcfg_check_reserved(struct device *dev, struct pci_mmcfg_region *cfg, int early) { if (!early && !acpi_disabled) { if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0)) @@ -514,7 +514,7 @@ static int __ref pci_mmcfg_check_reserved(struct device *dev, } /* - * e820_all_mapped() is marked as __init. + * e820__mapped_all() is marked as __init. * All entries from ACPI MCFG table have been checked at boot time. * For MCFG information constructed from hotpluggable host bridge's * _CBA method, just assume it's reserved. @@ -525,7 +525,7 @@ static int __ref pci_mmcfg_check_reserved(struct device *dev, /* Don't try to do this check unless configuration type 1 is available. how about type 2 ?*/ if (raw_pci_ops) - return is_mmconf_reserved(e820_all_mapped, cfg, dev, 1); + return is_mmconf_reserved(e820__mapped_all, cfg, dev, 1); return 0; } diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index 43984bc1665a..3e9e166f6408 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c @@ -12,7 +12,7 @@ #include <linux/pci.h> #include <linux/init.h> #include <linux/rcupdate.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/pci_x86.h> /* Assume systems with more busses have correct MCFG */ diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index bea52496aea6..f1c1aa0430ae 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c @@ -10,7 +10,7 @@ #include <linux/acpi.h> #include <linux/bitmap.h> #include <linux/rcupdate.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/pci_x86.h> #define PREFIX "PCI: " diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index 1d97cea3b3a4..29e9ba6ace9d 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c @@ -7,7 +7,9 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/uaccess.h> + #include <asm/pci_x86.h> +#include <asm/e820/types.h> #include <asm/pci-functions.h> #include <asm/cacheflush.h> diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile index 066619b0700c..f1d83b34c329 100644 --- a/arch/x86/platform/efi/Makefile +++ b/arch/x86/platform/efi/Makefile @@ -1,6 +1,5 @@ OBJECT_FILES_NON_STANDARD_efi_thunk_$(BITS).o := y obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o -obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c deleted file mode 100644 index 04ca8764f0c0..000000000000 --- a/arch/x86/platform/efi/efi-bgrt.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012 Intel Corporation - * Author: Josh Triplett <josh@joshtriplett.org> - * - * Based on the bgrt driver: - * Copyright 2012 Red Hat, Inc <mjg@redhat.com> - * Author: Matthew Garrett - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/acpi.h> -#include <linux/efi.h> -#include <linux/efi-bgrt.h> - -struct acpi_table_bgrt bgrt_tab; -size_t __initdata bgrt_image_size; - -struct bmp_header { - u16 id; - u32 size; -} __packed; - -void __init efi_bgrt_init(struct acpi_table_header *table) -{ - void *image; - struct bmp_header bmp_header; - struct acpi_table_bgrt *bgrt = &bgrt_tab; - - if (acpi_disabled) - return; - - if (table->length < sizeof(bgrt_tab)) { - pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n", - table->length, sizeof(bgrt_tab)); - return; - } - *bgrt = *(struct acpi_table_bgrt *)table; - if (bgrt->version != 1) { - pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n", - bgrt->version); - goto out; - } - if (bgrt->status & 0xfe) { - pr_notice("Ignoring BGRT: reserved status bits are non-zero %u\n", - bgrt->status); - goto out; - } - if (bgrt->image_type != 0) { - pr_notice("Ignoring BGRT: invalid image type %u (expected 0)\n", - bgrt->image_type); - goto out; - } - if (!bgrt->image_address) { - pr_notice("Ignoring BGRT: null image address\n"); - goto out; - } - - image = early_memremap(bgrt->image_address, sizeof(bmp_header)); - if (!image) { - pr_notice("Ignoring BGRT: failed to map image header memory\n"); - goto out; - } - - memcpy(&bmp_header, image, sizeof(bmp_header)); - early_memunmap(image, sizeof(bmp_header)); - if (bmp_header.id != 0x4d42) { - pr_notice("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n", - bmp_header.id); - goto out; - } - bgrt_image_size = bmp_header.size; - efi_mem_reserve(bgrt->image_address, bgrt_image_size); - - return; -out: - memset(bgrt, 0, sizeof(bgrt_tab)); -} diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 565dff3c9a12..a15cf815ac4e 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -47,6 +47,7 @@ #include <asm/setup.h> #include <asm/efi.h> +#include <asm/e820/api.h> #include <asm/time.h> #include <asm/cacheflush.h> #include <asm/tlbflush.h> @@ -139,21 +140,21 @@ static void __init do_add_efi_memmap(void) case EFI_BOOT_SERVICES_DATA: case EFI_CONVENTIONAL_MEMORY: if (md->attribute & EFI_MEMORY_WB) - e820_type = E820_RAM; + e820_type = E820_TYPE_RAM; else - e820_type = E820_RESERVED; + e820_type = E820_TYPE_RESERVED; break; case EFI_ACPI_RECLAIM_MEMORY: - e820_type = E820_ACPI; + e820_type = E820_TYPE_ACPI; break; case EFI_ACPI_MEMORY_NVS: - e820_type = E820_NVS; + e820_type = E820_TYPE_NVS; break; case EFI_UNUSABLE_MEMORY: - e820_type = E820_UNUSABLE; + e820_type = E820_TYPE_UNUSABLE; break; case EFI_PERSISTENT_MEMORY: - e820_type = E820_PMEM; + e820_type = E820_TYPE_PMEM; break; default: /* @@ -161,12 +162,12 @@ static void __init do_add_efi_memmap(void) * EFI_RUNTIME_SERVICES_DATA EFI_MEMORY_MAPPED_IO * EFI_MEMORY_MAPPED_IO_PORT_SPACE EFI_PAL_CODE */ - e820_type = E820_RESERVED; + e820_type = E820_TYPE_RESERVED; break; } - e820_add_region(start, size, e820_type); + e820__range_add(start, size, e820_type); } - sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map); + e820__update_table(e820_table); } int __init efi_memblock_x86_reserve_range(void) diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index a4695da42d77..642a8698ad61 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -35,7 +35,7 @@ #include <asm/setup.h> #include <asm/page.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/pgtable.h> #include <asm/tlbflush.h> #include <asm/proto.h> @@ -47,7 +47,7 @@ #include <asm/pgalloc.h> /* - * We allocate runtime services regions bottom-up, starting from -4G, i.e. + * We allocate runtime services regions top-down, starting from -4G, i.e. * 0xffff_ffff_0000_0000 and limit EFI VA mapping space to 64G. */ static u64 efi_va = EFI_VA_START; diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 30031d5293c4..26615991d69c 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -11,6 +11,8 @@ #include <linux/bootmem.h> #include <linux/acpi.h> #include <linux/dmi.h> + +#include <asm/e820/api.h> #include <asm/efi.h> #include <asm/uv/uv.h> @@ -201,6 +203,10 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size) return; } + /* No need to reserve regions that will never be freed. */ + if (md.attribute & EFI_MEMORY_RUNTIME) + return; + size += addr % EFI_PAGE_SIZE; size = round_up(size, EFI_PAGE_SIZE); addr = round_down(addr, EFI_PAGE_SIZE); @@ -240,14 +246,14 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size) * else. We must only reserve (and then free) regions: * * - Not within any part of the kernel - * - Not the BIOS reserved area (E820_RESERVED, E820_NVS, etc) + * - Not the BIOS reserved area (E820_TYPE_RESERVED, E820_TYPE_NVS, etc) */ static bool can_free_region(u64 start, u64 size) { if (start + size > __pa_symbol(_text) && start <= __pa_symbol(_end)) return false; - if (!e820_all_mapped(start, start+size, E820_RAM)) + if (!e820__mapped_all(start, start+size, E820_TYPE_RAM)) return false; return true; @@ -280,7 +286,7 @@ void __init efi_reserve_boot_services(void) * A good example of a critical region that must not be * freed is page zero (first 4Kb of memory), which may * contain boot services code/data but is marked - * E820_RESERVED by trim_bios_range(). + * E820_TYPE_RESERVED by trim_bios_range(). */ if (!already_reserved) { memblock_reserve(start, size); diff --git a/arch/x86/platform/uv/uv_time.c b/arch/x86/platform/uv/uv_time.c index 2ee7632d4916..b082d71b08ee 100644 --- a/arch/x86/platform/uv/uv_time.c +++ b/arch/x86/platform/uv/uv_time.c @@ -390,9 +390,11 @@ static __init int uv_rtc_setup_clock(void) clock_event_device_uv.min_delta_ns = NSEC_PER_SEC / sn_rtc_cycles_per_second; + clock_event_device_uv.min_delta_ticks = 1; clock_event_device_uv.max_delta_ns = clocksource_uv.mask * (NSEC_PER_SEC / sn_rtc_cycles_per_second); + clock_event_device_uv.max_delta_ticks = clocksource_uv.mask; rc = schedule_on_each_cpu(uv_rtc_register_clockevents); if (rc) { diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c index ded2e8272382..053801b022dd 100644 --- a/arch/x86/power/hibernate_64.c +++ b/arch/x86/power/hibernate_64.c @@ -16,6 +16,7 @@ #include <crypto/hash.h> +#include <asm/e820/api.h> #include <asm/init.h> #include <asm/proto.h> #include <asm/page.h> @@ -195,12 +196,12 @@ struct restore_data_record { #if IS_BUILTIN(CONFIG_CRYPTO_MD5) /** - * get_e820_md5 - calculate md5 according to given e820 map + * get_e820_md5 - calculate md5 according to given e820 table * - * @map: the e820 map to be calculated + * @table: the e820 table to be calculated * @buf: the md5 result to be stored to */ -static int get_e820_md5(struct e820map *map, void *buf) +static int get_e820_md5(struct e820_table *table, void *buf) { struct scatterlist sg; struct crypto_ahash *tfm; @@ -213,10 +214,9 @@ static int get_e820_md5(struct e820map *map, void *buf) { AHASH_REQUEST_ON_STACK(req, tfm); - size = offsetof(struct e820map, map) - + sizeof(struct e820entry) * map->nr_map; + size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry) * table->nr_entries; ahash_request_set_tfm(req, tfm); - sg_init_one(&sg, (u8 *)map, size); + sg_init_one(&sg, (u8 *)table, size); ahash_request_set_callback(req, 0, NULL, NULL); ahash_request_set_crypt(req, &sg, buf, size); @@ -231,7 +231,7 @@ static int get_e820_md5(struct e820map *map, void *buf) static void hibernation_e820_save(void *buf) { - get_e820_md5(e820_saved, buf); + get_e820_md5(e820_table_firmware, buf); } static bool hibernation_e820_mismatch(void *buf) @@ -244,7 +244,7 @@ static bool hibernation_e820_mismatch(void *buf) if (!memcmp(result, buf, MD5_DIGEST_SIZE)) return false; - ret = get_e820_md5(e820_saved, result); + ret = get_e820_md5(e820_table_firmware, result); if (ret) return true; diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile index 555b9fa0ad43..7dbdb780264d 100644 --- a/arch/x86/purgatory/Makefile +++ b/arch/x86/purgatory/Makefile @@ -8,6 +8,7 @@ PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y)) LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib -z nodefaultlib targets += purgatory.ro +KASAN_SANITIZE := n KCOV_INSTRUMENT := n # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That diff --git a/arch/x86/ras/Kconfig b/arch/x86/ras/Kconfig index 0bc60a308730..2a2d89d39af6 100644 --- a/arch/x86/ras/Kconfig +++ b/arch/x86/ras/Kconfig @@ -7,3 +7,17 @@ config MCE_AMD_INJ aspects of the MCE handling code. WARNING: Do not even assume this interface is staying stable! + +config RAS_CEC + bool "Correctable Errors Collector" + depends on X86_MCE && MEMORY_FAILURE && DEBUG_FS + ---help--- + This is a small cache which collects correctable memory errors per 4K + page PFN and counts their repeated occurrence. Once the counter for a + PFN overflows, we try to soft-offline that page as we take it to mean + that it has reached a relatively high error count and would probably + be best if we don't use it anymore. + + Bear in mind that this is absolutely useless if your platform doesn't + have ECC DIMMs and doesn't have DRAM ECC checking enabled in the BIOS. + diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile index e7e7055a8658..46cbbfe03285 100644 --- a/arch/x86/um/Makefile +++ b/arch/x86/um/Makefile @@ -8,7 +8,7 @@ else BITS := 64 endif -obj-y = bug.o bugs_$(BITS).o delay.o fault.o ldt.o \ +obj-y = bugs_$(BITS).o delay.o fault.o ldt.o \ ptrace_$(BITS).o ptrace_user.o setjmp_$(BITS).o signal.o \ stub_$(BITS).o stub_segv.o \ sys_call_table_$(BITS).o sysrq_$(BITS).o tls_$(BITS).o \ @@ -16,7 +16,7 @@ obj-y = bug.o bugs_$(BITS).o delay.o fault.o ldt.o \ ifeq ($(CONFIG_X86_32),y) -obj-y += checksum_32.o +obj-y += checksum_32.o syscalls_32.o obj-$(CONFIG_ELF_CORE) += elfcore.o subarch-y = ../lib/string_32.o ../lib/atomic64_32.o ../lib/atomic64_cx8_32.o diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h index e59eef20647b..b291ca5cf66b 100644 --- a/arch/x86/um/asm/ptrace.h +++ b/arch/x86/um/asm/ptrace.h @@ -78,7 +78,7 @@ static inline int ptrace_set_thread_area(struct task_struct *child, int idx, return -ENOSYS; } -extern long arch_prctl(struct task_struct *task, int code, +extern long arch_prctl(struct task_struct *task, int option, unsigned long __user *addr); #endif diff --git a/arch/x86/um/bug.c b/arch/x86/um/bug.c deleted file mode 100644 index e8034e363d83..000000000000 --- a/arch/x86/um/bug.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) - * Licensed under the GPL V2 - */ - -#include <linux/uaccess.h> - -/* - * Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because - * that's not relevant in skas mode. - */ - -int is_valid_bugaddr(unsigned long eip) -{ - unsigned short ud2; - - if (probe_kernel_address((unsigned short __user *)eip, ud2)) - return 0; - - return ud2 == 0x0b0f; -} diff --git a/arch/x86/um/os-Linux/prctl.c b/arch/x86/um/os-Linux/prctl.c index 96eb2bd28832..8431e87ac333 100644 --- a/arch/x86/um/os-Linux/prctl.c +++ b/arch/x86/um/os-Linux/prctl.c @@ -6,7 +6,7 @@ #include <sys/ptrace.h> #include <asm/ptrace.h> -int os_arch_prctl(int pid, int code, unsigned long *addr) +int os_arch_prctl(int pid, int option, unsigned long *arg2) { - return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) addr, code); + return ptrace(PTRACE_ARCH_PRCTL, pid, (unsigned long) arg2, option); } diff --git a/arch/x86/um/syscalls_32.c b/arch/x86/um/syscalls_32.c new file mode 100644 index 000000000000..627d68836b16 --- /dev/null +++ b/arch/x86/um/syscalls_32.c @@ -0,0 +1,7 @@ +#include <linux/syscalls.h> +#include <os.h> + +SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) +{ + return -EINVAL; +} diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c index 10d907098c26..58f51667e2e4 100644 --- a/arch/x86/um/syscalls_64.c +++ b/arch/x86/um/syscalls_64.c @@ -7,13 +7,15 @@ #include <linux/sched.h> #include <linux/sched/mm.h> +#include <linux/syscalls.h> #include <linux/uaccess.h> #include <asm/prctl.h> /* XXX This should get the constants from libc */ #include <os.h> -long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) +long arch_prctl(struct task_struct *task, int option, + unsigned long __user *arg2) { - unsigned long *ptr = addr, tmp; + unsigned long *ptr = arg2, tmp; long ret; int pid = task->mm->context.id.u.pid; @@ -30,7 +32,7 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) * arch_prctl is run on the host, then the registers are read * back. */ - switch (code) { + switch (option) { case ARCH_SET_FS: case ARCH_SET_GS: ret = restore_registers(pid, ¤t->thread.regs.regs); @@ -50,11 +52,11 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) ptr = &tmp; } - ret = os_arch_prctl(pid, code, ptr); + ret = os_arch_prctl(pid, option, ptr); if (ret) return ret; - switch (code) { + switch (option) { case ARCH_SET_FS: current->thread.arch.fs = (unsigned long) ptr; ret = save_registers(pid, ¤t->thread.regs.regs); @@ -63,19 +65,19 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) ret = save_registers(pid, ¤t->thread.regs.regs); break; case ARCH_GET_FS: - ret = put_user(tmp, addr); + ret = put_user(tmp, arg2); break; case ARCH_GET_GS: - ret = put_user(tmp, addr); + ret = put_user(tmp, arg2); break; } return ret; } -long sys_arch_prctl(int code, unsigned long addr) +SYSCALL_DEFINE2(arch_prctl, int, option, unsigned long, arg2) { - return arch_prctl(current, code, (unsigned long __user *) addr); + return arch_prctl(current, option, (unsigned long __user *) arg2); } void arch_switch_to(struct task_struct *to) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index ec1d5c46e58f..504ec746b2e4 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -76,6 +76,7 @@ #include <asm/mwait.h> #include <asm/pci_x86.h> #include <asm/cpu.h> +#include <asm/e820/api.h> #ifdef CONFIG_ACPI #include <linux/acpi.h> @@ -1595,7 +1596,6 @@ asmlinkage __visible void __init xen_start_kernel(void) /* set up basic CPUID stuff */ cpu_detect(&new_cpu_data); set_cpu_cap(&new_cpu_data, X86_FEATURE_FPU); - new_cpu_data.wp_works_ok = 1; new_cpu_data.x86_capability[CPUID_1_EDX] = cpuid_edx(1); #endif @@ -1690,34 +1690,32 @@ static void __init init_pvh_bootparams(void) memset(&pvh_bootparams, 0, sizeof(pvh_bootparams)); - memmap.nr_entries = ARRAY_SIZE(pvh_bootparams.e820_map); - set_xen_guest_handle(memmap.buffer, pvh_bootparams.e820_map); + memmap.nr_entries = ARRAY_SIZE(pvh_bootparams.e820_table); + set_xen_guest_handle(memmap.buffer, pvh_bootparams.e820_table); rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap); if (rc) { xen_raw_printk("XENMEM_memory_map failed (%d)\n", rc); BUG(); } - if (memmap.nr_entries < E820MAX - 1) { - pvh_bootparams.e820_map[memmap.nr_entries].addr = + if (memmap.nr_entries < E820_MAX_ENTRIES_ZEROPAGE - 1) { + pvh_bootparams.e820_table[memmap.nr_entries].addr = ISA_START_ADDRESS; - pvh_bootparams.e820_map[memmap.nr_entries].size = + pvh_bootparams.e820_table[memmap.nr_entries].size = ISA_END_ADDRESS - ISA_START_ADDRESS; - pvh_bootparams.e820_map[memmap.nr_entries].type = - E820_RESERVED; + pvh_bootparams.e820_table[memmap.nr_entries].type = + E820_TYPE_RESERVED; memmap.nr_entries++; } else xen_raw_printk("Warning: Can fit ISA range into e820\n"); - sanitize_e820_map(pvh_bootparams.e820_map, - ARRAY_SIZE(pvh_bootparams.e820_map), - &memmap.nr_entries); - pvh_bootparams.e820_entries = memmap.nr_entries; for (i = 0; i < pvh_bootparams.e820_entries; i++) - e820_add_region(pvh_bootparams.e820_map[i].addr, - pvh_bootparams.e820_map[i].size, - pvh_bootparams.e820_map[i].type); + e820__range_add(pvh_bootparams.e820_table[i].addr, + pvh_bootparams.e820_table[i].size, + pvh_bootparams.e820_table[i].type); + + e820__update_table(e820_table); pvh_bootparams.hdr.cmd_line_ptr = pvh_start_info.cmdline_paddr; diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 37cb5aad71de..1d68be6e3ff1 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -58,7 +58,7 @@ #include <asm/mmu_context.h> #include <asm/setup.h> #include <asm/paravirt.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/linkage.h> #include <asm/page.h> #include <asm/init.h> diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index a8c306cf8868..a5bf7c451435 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -14,7 +14,7 @@ #include <asm/elf.h> #include <asm/vdso.h> -#include <asm/e820.h> +#include <asm/e820/api.h> #include <asm/setup.h> #include <asm/acpi.h> #include <asm/numa.h> @@ -41,8 +41,7 @@ struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata; unsigned long xen_released_pages; /* E820 map used during setting up memory. */ -static struct e820entry xen_e820_map[E820_X_MAX] __initdata; -static u32 xen_e820_map_entries __initdata; +static struct e820_table xen_e820_table __initdata; /* * Buffer used to remap identity mapped pages. We only need the virtual space. @@ -198,15 +197,15 @@ void __init xen_inv_extra_mem(void) */ static unsigned long __init xen_find_pfn_range(unsigned long *min_pfn) { - const struct e820entry *entry = xen_e820_map; + const struct e820_entry *entry = xen_e820_table.entries; unsigned int i; unsigned long done = 0; - for (i = 0; i < xen_e820_map_entries; i++, entry++) { + for (i = 0; i < xen_e820_table.nr_entries; i++, entry++) { unsigned long s_pfn; unsigned long e_pfn; - if (entry->type != E820_RAM) + if (entry->type != E820_TYPE_RAM) continue; e_pfn = PFN_DOWN(entry->addr + entry->size); @@ -457,7 +456,7 @@ static unsigned long __init xen_foreach_remap_area(unsigned long nr_pages, { phys_addr_t start = 0; unsigned long ret_val = 0; - const struct e820entry *entry = xen_e820_map; + const struct e820_entry *entry = xen_e820_table.entries; int i; /* @@ -471,13 +470,13 @@ static unsigned long __init xen_foreach_remap_area(unsigned long nr_pages, * example) the DMI tables in a reserved region that begins on * a non-page boundary. */ - for (i = 0; i < xen_e820_map_entries; i++, entry++) { + for (i = 0; i < xen_e820_table.nr_entries; i++, entry++) { phys_addr_t end = entry->addr + entry->size; - if (entry->type == E820_RAM || i == xen_e820_map_entries - 1) { + if (entry->type == E820_TYPE_RAM || i == xen_e820_table.nr_entries - 1) { unsigned long start_pfn = PFN_DOWN(start); unsigned long end_pfn = PFN_UP(end); - if (entry->type == E820_RAM) + if (entry->type == E820_TYPE_RAM) end_pfn = PFN_UP(entry->addr); if (start_pfn < end_pfn) @@ -591,28 +590,28 @@ static void __init xen_align_and_add_e820_region(phys_addr_t start, phys_addr_t end = start + size; /* Align RAM regions to page boundaries. */ - if (type == E820_RAM) { + if (type == E820_TYPE_RAM) { start = PAGE_ALIGN(start); end &= ~((phys_addr_t)PAGE_SIZE - 1); } - e820_add_region(start, end - start, type); + e820__range_add(start, end - start, type); } static void __init xen_ignore_unusable(void) { - struct e820entry *entry = xen_e820_map; + struct e820_entry *entry = xen_e820_table.entries; unsigned int i; - for (i = 0; i < xen_e820_map_entries; i++, entry++) { - if (entry->type == E820_UNUSABLE) - entry->type = E820_RAM; + for (i = 0; i < xen_e820_table.nr_entries; i++, entry++) { + if (entry->type == E820_TYPE_UNUSABLE) + entry->type = E820_TYPE_RAM; } } bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size) { - struct e820entry *entry; + struct e820_entry *entry; unsigned mapcnt; phys_addr_t end; @@ -620,10 +619,10 @@ bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size) return false; end = start + size; - entry = xen_e820_map; + entry = xen_e820_table.entries; - for (mapcnt = 0; mapcnt < xen_e820_map_entries; mapcnt++) { - if (entry->type == E820_RAM && entry->addr <= start && + for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) { + if (entry->type == E820_TYPE_RAM && entry->addr <= start && (entry->addr + entry->size) >= end) return false; @@ -645,10 +644,10 @@ phys_addr_t __init xen_find_free_area(phys_addr_t size) { unsigned mapcnt; phys_addr_t addr, start; - struct e820entry *entry = xen_e820_map; + struct e820_entry *entry = xen_e820_table.entries; - for (mapcnt = 0; mapcnt < xen_e820_map_entries; mapcnt++, entry++) { - if (entry->type != E820_RAM || entry->size < size) + for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++, entry++) { + if (entry->type != E820_TYPE_RAM || entry->size < size) continue; start = entry->addr; for (addr = start; addr < start + size; addr += PAGE_SIZE) { @@ -750,8 +749,8 @@ char * __init xen_memory_setup(void) max_pfn = min(max_pfn, xen_start_info->nr_pages); mem_end = PFN_PHYS(max_pfn); - memmap.nr_entries = ARRAY_SIZE(xen_e820_map); - set_xen_guest_handle(memmap.buffer, xen_e820_map); + memmap.nr_entries = ARRAY_SIZE(xen_e820_table.entries); + set_xen_guest_handle(memmap.buffer, xen_e820_table.entries); op = xen_initial_domain() ? XENMEM_machine_memory_map : @@ -760,16 +759,16 @@ char * __init xen_memory_setup(void) if (rc == -ENOSYS) { BUG_ON(xen_initial_domain()); memmap.nr_entries = 1; - xen_e820_map[0].addr = 0ULL; - xen_e820_map[0].size = mem_end; + xen_e820_table.entries[0].addr = 0ULL; + xen_e820_table.entries[0].size = mem_end; /* 8MB slack (to balance backend allocations). */ - xen_e820_map[0].size += 8ULL << 20; - xen_e820_map[0].type = E820_RAM; + xen_e820_table.entries[0].size += 8ULL << 20; + xen_e820_table.entries[0].type = E820_TYPE_RAM; rc = 0; } BUG_ON(rc); BUG_ON(memmap.nr_entries == 0); - xen_e820_map_entries = memmap.nr_entries; + xen_e820_table.nr_entries = memmap.nr_entries; /* * Xen won't allow a 1:1 mapping to be created to UNUSABLE @@ -783,8 +782,7 @@ char * __init xen_memory_setup(void) xen_ignore_unusable(); /* Make sure the Xen-supplied memory map is well-ordered. */ - sanitize_e820_map(xen_e820_map, ARRAY_SIZE(xen_e820_map), - &xen_e820_map_entries); + e820__update_table(&xen_e820_table); max_pages = xen_get_max_pages(); @@ -811,15 +809,15 @@ char * __init xen_memory_setup(void) extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)), extra_pages, max_pages - max_pfn); i = 0; - addr = xen_e820_map[0].addr; - size = xen_e820_map[0].size; - while (i < xen_e820_map_entries) { + addr = xen_e820_table.entries[0].addr; + size = xen_e820_table.entries[0].size; + while (i < xen_e820_table.nr_entries) { bool discard = false; chunk_size = size; - type = xen_e820_map[i].type; + type = xen_e820_table.entries[i].type; - if (type == E820_RAM) { + if (type == E820_TYPE_RAM) { if (addr < mem_end) { chunk_size = min(size, mem_end - addr); } else if (extra_pages) { @@ -840,9 +838,9 @@ char * __init xen_memory_setup(void) size -= chunk_size; if (size == 0) { i++; - if (i < xen_e820_map_entries) { - addr = xen_e820_map[i].addr; - size = xen_e820_map[i].size; + if (i < xen_e820_table.nr_entries) { + addr = xen_e820_table.entries[i].addr; + size = xen_e820_table.entries[i].size; } } } @@ -858,10 +856,9 @@ char * __init xen_memory_setup(void) * reserve ISA memory anyway because too many things poke * about in there. */ - e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, - E820_RESERVED); + e820__range_add(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, E820_TYPE_RESERVED); - sanitize_e820_map(e820->map, ARRAY_SIZE(e820->map), &e820->nr_map); + e820__update_table(e820_table); /* * Check whether the kernel itself conflicts with the target E820 map. @@ -915,6 +912,37 @@ char * __init xen_memory_setup(void) } /* + * Machine specific memory setup for auto-translated guests. + */ +char * __init xen_auto_xlated_memory_setup(void) +{ + struct xen_memory_map memmap; + int i; + int rc; + + memmap.nr_entries = ARRAY_SIZE(xen_e820_table.entries); + set_xen_guest_handle(memmap.buffer, xen_e820_table.entries); + + rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap); + if (rc < 0) + panic("No memory map (%d)\n", rc); + + xen_e820_table.nr_entries = memmap.nr_entries; + + e820__update_table(&xen_e820_table); + + for (i = 0; i < xen_e820_table.nr_entries; i++) + e820__range_add(xen_e820_table.entries[i].addr, xen_e820_table.entries[i].size, xen_e820_table.entries[i].type); + + /* Remove p2m info, it is not needed. */ + xen_start_info->mfn_list = 0; + xen_start_info->first_p2m_pfn = 0; + xen_start_info->nr_p2m_frames = 0; + + return "Xen"; +} + +/* * Set the bit indicating "nosegneg" library variants should be used. * We only need to bother in pure 32-bit mode; compat 32-bit processes * can have un-truncated segments, so wrapping around is allowed. @@ -999,8 +1027,8 @@ void __init xen_pvmmu_arch_setup(void) void __init xen_arch_setup(void) { xen_panic_handler_init(); - - xen_pvmmu_arch_setup(); + if (!xen_feature(XENFEAT_auto_translated_physmap)) + xen_pvmmu_arch_setup(); #ifdef CONFIG_ACPI if (!(xen_start_info->flags & SIF_INITDOMAIN)) { diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 1e69956d7852..7a3089285c59 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -209,7 +209,9 @@ static const struct clock_event_device xen_timerop_clockevent = { .features = CLOCK_EVT_FEAT_ONESHOT, .max_delta_ns = 0xffffffff, + .max_delta_ticks = 0xffffffff, .min_delta_ns = TIMER_SLOP, + .min_delta_ticks = TIMER_SLOP, .mult = 1, .shift = 0, @@ -268,7 +270,9 @@ static const struct clock_event_device xen_vcpuop_clockevent = { .features = CLOCK_EVT_FEAT_ONESHOT, .max_delta_ns = 0xffffffff, + .max_delta_ticks = 0xffffffff, .min_delta_ns = TIMER_SLOP, + .min_delta_ticks = TIMER_SLOP, .mult = 1, .shift = 0, diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild index f41408c53fe1..cc23e9ecc6bb 100644 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild @@ -6,6 +6,7 @@ generic-y += dma-contiguous.h generic-y += emergency-restart.h generic-y += errno.h generic-y += exec.h +generic-y += extable.h generic-y += fcntl.h generic-y += hardirq.h generic-y += ioctl.h diff --git a/arch/xtensa/include/asm/asm-uaccess.h b/arch/xtensa/include/asm/asm-uaccess.h index a7a110039786..dfdf9fae1f84 100644 --- a/arch/xtensa/include/asm/asm-uaccess.h +++ b/arch/xtensa/include/asm/asm-uaccess.h @@ -19,9 +19,6 @@ #include <linux/errno.h> #include <asm/types.h> -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - #include <asm/current.h> #include <asm/asm-offsets.h> #include <asm/processor.h> diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index 976b1d70edbc..4ddbfd57a7c8 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h @@ -164,8 +164,21 @@ void copy_user_highpage(struct page *to, struct page *from, #define ARCH_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) +#ifdef CONFIG_MMU +static inline unsigned long ___pa(unsigned long va) +{ + unsigned long off = va - PAGE_OFFSET; + + if (off >= XCHAL_KSEG_SIZE) + off -= XCHAL_KSEG_SIZE; + + return off + PHYS_OFFSET; +} +#define __pa(x) ___pa((unsigned long)(x)) +#else #define __pa(x) \ ((unsigned long) (x) - PAGE_OFFSET + PHYS_OFFSET) +#endif #define __va(x) \ ((void *)((unsigned long) (x) - PHYS_OFFSET + PAGE_OFFSET)) #define pfn_valid(pfn) \ diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h index 848a3d736bcb..2e7bac0d4b2c 100644 --- a/arch/xtensa/include/asm/uaccess.h +++ b/arch/xtensa/include/asm/uaccess.h @@ -16,14 +16,9 @@ #ifndef _XTENSA_UACCESS_H #define _XTENSA_UACCESS_H -#include <linux/errno.h> #include <linux/prefetch.h> #include <asm/types.h> - -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -#include <linux/sched.h> +#include <asm/extable.h> /* * The fs value determines whether argument validity checking should @@ -43,7 +38,7 @@ #define segment_eq(a, b) ((a).seg == (b).seg) -#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) +#define __kernel_ok (uaccess_kernel()) #define __user_ok(addr, size) \ (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) #define __access_ok(addr, size) (__kernel_ok || __user_ok((addr), (size))) @@ -239,60 +234,22 @@ __asm__ __volatile__( \ * Copy to/from user space */ -/* - * We use a generic, arbitrary-sized copy subroutine. The Xtensa - * architecture would cause heavy code bloat if we tried to inline - * these functions and provide __constant_copy_* equivalents like the - * i386 versions. __xtensa_copy_user is quite efficient. See the - * .fixup section of __xtensa_copy_user for a discussion on the - * X_zeroing equivalents for Xtensa. - */ - extern unsigned __xtensa_copy_user(void *to, const void *from, unsigned n); -#define __copy_user(to, from, size) __xtensa_copy_user(to, from, size) - static inline unsigned long -__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n) +raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - return __copy_user(to, from, n); -} - -static inline unsigned long -__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n) -{ - return __copy_user(to, from, n); + prefetchw(to); + return __xtensa_copy_user(to, (__force const void *)from, n); } - static inline unsigned long -__generic_copy_to_user(void *to, const void *from, unsigned long n) +raw_copy_to_user(void __user *to, const void *from, unsigned long n) { prefetch(from); - if (access_ok(VERIFY_WRITE, to, n)) - return __copy_user(to, from, n); - return n; -} - -static inline unsigned long -__generic_copy_from_user(void *to, const void *from, unsigned long n) -{ - prefetchw(to); - if (access_ok(VERIFY_READ, from, n)) - return __copy_user(to, from, n); - else - memset(to, 0, n); - return n; + return __xtensa_copy_user((__force void *)to, from, n); } - -#define copy_to_user(to, from, n) __generic_copy_to_user((to), (from), (n)) -#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n)) -#define __copy_to_user(to, from, n) \ - __generic_copy_to_user_nocheck((to), (from), (n)) -#define __copy_from_user(to, from, n) \ - __generic_copy_from_user_nocheck((to), (from), (n)) -#define __copy_to_user_inatomic __copy_to_user -#define __copy_from_user_inatomic __copy_from_user - +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER /* * We need to return the number of bytes not cleared. Our memset() @@ -348,10 +305,4 @@ static inline long strnlen_user(const char *str, long len) return __strnlen_user(str, len); } - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - #endif /* _XTENSA_UACCESS_H */ diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index cd400af4a6b2..6be7eb27fd29 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h @@ -774,7 +774,10 @@ __SYSCALL(349, sys_pkey_alloc, 2) #define __NR_pkey_free 350 __SYSCALL(350, sys_pkey_free, 1) -#define __NR_syscall_count 351 +#define __NR_statx 351 +__SYSCALL(351, sys_statx, 5) + +#define __NR_syscall_count 352 /* * sysxtensa syscall handler diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index c82c43bff296..bae697a06a98 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -483,10 +483,8 @@ void show_regs(struct pt_regs * regs) static int show_trace_cb(struct stackframe *frame, void *data) { - if (kernel_text_address(frame->pc)) { - pr_cont(" [<%08lx>]", frame->pc); - print_symbol(" %s\n", frame->pc); - } + if (kernel_text_address(frame->pc)) + pr_cont(" [<%08lx>] %pB\n", frame->pc, (void *)frame->pc); return 0; } diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S index 7ea4dd68893e..d9cd766bde3e 100644 --- a/arch/xtensa/lib/usercopy.S +++ b/arch/xtensa/lib/usercopy.S @@ -102,9 +102,9 @@ __xtensa_copy_user: bltui a4, 7, .Lbytecopy # do short copies byte by byte # copy 1 byte - EX(l8ui, a6, a3, 0, l_fixup) + EX(l8ui, a6, a3, 0, fixup) addi a3, a3, 1 - EX(s8i, a6, a5, 0, s_fixup) + EX(s8i, a6, a5, 0, fixup) addi a5, a5, 1 addi a4, a4, -1 bbci.l a5, 1, .Ldstaligned # if dst is now aligned, then @@ -112,11 +112,11 @@ __xtensa_copy_user: .Ldst2mod4: # dst 16-bit aligned # copy 2 bytes bltui a4, 6, .Lbytecopy # do short copies byte by byte - EX(l8ui, a6, a3, 0, l_fixup) - EX(l8ui, a7, a3, 1, l_fixup) + EX(l8ui, a6, a3, 0, fixup) + EX(l8ui, a7, a3, 1, fixup) addi a3, a3, 2 - EX(s8i, a6, a5, 0, s_fixup) - EX(s8i, a7, a5, 1, s_fixup) + EX(s8i, a6, a5, 0, fixup) + EX(s8i, a7, a5, 1, fixup) addi a5, a5, 2 addi a4, a4, -2 j .Ldstaligned # dst is now aligned, return to main algorithm @@ -135,9 +135,9 @@ __xtensa_copy_user: add a7, a3, a4 # a7 = end address for source #endif /* !XCHAL_HAVE_LOOPS */ .Lnextbyte: - EX(l8ui, a6, a3, 0, l_fixup) + EX(l8ui, a6, a3, 0, fixup) addi a3, a3, 1 - EX(s8i, a6, a5, 0, s_fixup) + EX(s8i, a6, a5, 0, fixup) addi a5, a5, 1 #if !XCHAL_HAVE_LOOPS blt a3, a7, .Lnextbyte @@ -161,15 +161,15 @@ __xtensa_copy_user: add a8, a8, a3 # a8 = end of last 16B source chunk #endif /* !XCHAL_HAVE_LOOPS */ .Loop1: - EX(l32i, a6, a3, 0, l_fixup) - EX(l32i, a7, a3, 4, l_fixup) - EX(s32i, a6, a5, 0, s_fixup) - EX(l32i, a6, a3, 8, l_fixup) - EX(s32i, a7, a5, 4, s_fixup) - EX(l32i, a7, a3, 12, l_fixup) - EX(s32i, a6, a5, 8, s_fixup) + EX(l32i, a6, a3, 0, fixup) + EX(l32i, a7, a3, 4, fixup) + EX(s32i, a6, a5, 0, fixup) + EX(l32i, a6, a3, 8, fixup) + EX(s32i, a7, a5, 4, fixup) + EX(l32i, a7, a3, 12, fixup) + EX(s32i, a6, a5, 8, fixup) addi a3, a3, 16 - EX(s32i, a7, a5, 12, s_fixup) + EX(s32i, a7, a5, 12, fixup) addi a5, a5, 16 #if !XCHAL_HAVE_LOOPS blt a3, a8, .Loop1 @@ -177,31 +177,31 @@ __xtensa_copy_user: .Loop1done: bbci.l a4, 3, .L2 # copy 8 bytes - EX(l32i, a6, a3, 0, l_fixup) - EX(l32i, a7, a3, 4, l_fixup) + EX(l32i, a6, a3, 0, fixup) + EX(l32i, a7, a3, 4, fixup) addi a3, a3, 8 - EX(s32i, a6, a5, 0, s_fixup) - EX(s32i, a7, a5, 4, s_fixup) + EX(s32i, a6, a5, 0, fixup) + EX(s32i, a7, a5, 4, fixup) addi a5, a5, 8 .L2: bbci.l a4, 2, .L3 # copy 4 bytes - EX(l32i, a6, a3, 0, l_fixup) + EX(l32i, a6, a3, 0, fixup) addi a3, a3, 4 - EX(s32i, a6, a5, 0, s_fixup) + EX(s32i, a6, a5, 0, fixup) addi a5, a5, 4 .L3: bbci.l a4, 1, .L4 # copy 2 bytes - EX(l16ui, a6, a3, 0, l_fixup) + EX(l16ui, a6, a3, 0, fixup) addi a3, a3, 2 - EX(s16i, a6, a5, 0, s_fixup) + EX(s16i, a6, a5, 0, fixup) addi a5, a5, 2 .L4: bbci.l a4, 0, .L5 # copy 1 byte - EX(l8ui, a6, a3, 0, l_fixup) - EX(s8i, a6, a5, 0, s_fixup) + EX(l8ui, a6, a3, 0, fixup) + EX(s8i, a6, a5, 0, fixup) .L5: movi a2, 0 # return success for len bytes copied retw @@ -217,7 +217,7 @@ __xtensa_copy_user: # copy 16 bytes per iteration for word-aligned dst and unaligned src and a10, a3, a8 # save unalignment offset for below sub a3, a3, a10 # align a3 (to avoid sim warnings only; not needed for hardware) - EX(l32i, a6, a3, 0, l_fixup) # load first word + EX(l32i, a6, a3, 0, fixup) # load first word #if XCHAL_HAVE_LOOPS loopnez a7, .Loop2done #else /* !XCHAL_HAVE_LOOPS */ @@ -226,19 +226,19 @@ __xtensa_copy_user: add a12, a12, a3 # a12 = end of last 16B source chunk #endif /* !XCHAL_HAVE_LOOPS */ .Loop2: - EX(l32i, a7, a3, 4, l_fixup) - EX(l32i, a8, a3, 8, l_fixup) + EX(l32i, a7, a3, 4, fixup) + EX(l32i, a8, a3, 8, fixup) ALIGN( a6, a6, a7) - EX(s32i, a6, a5, 0, s_fixup) - EX(l32i, a9, a3, 12, l_fixup) + EX(s32i, a6, a5, 0, fixup) + EX(l32i, a9, a3, 12, fixup) ALIGN( a7, a7, a8) - EX(s32i, a7, a5, 4, s_fixup) - EX(l32i, a6, a3, 16, l_fixup) + EX(s32i, a7, a5, 4, fixup) + EX(l32i, a6, a3, 16, fixup) ALIGN( a8, a8, a9) - EX(s32i, a8, a5, 8, s_fixup) + EX(s32i, a8, a5, 8, fixup) addi a3, a3, 16 ALIGN( a9, a9, a6) - EX(s32i, a9, a5, 12, s_fixup) + EX(s32i, a9, a5, 12, fixup) addi a5, a5, 16 #if !XCHAL_HAVE_LOOPS blt a3, a12, .Loop2 @@ -246,39 +246,39 @@ __xtensa_copy_user: .Loop2done: bbci.l a4, 3, .L12 # copy 8 bytes - EX(l32i, a7, a3, 4, l_fixup) - EX(l32i, a8, a3, 8, l_fixup) + EX(l32i, a7, a3, 4, fixup) + EX(l32i, a8, a3, 8, fixup) ALIGN( a6, a6, a7) - EX(s32i, a6, a5, 0, s_fixup) + EX(s32i, a6, a5, 0, fixup) addi a3, a3, 8 ALIGN( a7, a7, a8) - EX(s32i, a7, a5, 4, s_fixup) + EX(s32i, a7, a5, 4, fixup) addi a5, a5, 8 mov a6, a8 .L12: bbci.l a4, 2, .L13 # copy 4 bytes - EX(l32i, a7, a3, 4, l_fixup) + EX(l32i, a7, a3, 4, fixup) addi a3, a3, 4 ALIGN( a6, a6, a7) - EX(s32i, a6, a5, 0, s_fixup) + EX(s32i, a6, a5, 0, fixup) addi a5, a5, 4 mov a6, a7 .L13: add a3, a3, a10 # readjust a3 with correct misalignment bbci.l a4, 1, .L14 # copy 2 bytes - EX(l8ui, a6, a3, 0, l_fixup) - EX(l8ui, a7, a3, 1, l_fixup) + EX(l8ui, a6, a3, 0, fixup) + EX(l8ui, a7, a3, 1, fixup) addi a3, a3, 2 - EX(s8i, a6, a5, 0, s_fixup) - EX(s8i, a7, a5, 1, s_fixup) + EX(s8i, a6, a5, 0, fixup) + EX(s8i, a7, a5, 1, fixup) addi a5, a5, 2 .L14: bbci.l a4, 0, .L15 # copy 1 byte - EX(l8ui, a6, a3, 0, l_fixup) - EX(s8i, a6, a5, 0, s_fixup) + EX(l8ui, a6, a3, 0, fixup) + EX(s8i, a6, a5, 0, fixup) .L15: movi a2, 0 # return success for len bytes copied retw @@ -291,30 +291,10 @@ __xtensa_copy_user: * bytes_copied = a5 - a2 * retval = bytes_not_copied = original len - bytes_copied * retval = a11 - (a5 - a2) - * - * Clearing the remaining pieces of kernel memory plugs security - * holes. This functionality is the equivalent of the *_zeroing - * functions that some architectures provide. */ -.Lmemset: - .word memset -s_fixup: +fixup: sub a2, a5, a2 /* a2 <-- bytes copied */ sub a2, a11, a2 /* a2 <-- bytes not copied */ retw - -l_fixup: - sub a2, a5, a2 /* a2 <-- bytes copied */ - sub a2, a11, a2 /* a2 <-- bytes not copied == return value */ - - /* void *memset(void *s, int c, size_t n); */ - mov a6, a5 /* s */ - movi a7, 0 /* c */ - mov a8, a2 /* n */ - l32r a4, .Lmemset - callx4 a4 - /* Ignore memset return value in a6. */ - /* a2 still contains bytes not copied. */ - retw |