forked from luck/tmp_suning_uos_patched
Xtensa updates for v5.2:
- implement atomic operations using exclusive access Xtensa option operations. - add support for Xtensa cores with memory protection unit (MPU). - clean up xtensa-specific kernel-only headers. - fix error path in simdisk_setup. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEK2eFS5jlMn3N6xfYUfnMkfg/oEQFAlzV0oQTHGpjbXZia2Jj QGdtYWlsLmNvbQAKCRBR+cyR+D+gRHTkD/sETyrWaYCSvz07gcvxsauJgkKyikq3 oNsO6H0R9WzIRtofP7eIPe1me46YDxPGJxx3VEnJA1JWvUg8CU1UNmvA3ZD4yXp2 tA1G8/0WFbiKXX+svNXlIkCtBHm2Y9wdT2l1zfFLnQgyuJhr9uwrIY0YmQYM+INe bAX9PyDg2aa2GkCkZMFvMeFrMHEAx+ae/A9jYqhnsmrYbfIV/4qdcKpgm0lty/fv RRNx+eqDamI5EMnXQwW86/1YxB+KItKGSEQ3t/20jBXcH1tZsXAvcs91kKH1/nCE cR8w21yBWCulPSuACqqrwtZ+aCxsQ22O4QMtlmJEl0jsWOdOk47JeyLwAqbGZS7g nk5FQH7/aGU250HOCLEX1IdA0VZsOeJRXfJknFcEyfKi8JuhXZK/zHyhNE3VkpH5 cfA1dVRFH4qmKevEWygBfNyo8rR9E/0aaNhTzMUHXrIU07fxh5CQk9trIlwtWWsS kEV3bEsTMXdz3e4ev5HLUuJzLlYQ7Szs1HsgB5XPUsCC4kwbjKZTN8BtqIpx7P9K lDVplXKlHOd2SJ9Ii5eJ0Zn9cBdUulqrQzHlSg6kWyrfQ/QrY8OFwCM8hUQIWGir MrpSWfafjIudjdxN3lHEM8Gv0LzNmjwWrh6QJYlE08Ggi7QXM/BiXkgBDaeRItbl xLB9UsUsTL8OLQ== =aszE -----END PGP SIGNATURE----- Merge tag 'xtensa-20190510' of git://github.com/jcmvbkbc/linux-xtensa Pull xtensa updates from Max Filippov: - implement atomic operations using exclusive access Xtensa option operations - add support for Xtensa cores with memory protection unit (MPU) - clean up xtensa-specific kernel-only headers - fix error path in simdisk_setup * tag 'xtensa-20190510' of git://github.com/jcmvbkbc/linux-xtensa: xtensa: implement initialize_cacheattr for MPU cores xtensa: add exclusive atomics support xtensa: clean up inline assembly in futex.h xtensa: replace variant/core.h with asm/core.h xtensa: drop ifdef __KERNEL__ from kernel-only headers xtensa: set proper error code for simdisk_setup() xtensa: fix incorrect fd close in error case of simdisk_setup()
This commit is contained in:
commit
7a5575212c
|
@ -253,12 +253,26 @@ config MEMMAP_CACHEATTR
|
|||
region: bits 0..3 -- for addresses 0x00000000..0x1fffffff,
|
||||
bits 4..7 -- for addresses 0x20000000..0x3fffffff, and so on.
|
||||
|
||||
Cache attribute values are specific for the MMU type, so e.g.
|
||||
for region protection MMUs: 2 is cache bypass, 4 is WB cached,
|
||||
1 is WT cached, f is illegal. For ful MMU: bit 0 makes it executable,
|
||||
bit 1 makes it writable, bits 2..3 meaning is 0: cache bypass,
|
||||
1: WB cache, 2: WT cache, 3: special (c and e are illegal, f is
|
||||
reserved).
|
||||
Cache attribute values are specific for the MMU type.
|
||||
For region protection MMUs:
|
||||
1: WT cached,
|
||||
2: cache bypass,
|
||||
4: WB cached,
|
||||
f: illegal.
|
||||
For ful MMU:
|
||||
bit 0: executable,
|
||||
bit 1: writable,
|
||||
bits 2..3:
|
||||
0: cache bypass,
|
||||
1: WB cache,
|
||||
2: WT cache,
|
||||
3: special (c and e are illegal, f is reserved).
|
||||
For MPU:
|
||||
0: illegal,
|
||||
1: WB cache,
|
||||
2: WB, no-write-allocate cache,
|
||||
3: WT cache,
|
||||
4: cache bypass.
|
||||
|
||||
config KSEG_PADDR
|
||||
hex "Physical address of the KSEG mapping"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
#include <asm/regs.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/cacheasm.h>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#ifndef _XTENSA_ASMMACRO_H
|
||||
#define _XTENSA_ASMMACRO_H
|
||||
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
/*
|
||||
* Some little helpers for loops. Use zero-overhead-loops
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
|
||||
#include <linux/stringify.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cmpxchg.h>
|
||||
#include <asm/barrier.h>
|
||||
|
@ -58,7 +56,67 @@
|
|||
*/
|
||||
#define atomic_set(v,i) WRITE_ONCE((v)->counter, (i))
|
||||
|
||||
#if XCHAL_HAVE_S32C1I
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
#define ATOMIC_OP(op) \
|
||||
static inline void atomic_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long tmp; \
|
||||
int result; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
"1: l32ex %1, %3\n" \
|
||||
" " #op " %0, %1, %2\n" \
|
||||
" s32ex %0, %3\n" \
|
||||
" getex %0\n" \
|
||||
" beqz %0, 1b\n" \
|
||||
: "=&a" (result), "=&a" (tmp) \
|
||||
: "a" (i), "a" (v) \
|
||||
: "memory" \
|
||||
); \
|
||||
} \
|
||||
|
||||
#define ATOMIC_OP_RETURN(op) \
|
||||
static inline int atomic_##op##_return(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long tmp; \
|
||||
int result; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
"1: l32ex %1, %3\n" \
|
||||
" " #op " %0, %1, %2\n" \
|
||||
" s32ex %0, %3\n" \
|
||||
" getex %0\n" \
|
||||
" beqz %0, 1b\n" \
|
||||
" " #op " %0, %1, %2\n" \
|
||||
: "=&a" (result), "=&a" (tmp) \
|
||||
: "a" (i), "a" (v) \
|
||||
: "memory" \
|
||||
); \
|
||||
\
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define ATOMIC_FETCH_OP(op) \
|
||||
static inline int atomic_fetch_##op(int i, atomic_t *v) \
|
||||
{ \
|
||||
unsigned long tmp; \
|
||||
int result; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
"1: l32ex %1, %3\n" \
|
||||
" " #op " %0, %1, %2\n" \
|
||||
" s32ex %0, %3\n" \
|
||||
" getex %0\n" \
|
||||
" beqz %0, 1b\n" \
|
||||
: "=&a" (result), "=&a" (tmp) \
|
||||
: "a" (i), "a" (v) \
|
||||
: "memory" \
|
||||
); \
|
||||
\
|
||||
return tmp; \
|
||||
}
|
||||
|
||||
#elif XCHAL_HAVE_S32C1I
|
||||
#define ATOMIC_OP(op) \
|
||||
static inline void atomic_##op(int i, atomic_t * v) \
|
||||
{ \
|
||||
|
@ -200,6 +258,4 @@ ATOMIC_OPS(xor)
|
|||
#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
|
||||
#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _XTENSA_ATOMIC_H */
|
||||
|
|
|
@ -9,12 +9,16 @@
|
|||
#ifndef _XTENSA_SYSTEM_H
|
||||
#define _XTENSA_SYSTEM_H
|
||||
|
||||
#include <asm/core.h>
|
||||
|
||||
#define mb() ({ __asm__ __volatile__("memw" : : : "memory"); })
|
||||
#define rmb() barrier()
|
||||
#define wmb() mb()
|
||||
|
||||
#if XCHAL_HAVE_S32C1I
|
||||
#define __smp_mb__before_atomic() barrier()
|
||||
#define __smp_mb__after_atomic() barrier()
|
||||
#endif
|
||||
|
||||
#include <asm-generic/barrier.h>
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
#ifndef _XTENSA_BITOPS_H
|
||||
#define _XTENSA_BITOPS_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifndef _LINUX_BITOPS_H
|
||||
#error only <linux/bitops.h> can be included directly
|
||||
#endif
|
||||
|
@ -98,7 +96,126 @@ static inline unsigned long __fls(unsigned long word)
|
|||
|
||||
#include <asm-generic/bitops/fls64.h>
|
||||
|
||||
#if XCHAL_HAVE_S32C1I
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
|
||||
static inline void set_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
unsigned long tmp;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: l32ex %0, %2\n"
|
||||
" or %0, %0, %1\n"
|
||||
" s32ex %0, %2\n"
|
||||
" getex %0\n"
|
||||
" beqz %0, 1b\n"
|
||||
: "=&a" (tmp)
|
||||
: "a" (mask), "a" (p)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void clear_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
unsigned long tmp;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: l32ex %0, %2\n"
|
||||
" and %0, %0, %1\n"
|
||||
" s32ex %0, %2\n"
|
||||
" getex %0\n"
|
||||
" beqz %0, 1b\n"
|
||||
: "=&a" (tmp)
|
||||
: "a" (~mask), "a" (p)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void change_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
unsigned long tmp;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: l32ex %0, %2\n"
|
||||
" xor %0, %0, %1\n"
|
||||
" s32ex %0, %2\n"
|
||||
" getex %0\n"
|
||||
" beqz %0, 1b\n"
|
||||
: "=&a" (tmp)
|
||||
: "a" (~mask), "a" (p)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_and_set_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
unsigned long tmp, value;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: l32ex %1, %3\n"
|
||||
" or %0, %1, %2\n"
|
||||
" s32ex %0, %3\n"
|
||||
" getex %0\n"
|
||||
" beqz %0, 1b\n"
|
||||
: "=&a" (tmp), "=&a" (value)
|
||||
: "a" (mask), "a" (p)
|
||||
: "memory");
|
||||
|
||||
return value & mask;
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
unsigned long tmp, value;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: l32ex %1, %3\n"
|
||||
" and %0, %1, %2\n"
|
||||
" s32ex %0, %3\n"
|
||||
" getex %0\n"
|
||||
" beqz %0, 1b\n"
|
||||
: "=&a" (tmp), "=&a" (value)
|
||||
: "a" (~mask), "a" (p)
|
||||
: "memory");
|
||||
|
||||
return value & mask;
|
||||
}
|
||||
|
||||
static inline int
|
||||
test_and_change_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
unsigned long tmp, value;
|
||||
unsigned long mask = 1UL << (bit & 31);
|
||||
|
||||
p += bit >> 5;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: l32ex %1, %3\n"
|
||||
" xor %0, %1, %2\n"
|
||||
" s32ex %0, %3\n"
|
||||
" getex %0\n"
|
||||
" beqz %0, 1b\n"
|
||||
: "=&a" (tmp), "=&a" (value)
|
||||
: "a" (mask), "a" (p)
|
||||
: "memory");
|
||||
|
||||
return value & mask;
|
||||
}
|
||||
|
||||
#elif XCHAL_HAVE_S32C1I
|
||||
|
||||
static inline void set_bit(unsigned int bit, volatile unsigned long *p)
|
||||
{
|
||||
|
@ -232,6 +349,4 @@ test_and_change_bit(unsigned int bit, volatile unsigned long *p)
|
|||
#include <asm-generic/bitops/lock.h>
|
||||
#include <asm-generic/bitops/sched.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _XTENSA_BITOPS_H */
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#ifndef _XTENSA_CACHE_H
|
||||
#define _XTENSA_CACHE_H
|
||||
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
#define L1_CACHE_SHIFT XCHAL_DCACHE_LINEWIDTH
|
||||
#define L1_CACHE_BYTES XCHAL_DCACHE_LINESIZE
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include <linux/in6.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
/*
|
||||
* computes the checksum of a memory block at buff, length len,
|
||||
|
|
|
@ -23,7 +23,24 @@
|
|||
static inline unsigned long
|
||||
__cmpxchg_u32(volatile int *p, int old, int new)
|
||||
{
|
||||
#if XCHAL_HAVE_S32C1I
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
unsigned long tmp, result;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: l32ex %0, %3\n"
|
||||
" bne %0, %4, 2f\n"
|
||||
" mov %1, %2\n"
|
||||
" s32ex %1, %3\n"
|
||||
" getex %1\n"
|
||||
" beqz %1, 1b\n"
|
||||
"2:\n"
|
||||
: "=&a" (result), "=&a" (tmp)
|
||||
: "a" (new), "a" (p), "a" (old)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return result;
|
||||
#elif XCHAL_HAVE_S32C1I
|
||||
__asm__ __volatile__(
|
||||
" wsr %2, scompare1\n"
|
||||
" s32c1i %0, %1, 0\n"
|
||||
|
@ -108,7 +125,22 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
|
|||
|
||||
static inline unsigned long xchg_u32(volatile int * m, unsigned long val)
|
||||
{
|
||||
#if XCHAL_HAVE_S32C1I
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
unsigned long tmp, result;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: l32ex %0, %3\n"
|
||||
" mov %1, %2\n"
|
||||
" s32ex %1, %3\n"
|
||||
" getex %1\n"
|
||||
" beqz %1, 1b\n"
|
||||
: "=&a" (result), "=&a" (tmp)
|
||||
: "a" (val), "a" (m)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return result;
|
||||
#elif XCHAL_HAVE_S32C1I
|
||||
unsigned long tmp, result;
|
||||
__asm__ __volatile__(
|
||||
"1: l32i %1, %2, 0\n"
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#ifndef _XTENSA_COPROCESSOR_H
|
||||
#define _XTENSA_COPROCESSOR_H
|
||||
|
||||
#include <variant/core.h>
|
||||
#include <variant/tie.h>
|
||||
#include <asm/core.h>
|
||||
#include <asm/types.h>
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
|
21
arch/xtensa/include/asm/core.h
Normal file
21
arch/xtensa/include/asm/core.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2019 Cadence Design Systems Inc. */
|
||||
|
||||
#ifndef _ASM_XTENSA_CORE_H
|
||||
#define _ASM_XTENSA_CORE_H
|
||||
|
||||
#include <variant/core.h>
|
||||
|
||||
#ifndef XCHAL_HAVE_EXCLUSIVE
|
||||
#define XCHAL_HAVE_EXCLUSIVE 0
|
||||
#endif
|
||||
|
||||
#ifndef XCHAL_HAVE_MPU
|
||||
#define XCHAL_HAVE_MPU 0
|
||||
#endif
|
||||
|
||||
#ifndef XCHAL_SPANNING_WAY
|
||||
#define XCHAL_SPANNING_WAY 0
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -15,65 +15,88 @@
|
|||
#ifndef _ASM_XTENSA_FUTEX_H
|
||||
#define _ASM_XTENSA_FUTEX_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/futex.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
#define __futex_atomic_op(insn, ret, old, uaddr, arg) \
|
||||
__asm__ __volatile( \
|
||||
"1: l32i %0, %2, 0\n" \
|
||||
"1: l32ex %[oldval], %[addr]\n" \
|
||||
insn "\n" \
|
||||
" wsr %0, scompare1\n" \
|
||||
"2: s32c1i %1, %2, 0\n" \
|
||||
" bne %1, %0, 1b\n" \
|
||||
" movi %1, 0\n" \
|
||||
"2: s32ex %[newval], %[addr]\n" \
|
||||
" getex %[newval]\n" \
|
||||
" beqz %[newval], 1b\n" \
|
||||
" movi %[newval], 0\n" \
|
||||
"3:\n" \
|
||||
" .section .fixup,\"ax\"\n" \
|
||||
" .align 4\n" \
|
||||
" .literal_position\n" \
|
||||
"5: movi %0, 3b\n" \
|
||||
" movi %1, %3\n" \
|
||||
" jx %0\n" \
|
||||
"5: movi %[oldval], 3b\n" \
|
||||
" movi %[newval], %[fault]\n" \
|
||||
" jx %[oldval]\n" \
|
||||
" .previous\n" \
|
||||
" .section __ex_table,\"a\"\n" \
|
||||
" .long 1b,5b,2b,5b\n" \
|
||||
" .long 1b, 5b, 2b, 5b\n" \
|
||||
" .previous\n" \
|
||||
: "=&r" (oldval), "=&r" (ret) \
|
||||
: "r" (uaddr), "I" (-EFAULT), "r" (oparg) \
|
||||
: [oldval] "=&r" (old), [newval] "=&r" (ret) \
|
||||
: [addr] "r" (uaddr), [oparg] "r" (arg), \
|
||||
[fault] "I" (-EFAULT) \
|
||||
: "memory")
|
||||
#elif XCHAL_HAVE_S32C1I
|
||||
#define __futex_atomic_op(insn, ret, old, uaddr, arg) \
|
||||
__asm__ __volatile( \
|
||||
"1: l32i %[oldval], %[addr], 0\n" \
|
||||
insn "\n" \
|
||||
" wsr %[oldval], scompare1\n" \
|
||||
"2: s32c1i %[newval], %[addr], 0\n" \
|
||||
" bne %[newval], %[oldval], 1b\n" \
|
||||
" movi %[newval], 0\n" \
|
||||
"3:\n" \
|
||||
" .section .fixup,\"ax\"\n" \
|
||||
" .align 4\n" \
|
||||
" .literal_position\n" \
|
||||
"5: movi %[oldval], 3b\n" \
|
||||
" movi %[newval], %[fault]\n" \
|
||||
" jx %[oldval]\n" \
|
||||
" .previous\n" \
|
||||
" .section __ex_table,\"a\"\n" \
|
||||
" .long 1b, 5b, 2b, 5b\n" \
|
||||
" .previous\n" \
|
||||
: [oldval] "=&r" (old), [newval] "=&r" (ret) \
|
||||
: [addr] "r" (uaddr), [oparg] "r" (arg), \
|
||||
[fault] "I" (-EFAULT) \
|
||||
: "memory")
|
||||
#endif
|
||||
|
||||
static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
||||
u32 __user *uaddr)
|
||||
{
|
||||
#if XCHAL_HAVE_S32C1I || XCHAL_HAVE_EXCLUSIVE
|
||||
int oldval = 0, ret;
|
||||
|
||||
#if !XCHAL_HAVE_S32C1I
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
|
||||
pagefault_disable();
|
||||
|
||||
switch (op) {
|
||||
case FUTEX_OP_SET:
|
||||
__futex_atomic_op("mov %1, %4", ret, oldval, uaddr, oparg);
|
||||
__futex_atomic_op("mov %[newval], %[oparg]",
|
||||
ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ADD:
|
||||
__futex_atomic_op("add %1, %0, %4", ret, oldval, uaddr,
|
||||
oparg);
|
||||
__futex_atomic_op("add %[newval], %[oldval], %[oparg]",
|
||||
ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_OR:
|
||||
__futex_atomic_op("or %1, %0, %4", ret, oldval, uaddr,
|
||||
oparg);
|
||||
__futex_atomic_op("or %[newval], %[oldval], %[oparg]",
|
||||
ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
case FUTEX_OP_ANDN:
|
||||
__futex_atomic_op("and %1, %0, %4", ret, oldval, uaddr,
|
||||
~oparg);
|
||||
__futex_atomic_op("and %[newval], %[oldval], %[oparg]",
|
||||
ret, oldval, uaddr, ~oparg);
|
||||
break;
|
||||
case FUTEX_OP_XOR:
|
||||
__futex_atomic_op("xor %1, %0, %4", ret, oldval, uaddr,
|
||||
oparg);
|
||||
__futex_atomic_op("xor %[newval], %[oldval], %[oparg]",
|
||||
ret, oldval, uaddr, oparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
|
@ -85,43 +108,60 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
|
|||
*oval = oldval;
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int
|
||||
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
|
||||
u32 oldval, u32 newval)
|
||||
{
|
||||
#if XCHAL_HAVE_S32C1I || XCHAL_HAVE_EXCLUSIVE
|
||||
unsigned long tmp;
|
||||
int ret = 0;
|
||||
|
||||
if (!access_ok(uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
#if !XCHAL_HAVE_S32C1I
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
|
||||
__asm__ __volatile__ (
|
||||
" # futex_atomic_cmpxchg_inatomic\n"
|
||||
" wsr %5, scompare1\n"
|
||||
"1: s32c1i %1, %4, 0\n"
|
||||
" s32i %1, %6, 0\n"
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
"1: l32ex %[tmp], %[addr]\n"
|
||||
" s32i %[tmp], %[uval], 0\n"
|
||||
" bne %[tmp], %[oldval], 2f\n"
|
||||
" mov %[tmp], %[newval]\n"
|
||||
"3: s32ex %[tmp], %[addr]\n"
|
||||
" getex %[tmp]\n"
|
||||
" beqz %[tmp], 1b\n"
|
||||
#elif XCHAL_HAVE_S32C1I
|
||||
" wsr %[oldval], scompare1\n"
|
||||
"1: s32c1i %[newval], %[addr], 0\n"
|
||||
" s32i %[newval], %[uval], 0\n"
|
||||
#endif
|
||||
"2:\n"
|
||||
" .section .fixup,\"ax\"\n"
|
||||
" .align 4\n"
|
||||
" .literal_position\n"
|
||||
"4: movi %1, 2b\n"
|
||||
" movi %0, %7\n"
|
||||
" jx %1\n"
|
||||
"4: movi %[tmp], 2b\n"
|
||||
" movi %[ret], %[fault]\n"
|
||||
" jx %[tmp]\n"
|
||||
" .previous\n"
|
||||
" .section __ex_table,\"a\"\n"
|
||||
" .long 1b,4b\n"
|
||||
" .long 1b, 4b\n"
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
" .long 3b, 4b\n"
|
||||
#endif
|
||||
" .previous\n"
|
||||
: "+r" (ret), "+r" (newval), "+m" (*uaddr), "+m" (*uval)
|
||||
: "r" (uaddr), "r" (oldval), "r" (uval), "I" (-EFAULT)
|
||||
: [ret] "+r" (ret), [newval] "+r" (newval), [tmp] "=&r" (tmp)
|
||||
: [addr] "r" (uaddr), [oldval] "r" (oldval), [uval] "r" (uval),
|
||||
[fault] "I" (-EFAULT)
|
||||
: "memory");
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_XTENSA_FUTEX_H */
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
#define CA_WRITEBACK (0x4)
|
||||
#endif
|
||||
|
||||
#ifndef XCHAL_SPANNING_WAY
|
||||
#define XCHAL_SPANNING_WAY 0
|
||||
#endif
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#define XTENSA_HWVERSION_RC_2009_0 230000
|
||||
|
@ -181,11 +177,42 @@
|
|||
|
||||
.macro initialize_cacheattr
|
||||
|
||||
#if !defined(CONFIG_MMU) && XCHAL_HAVE_TLBS
|
||||
#if !defined(CONFIG_MMU) && (XCHAL_HAVE_TLBS || XCHAL_HAVE_MPU)
|
||||
#if CONFIG_MEMMAP_CACHEATTR == 0x22222222 && XCHAL_HAVE_PTP_MMU
|
||||
#error Default MEMMAP_CACHEATTR of 0x22222222 does not work with full MMU.
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_MPU
|
||||
.data
|
||||
.align 4
|
||||
.Lattribute_table:
|
||||
.long 0x000000, 0x1fff00, 0x1ddf00, 0x1eef00
|
||||
.long 0x006600, 0x000000, 0x000000, 0x000000
|
||||
.long 0x000000, 0x000000, 0x000000, 0x000000
|
||||
.long 0x000000, 0x000000, 0x000000, 0x000000
|
||||
.previous
|
||||
|
||||
movi a3, .Lattribute_table
|
||||
movi a4, CONFIG_MEMMAP_CACHEATTR
|
||||
movi a5, 1
|
||||
movi a6, XCHAL_MPU_ENTRIES
|
||||
movi a10, 0x20000000
|
||||
movi a11, -1
|
||||
1:
|
||||
sub a5, a5, a10
|
||||
extui a8, a4, 28, 4
|
||||
beq a8, a11, 2f
|
||||
addi a6, a6, -1
|
||||
mov a11, a8
|
||||
2:
|
||||
addx4 a9, a8, a3
|
||||
l32i a9, a9, 0
|
||||
or a9, a9, a6
|
||||
wptlb a9, a5
|
||||
slli a4, a4, 4
|
||||
bgeu a5, a10, 1b
|
||||
|
||||
#else
|
||||
movi a5, XCHAL_SPANNING_WAY
|
||||
movi a6, ~_PAGE_ATTRIB_MASK
|
||||
movi a4, CONFIG_MEMMAP_CACHEATTR
|
||||
|
@ -207,6 +234,7 @@
|
|||
bgeu a5, a8, 1b
|
||||
|
||||
isync
|
||||
#endif
|
||||
#endif
|
||||
|
||||
.endm
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#ifndef _XTENSA_IO_H
|
||||
#define _XTENSA_IO_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/vectors.h>
|
||||
|
@ -78,8 +77,6 @@ static inline void iounmap(volatile void __iomem *addr)
|
|||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#include <asm-generic/io.h>
|
||||
|
||||
#endif /* _XTENSA_IO_H */
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#define _XTENSA_IRQ_H
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
#ifdef CONFIG_PLATFORM_NR_IRQS
|
||||
# define PLATFORM_NR_IRQS CONFIG_PLATFORM_NR_IRQS
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#ifndef _XTENSA_PCI_BRIDGE_H
|
||||
#define _XTENSA_PCI_BRIDGE_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
struct device_node;
|
||||
struct pci_controller;
|
||||
|
||||
|
@ -84,5 +82,4 @@ int early_write_config_byte(struct pci_controller*, int, int, int, u8);
|
|||
int early_write_config_word(struct pci_controller*, int, int, int, u16);
|
||||
int early_write_config_dword(struct pci_controller*, int, int, int, u32);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _XTENSA_PCI_BRIDGE_H */
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#ifndef _XTENSA_PCI_H
|
||||
#define _XTENSA_PCI_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* Can be used to override the logic in pci_scan_bus for skipping
|
||||
* already-configured bus numbers - to be used for buggy BIOSes
|
||||
* or architectures with incomplete PCI setup by the loader
|
||||
|
@ -45,8 +43,6 @@
|
|||
#define ARCH_GENERIC_PCI_MMAP_RESOURCE 1
|
||||
#define arch_can_pci_mmap_io() 1
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/* Generic PCI */
|
||||
#include <asm-generic/pci.h>
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#ifndef _XTENSA_PGALLOC_H
|
||||
#define _XTENSA_PGALLOC_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
@ -79,5 +77,4 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
|
|||
}
|
||||
#define pmd_pgtable(pmd) pmd_page(pmd)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _XTENSA_PGALLOC_H */
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef _XTENSA_PROCESSOR_H
|
||||
#define _XTENSA_PROCESSOR_H
|
||||
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/stringify.h>
|
||||
|
|
|
@ -80,7 +80,7 @@ struct pt_regs {
|
|||
unsigned long areg[16];
|
||||
};
|
||||
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
# define arch_has_single_step() (1)
|
||||
# define task_pt_regs(tsk) ((struct pt_regs*) \
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef _XTENSA_VECTORS_H
|
||||
#define _XTENSA_VECTORS_H
|
||||
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
#include <asm/kmem_layout.h>
|
||||
|
||||
#if XCHAL_HAVE_PTP_MMU
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <linux/log2.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
/* Breakpoint currently in use for each IBREAKA. */
|
||||
static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[XCHAL_NUM_IBREAK]);
|
||||
|
|
|
@ -650,6 +650,9 @@ c_show(struct seq_file *f, void *slot)
|
|||
#endif
|
||||
#if XCHAL_HAVE_S32C1I
|
||||
"s32c1i "
|
||||
#endif
|
||||
#if XCHAL_HAVE_EXCLUSIVE
|
||||
"exclusive "
|
||||
#endif
|
||||
"\n");
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#include <asm/page.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
#include <asm/core.h>
|
||||
#include <asm/vectors.h>
|
||||
#include <variant/core.h>
|
||||
|
||||
OUTPUT_ARCH(xtensa)
|
||||
ENTRY(_start)
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <variant/core.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
/*
|
||||
* computes a partial checksum, e.g. for TCP/UDP fragments
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <variant/core.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
/*
|
||||
* void *memcpy(void *dst, const void *src, size_t len);
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <variant/core.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
/*
|
||||
* void *memset(void *dst, int c, size_t length)
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <variant/core.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
/*
|
||||
* char *__strncpy_user(char *dst, const char *src, size_t len)
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <variant/core.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
/*
|
||||
* size_t __strnlen_user(const char *s, size_t len)
|
||||
|
|
|
@ -54,8 +54,8 @@
|
|||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <variant/core.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
.text
|
||||
ENTRY(__xtensa_copy_user)
|
||||
|
|
|
@ -297,8 +297,7 @@ static int __init simdisk_setup(struct simdisk *dev, int which,
|
|||
blk_cleanup_queue(dev->queue);
|
||||
dev->queue = NULL;
|
||||
out_alloc_queue:
|
||||
simc_close(dev->fd);
|
||||
return -EIO;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int __init simdisk_init(void)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef _XTENSA_XT2000_HARDWARE_H
|
||||
#define _XTENSA_XT2000_HARDWARE_H
|
||||
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
|
||||
/*
|
||||
* On-board components.
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#ifndef _XTENSA_XT2000_SERIAL_H
|
||||
#define _XTENSA_XT2000_SERIAL_H
|
||||
|
||||
#include <variant/core.h>
|
||||
#include <asm/core.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/* National-Semi PC16552D DUART: */
|
||||
|
|
Loading…
Reference in New Issue
Block a user