Merge tag 'mips_5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
Pull MIPS updates from Paul Burton: "Main MIPS changes: - boot_mem_map is removed, providing a nice cleanup made possible by the recent removal of bootmem. - Some fixes to atomics, in general providing compiler barriers for smp_mb__{before,after}_atomic plus fixes specific to Loongson CPUs or MIPS32 systems using cmpxchg64(). - Conversion to the new generic VDSO infrastructure courtesy of Vincenzo Frascino. - Removal of undefined behavior in set_io_port_base(), fixing the behavior of some MIPS kernel configurations when built with recent clang versions. - Initial MIPS32 huge page support, functional on at least Ingenic SoCs. - pte_special() is now supported for some configurations, allowing among other things generic fast GUP to be used. - Miscellaneous fixes & cleanups. And platform specific changes: - Major improvements to Ingenic SoC support from Paul Cercueil, mostly enabled by the inclusion of the new TCU (timer-counter unit) drivers he's spent a very patient year or so working on. Plus some fixes for X1000 SoCs from Zhou Yanjie. - Netgear R6200 v1 systems are now supported by the bcm47xx platform. - DT updates for BMIPS, Lantiq & Microsemi Ocelot systems" * tag 'mips_5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (89 commits) MIPS: Detect bad _PFN_SHIFT values MIPS: Disable pte_special() for MIPS32 with RiXi MIPS: ralink: deactivate PCI support for SOC_MT7621 mips: compat: vdso: Use legacy syscalls as fallback MIPS: Drop Loongson _CACHE_* definitions MIPS: tlbex: Remove cpu_has_local_ebase MIPS: tlbex: Simplify r3k check MIPS: Select R3k-style TLB in Kconfig MIPS: PCI: refactor ioc3 special handling mips: remove ioremap_cachable mips/atomic: Fix smp_mb__{before,after}_atomic() mips/atomic: Fix loongson_llsc_mb() wreckage mips/atomic: Fix cmpxchg64 barriers MIPS: Octeon: remove duplicated include from dma-octeon.c firmware: bcm47xx_nvram: Allow COMPILE_TEST firmware: bcm47xx_nvram: Correct size_t printf format MIPS: Treat Loongson Extensions as ASEs MIPS: Remove dev_err() usage after platform_get_irq() MIPS: dts: mscc: describe the PTP ready interrupt MIPS: dts: mscc: describe the PTP register range ...
This commit is contained in:
@@ -135,18 +135,9 @@
|
||||
*/
|
||||
#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */
|
||||
|
||||
#ifndef CONFIG_CPU_R8000
|
||||
|
||||
/*
|
||||
* The R8000 doesn't have the 32-bit compat spaces so we don't define them
|
||||
* in order to catch bugs in the source code.
|
||||
*/
|
||||
|
||||
#define COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000)
|
||||
#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
|
||||
|
||||
#endif
|
||||
|
||||
#define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK)
|
||||
#define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE)
|
||||
|
||||
|
@@ -68,7 +68,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \
|
||||
"\t" __scbeqz " %0, 1b \n" \
|
||||
" .set pop \n" \
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@@ -98,7 +98,7 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \
|
||||
" .set pop \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@@ -132,7 +132,7 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \
|
||||
" move %0, %1 \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@@ -193,6 +193,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
||||
if (kernel_uses_llsc) {
|
||||
int temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
@@ -200,16 +201,16 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
|
||||
" .set pop \n"
|
||||
" subu %0, %1, %3 \n"
|
||||
" move %1, %0 \n"
|
||||
" bltz %0, 1f \n"
|
||||
" bltz %0, 2f \n"
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
" sc %1, %2 \n"
|
||||
"\t" __scbeqz " %1, 1b \n"
|
||||
"1: \n"
|
||||
"2: \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (result), "=&r" (temp),
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter)
|
||||
: "Ir" (i));
|
||||
: "Ir" (i) : __LLSC_CLOBBER);
|
||||
} else {
|
||||
unsigned long flags;
|
||||
|
||||
@@ -269,7 +270,7 @@ static __inline__ void atomic64_##op(s64 i, atomic64_t * v) \
|
||||
"\t" __scbeqz " %0, 1b \n" \
|
||||
" .set pop \n" \
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@@ -299,7 +300,7 @@ static __inline__ s64 atomic64_##op##_return_relaxed(s64 i, atomic64_t * v) \
|
||||
" .set pop \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
@@ -333,7 +334,7 @@ static __inline__ s64 atomic64_fetch_##op##_relaxed(s64 i, atomic64_t * v) \
|
||||
" .set pop \n" \
|
||||
: "=&r" (result), "=&r" (temp), \
|
||||
"+" GCC_OFF_SMALL_ASM() (v->counter) \
|
||||
: "Ir" (i)); \
|
||||
: "Ir" (i) : __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long flags; \
|
||||
\
|
||||
|
@@ -211,14 +211,22 @@
|
||||
#define __smp_wmb() barrier()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When LL/SC does imply order, it must also be a compiler barrier to avoid the
|
||||
* compiler from reordering where the CPU will not. When it does not imply
|
||||
* order, the compiler is also free to reorder across the LL/SC loop and
|
||||
* ordering will be done by smp_llsc_mb() and friends.
|
||||
*/
|
||||
#if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP)
|
||||
#define __WEAK_LLSC_MB " sync \n"
|
||||
#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
|
||||
#define __LLSC_CLOBBER
|
||||
#else
|
||||
#define __WEAK_LLSC_MB " \n"
|
||||
#define smp_llsc_mb() do { } while (0)
|
||||
#define __LLSC_CLOBBER "memory"
|
||||
#endif
|
||||
|
||||
#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
|
||||
|
||||
#ifdef CONFIG_CPU_CAVIUM_OCTEON
|
||||
#define smp_mb__before_llsc() smp_wmb()
|
||||
#define __smp_mb__before_llsc() __smp_wmb()
|
||||
@@ -238,36 +246,40 @@
|
||||
|
||||
/*
|
||||
* Some Loongson 3 CPUs have a bug wherein execution of a memory access (load,
|
||||
* store or pref) in between an ll & sc can cause the sc instruction to
|
||||
* store or prefetch) in between an LL & SC can cause the SC instruction to
|
||||
* erroneously succeed, breaking atomicity. Whilst it's unusual to write code
|
||||
* containing such sequences, this bug bites harder than we might otherwise
|
||||
* expect due to reordering & speculation:
|
||||
*
|
||||
* 1) A memory access appearing prior to the ll in program order may actually
|
||||
* be executed after the ll - this is the reordering case.
|
||||
* 1) A memory access appearing prior to the LL in program order may actually
|
||||
* be executed after the LL - this is the reordering case.
|
||||
*
|
||||
* In order to avoid this we need to place a memory barrier (ie. a sync
|
||||
* instruction) prior to every ll instruction, in between it & any earlier
|
||||
* memory access instructions. Many of these cases are already covered by
|
||||
* smp_mb__before_llsc() but for the remaining cases, typically ones in
|
||||
* which multiple CPUs may operate on a memory location but ordering is not
|
||||
* usually guaranteed, we use loongson_llsc_mb() below.
|
||||
* In order to avoid this we need to place a memory barrier (ie. a SYNC
|
||||
* instruction) prior to every LL instruction, in between it and any earlier
|
||||
* memory access instructions.
|
||||
*
|
||||
* This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later.
|
||||
*
|
||||
* 2) If a conditional branch exists between an ll & sc with a target outside
|
||||
* of the ll-sc loop, for example an exit upon value mismatch in cmpxchg()
|
||||
* 2) If a conditional branch exists between an LL & SC with a target outside
|
||||
* of the LL-SC loop, for example an exit upon value mismatch in cmpxchg()
|
||||
* or similar, then misprediction of the branch may allow speculative
|
||||
* execution of memory accesses from outside of the ll-sc loop.
|
||||
* execution of memory accesses from outside of the LL-SC loop.
|
||||
*
|
||||
* In order to avoid this we need a memory barrier (ie. a sync instruction)
|
||||
* In order to avoid this we need a memory barrier (ie. a SYNC instruction)
|
||||
* at each affected branch target, for which we also use loongson_llsc_mb()
|
||||
* defined below.
|
||||
*
|
||||
* This case affects all current Loongson 3 CPUs.
|
||||
*
|
||||
* The above described cases cause an error in the cache coherence protocol;
|
||||
* such that the Invalidate of a competing LL-SC goes 'missing' and SC
|
||||
* erroneously observes its core still has Exclusive state and lets the SC
|
||||
* proceed.
|
||||
*
|
||||
* Therefore the error only occurs on SMP systems.
|
||||
*/
|
||||
#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS /* Loongson-3's LLSC workaround */
|
||||
#define loongson_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
|
||||
#define loongson_llsc_mb() __asm__ __volatile__("sync" : : :"memory")
|
||||
#else
|
||||
#define loongson_llsc_mb() do { } while (0)
|
||||
#endif
|
||||
|
@@ -66,7 +66,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" beqzl %0, 1b \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m));
|
||||
: "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m)
|
||||
: __LLSC_CLOBBER);
|
||||
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
|
||||
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
|
||||
loongson_llsc_mb();
|
||||
@@ -76,7 +77,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" " __INS "%0, %3, %2, 1 \n"
|
||||
" " __SC "%0, %1 \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (bit), "r" (~0));
|
||||
: "ir" (bit), "r" (~0)
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
|
||||
} else if (kernel_uses_llsc) {
|
||||
@@ -90,7 +92,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" " __SC "%0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (1UL << bit));
|
||||
: "ir" (1UL << bit)
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
} else
|
||||
__mips_set_bit(nr, addr);
|
||||
@@ -122,7 +125,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" beqzl %0, 1b \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (~(1UL << bit)));
|
||||
: "ir" (~(1UL << bit))
|
||||
: __LLSC_CLOBBER);
|
||||
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
|
||||
} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
|
||||
loongson_llsc_mb();
|
||||
@@ -132,7 +136,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" " __INS "%0, $0, %2, 1 \n"
|
||||
" " __SC "%0, %1 \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (bit));
|
||||
: "ir" (bit)
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
|
||||
} else if (kernel_uses_llsc) {
|
||||
@@ -146,7 +151,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" " __SC "%0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (~(1UL << bit)));
|
||||
: "ir" (~(1UL << bit))
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
} else
|
||||
__mips_clear_bit(nr, addr);
|
||||
@@ -192,7 +198,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" beqzl %0, 1b \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (1UL << bit));
|
||||
: "ir" (1UL << bit)
|
||||
: __LLSC_CLOBBER);
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
@@ -207,7 +214,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
|
||||
" " __SC "%0, %1 \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
|
||||
: "ir" (1UL << bit));
|
||||
: "ir" (1UL << bit)
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
} else
|
||||
__mips_change_bit(nr, addr);
|
||||
@@ -244,11 +252,12 @@ static inline int test_and_set_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@@ -259,7 +268,7 @@ static inline int test_and_set_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!res));
|
||||
|
||||
res = temp & (1UL << bit);
|
||||
@@ -300,11 +309,12 @@ static inline int test_and_set_bit_lock(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+m" (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@@ -315,7 +325,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!res));
|
||||
|
||||
res = temp & (1UL << bit);
|
||||
@@ -358,12 +368,13 @@ static inline int test_and_clear_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
|
||||
} else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" " __LL "%0, %1 # test_and_clear_bit \n"
|
||||
@@ -372,13 +383,14 @@ static inline int test_and_clear_bit(unsigned long nr,
|
||||
" " __SC "%0, %1 \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "ir" (bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!temp));
|
||||
#endif
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@@ -390,7 +402,7 @@ static inline int test_and_clear_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!res));
|
||||
|
||||
res = temp & (1UL << bit);
|
||||
@@ -433,11 +445,12 @@ static inline int test_and_change_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} else if (kernel_uses_llsc) {
|
||||
unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
|
||||
unsigned long temp;
|
||||
|
||||
loongson_llsc_mb();
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
@@ -448,7 +461,7 @@ static inline int test_and_change_bit(unsigned long nr,
|
||||
" .set pop \n"
|
||||
: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res)
|
||||
: "r" (1UL << bit)
|
||||
: "memory");
|
||||
: __LLSC_CLOBBER);
|
||||
} while (unlikely(!res));
|
||||
|
||||
res = temp & (1UL << bit);
|
||||
|
@@ -81,34 +81,19 @@ enum loongson_machine_type {
|
||||
#define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */
|
||||
#define MACH_INGENIC_JZ4770 2 /* JZ4770 SOC */
|
||||
#define MACH_INGENIC_JZ4780 3 /* JZ4780 SOC */
|
||||
#define MACH_INGENIC_X1000 4 /* X1000 SOC */
|
||||
|
||||
extern char *system_type;
|
||||
const char *get_system_type(void);
|
||||
|
||||
extern unsigned long mips_machtype;
|
||||
|
||||
#define BOOT_MEM_MAP_MAX 32
|
||||
#define BOOT_MEM_RAM 1
|
||||
#define BOOT_MEM_ROM_DATA 2
|
||||
#define BOOT_MEM_RESERVED 3
|
||||
#define BOOT_MEM_INIT_RAM 4
|
||||
#define BOOT_MEM_NOMAP 5
|
||||
|
||||
/*
|
||||
* A memory map that's built upon what was determined
|
||||
* or specified on the command line.
|
||||
*/
|
||||
struct boot_mem_map {
|
||||
int nr_map;
|
||||
struct boot_mem_map_entry {
|
||||
phys_addr_t addr; /* start of memory segment */
|
||||
phys_addr_t size; /* size of memory segment */
|
||||
long type; /* type of memory segment */
|
||||
} map[BOOT_MEM_MAP_MAX];
|
||||
};
|
||||
|
||||
extern struct boot_mem_map boot_mem_map;
|
||||
|
||||
extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type);
|
||||
extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max);
|
||||
|
||||
|
@@ -46,6 +46,7 @@ extern unsigned long __xchg_called_with_bad_pointer(void)
|
||||
__typeof(*(m)) __ret; \
|
||||
\
|
||||
if (kernel_uses_llsc) { \
|
||||
loongson_llsc_mb(); \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
@@ -60,7 +61,7 @@ extern unsigned long __xchg_called_with_bad_pointer(void)
|
||||
" .set pop \n" \
|
||||
: "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \
|
||||
: GCC_OFF_SMALL_ASM() (*m), "Jr" (val) \
|
||||
: "memory"); \
|
||||
: __LLSC_CLOBBER); \
|
||||
} else { \
|
||||
unsigned long __flags; \
|
||||
\
|
||||
@@ -117,6 +118,7 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
|
||||
__typeof(*(m)) __ret; \
|
||||
\
|
||||
if (kernel_uses_llsc) { \
|
||||
loongson_llsc_mb(); \
|
||||
__asm__ __volatile__( \
|
||||
" .set push \n" \
|
||||
" .set noat \n" \
|
||||
@@ -132,8 +134,9 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
|
||||
" .set pop \n" \
|
||||
"2: \n" \
|
||||
: "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \
|
||||
: GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \
|
||||
: "memory"); \
|
||||
: GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \
|
||||
: __LLSC_CLOBBER); \
|
||||
loongson_llsc_mb(); \
|
||||
} else { \
|
||||
unsigned long __flags; \
|
||||
\
|
||||
@@ -229,6 +232,7 @@ static inline unsigned long __cmpxchg64(volatile void *ptr,
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
|
||||
loongson_llsc_mb();
|
||||
asm volatile(
|
||||
" .set push \n"
|
||||
" .set " MIPS_ISA_ARCH_LEVEL " \n"
|
||||
@@ -274,6 +278,7 @@ static inline unsigned long __cmpxchg64(volatile void *ptr,
|
||||
"r" (old),
|
||||
"r" (new)
|
||||
: "memory");
|
||||
loongson_llsc_mb();
|
||||
|
||||
local_irq_restore(flags);
|
||||
return ret;
|
||||
@@ -290,10 +295,13 @@ static inline unsigned long __cmpxchg64(volatile void *ptr,
|
||||
* will cause a build error unless cpu_has_64bits is a \
|
||||
* compile-time constant 1. \
|
||||
*/ \
|
||||
if (cpu_has_64bits && kernel_uses_llsc) \
|
||||
if (cpu_has_64bits && kernel_uses_llsc) { \
|
||||
smp_mb__before_llsc(); \
|
||||
__res = __cmpxchg64((ptr), __old, __new); \
|
||||
else \
|
||||
smp_llsc_mb(); \
|
||||
} else { \
|
||||
__res = __cmpxchg64_unsupported(); \
|
||||
} \
|
||||
\
|
||||
__res; \
|
||||
})
|
||||
|
@@ -243,9 +243,6 @@
|
||||
#ifndef cpu_has_pindexed_dcache
|
||||
#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
|
||||
#endif
|
||||
#ifndef cpu_has_local_ebase
|
||||
#define cpu_has_local_ebase 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
|
||||
@@ -397,6 +394,22 @@
|
||||
#define cpu_has_dsp3 __ase(MIPS_ASE_DSP3)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_loongson_mmi
|
||||
#define cpu_has_loongson_mmi __ase(MIPS_ASE_LOONGSON_MMI)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_loongson_cam
|
||||
#define cpu_has_loongson_cam __ase(MIPS_ASE_LOONGSON_CAM)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_loongson_ext
|
||||
#define cpu_has_loongson_ext __ase(MIPS_ASE_LOONGSON_EXT)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_loongson_ext2
|
||||
#define cpu_has_loongson_ext2 __ase(MIPS_ASE_LOONGSON_EXT2)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_mipsmt
|
||||
#define cpu_has_mipsmt __isa_lt_and_ase(6, MIPS_ASE_MIPSMT)
|
||||
#endif
|
||||
|
@@ -38,7 +38,7 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
||||
#if defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) || \
|
||||
defined(CONFIG_SYS_HAS_CPU_MIPS32_R2)
|
||||
case CPU_4KEC:
|
||||
case CPU_JZRISC:
|
||||
case CPU_XBURST:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_MIPS32_R2
|
||||
@@ -116,11 +116,6 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
||||
case CPU_VR4181A:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R4300
|
||||
case CPU_R4300:
|
||||
case CPU_R4310:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R4X00
|
||||
case CPU_R4000PC:
|
||||
case CPU_R4000SC:
|
||||
@@ -143,10 +138,6 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
||||
case CPU_R5000:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R5432
|
||||
case CPU_R5432:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R5500
|
||||
case CPU_R5500:
|
||||
#endif
|
||||
@@ -155,10 +146,6 @@ static inline int __pure __get_cpu_type(const int cpu_type)
|
||||
case CPU_NEVADA:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R8000
|
||||
case CPU_R8000:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_HAS_CPU_R10000
|
||||
case CPU_R10000:
|
||||
case CPU_R12000:
|
||||
|
@@ -47,7 +47,7 @@
|
||||
#define PRID_COMP_CAVIUM 0x0d0000
|
||||
#define PRID_COMP_LOONGSON 0x140000
|
||||
#define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750 */
|
||||
#define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775 */
|
||||
#define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775, X1000 */
|
||||
#define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */
|
||||
|
||||
/*
|
||||
@@ -183,7 +183,7 @@
|
||||
* These are the PRID's for when 23:16 == PRID_COMP_INGENIC_*
|
||||
*/
|
||||
|
||||
#define PRID_IMP_JZRISC 0x0200
|
||||
#define PRID_IMP_XBURST 0x0200
|
||||
|
||||
/*
|
||||
* These are the PRID's for when 23:16 == PRID_COMP_NETLOGIC
|
||||
@@ -293,18 +293,13 @@ enum cpu_type_enum {
|
||||
/*
|
||||
* R4000 class processors
|
||||
*/
|
||||
CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310,
|
||||
CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200,
|
||||
CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600, CPU_R4640, CPU_R4650,
|
||||
CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R5432, CPU_R10000,
|
||||
CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R10000,
|
||||
CPU_R12000, CPU_R14000, CPU_R16000, CPU_VR41XX, CPU_VR4111, CPU_VR4121,
|
||||
CPU_VR4122, CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000,
|
||||
CPU_SR71000, CPU_TX49XX,
|
||||
|
||||
/*
|
||||
* R8000 class processors
|
||||
*/
|
||||
CPU_R8000,
|
||||
|
||||
/*
|
||||
* TX3900 class processors
|
||||
*/
|
||||
@@ -315,7 +310,7 @@ enum cpu_type_enum {
|
||||
*/
|
||||
CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
|
||||
CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
|
||||
CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,
|
||||
CPU_BMIPS4380, CPU_BMIPS5000, CPU_XBURST, CPU_LOONGSON1, CPU_M14KC,
|
||||
CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K,
|
||||
CPU_M5150, CPU_I6400, CPU_P6600, CPU_M6250,
|
||||
|
||||
@@ -433,5 +428,9 @@ enum cpu_type_enum {
|
||||
#define MIPS_ASE_MSA 0x00000100 /* MIPS SIMD Architecture */
|
||||
#define MIPS_ASE_DSP3 0x00000200 /* Signal Processing ASE Rev 3*/
|
||||
#define MIPS_ASE_MIPS16E2 0x00000400 /* MIPS16e2 */
|
||||
#define MIPS_ASE_LOONGSON_MMI 0x00000800 /* Loongson MultiMedia extensions Instructions */
|
||||
#define MIPS_ASE_LOONGSON_CAM 0x00001000 /* Loongson CAM */
|
||||
#define MIPS_ASE_LOONGSON_EXT 0x00002000 /* Loongson EXTensions */
|
||||
#define MIPS_ASE_LOONGSON_EXT2 0x00004000 /* Loongson EXTensions R2 */
|
||||
|
||||
#endif /* _ASM_CPU_H */
|
||||
|
@@ -63,21 +63,11 @@
|
||||
* instruction, so the lower 16 bits must be zero. Should be true on
|
||||
* on any sane architecture; generic code does not use this assumption.
|
||||
*/
|
||||
extern const unsigned long mips_io_port_base;
|
||||
extern unsigned long mips_io_port_base;
|
||||
|
||||
/*
|
||||
* Gcc will generate code to load the value of mips_io_port_base after each
|
||||
* function call which may be fairly wasteful in some cases. So we don't
|
||||
* play quite by the book. We tell gcc mips_io_port_base is a long variable
|
||||
* which solves the code generation issue. Now we need to violate the
|
||||
* aliasing rules a little to make initialization possible and finally we
|
||||
* will need the barrier() to fight side effects of the aliasing chat.
|
||||
* This trickery will eventually collapse under gcc's optimizer. Oh well.
|
||||
*/
|
||||
static inline void set_io_port_base(unsigned long base)
|
||||
{
|
||||
* (unsigned long *) &mips_io_port_base = base;
|
||||
barrier();
|
||||
mips_io_port_base = base;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -262,11 +252,11 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset,
|
||||
#define ioremap_uc ioremap_nocache
|
||||
|
||||
/*
|
||||
* ioremap_cachable - map bus memory into CPU space
|
||||
* ioremap_cache - map bus memory into CPU space
|
||||
* @offset: bus address of the memory
|
||||
* @size: size of the resource to map
|
||||
*
|
||||
* ioremap_nocache performs a platform specific sequence of operations to
|
||||
* ioremap_cache performs a platform specific sequence of operations to
|
||||
* make bus memory CPU accessible via the readb/readw/readl/writeb/
|
||||
* writew/writel functions and the other mmio helpers. The returned
|
||||
* address is not guaranteed to be usable directly as a virtual
|
||||
@@ -276,9 +266,8 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset,
|
||||
* the CPU. Also enables full write-combining. Useful for some
|
||||
* memory-like regions on I/O busses.
|
||||
*/
|
||||
#define ioremap_cachable(offset, size) \
|
||||
#define ioremap_cache(offset, size) \
|
||||
__ioremap_mode((offset), (size), _page_cachable_default)
|
||||
#define ioremap_cache ioremap_cachable
|
||||
|
||||
/*
|
||||
* ioremap_wc - map bus memory into CPU space
|
||||
|
@@ -98,6 +98,7 @@ enum bcm47xx_board {
|
||||
BCM47XX_BOARD_MOTOROLA_WR850GP,
|
||||
BCM47XX_BOARD_MOTOROLA_WR850GV2V3,
|
||||
|
||||
BCM47XX_BOARD_NETGEAR_R6200_V1,
|
||||
BCM47XX_BOARD_NETGEAR_WGR614V8,
|
||||
BCM47XX_BOARD_NETGEAR_WGR614V9,
|
||||
BCM47XX_BOARD_NETGEAR_WGR614_V10,
|
||||
|
@@ -45,7 +45,6 @@
|
||||
#define cpu_has_ic_fills_f_dc 0
|
||||
#define cpu_has_64bits 1
|
||||
#define cpu_has_octeon_cache 1
|
||||
#define cpu_has_saa octeon_has_saa()
|
||||
#define cpu_has_mips32r1 1
|
||||
#define cpu_has_mips32r2 1
|
||||
#define cpu_has_mips64r1 1
|
||||
@@ -60,7 +59,6 @@
|
||||
|
||||
#define cpu_has_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
|
||||
|
||||
#define ARCH_HAS_IRQ_PER_CPU 1
|
||||
#define ARCH_HAS_SPINLOCK_PREFETCH 1
|
||||
#define spin_lock_prefetch(x) prefetch(x)
|
||||
#define PREFETCH_STRIDE 128
|
||||
@@ -73,13 +71,6 @@
|
||||
#define ARCH_HAS_USABLE_BUILTIN_POPCOUNT 1
|
||||
#endif
|
||||
|
||||
static inline int octeon_has_saa(void)
|
||||
{
|
||||
int id;
|
||||
asm volatile ("mfc0 %0, $15,0" : "=r" (id));
|
||||
return id >= 0x000d0300;
|
||||
}
|
||||
|
||||
/*
|
||||
* The last 256MB are reserved for device to device mappings and the
|
||||
* BAR1 hole.
|
||||
|
@@ -12,7 +12,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@@ -32,7 +32,6 @@
|
||||
#define cpu_has_vtag_icache 0
|
||||
#define cpu_has_ic_fills_f_dc 0
|
||||
#define cpu_has_pindexed_dcache 0
|
||||
#define cpu_has_local_ebase 0
|
||||
#define cpu_icache_snoops_remote_store 1
|
||||
#define cpu_has_mips_4 0
|
||||
#define cpu_has_mips_5 0
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@@ -15,7 +15,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 1
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 1
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 1
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
|
||||
* JZ4740 GPIO pin definitions
|
||||
*/
|
||||
|
||||
#ifndef _JZ_GPIO_H
|
||||
#define _JZ_GPIO_H
|
||||
|
||||
#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
|
||||
#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
|
||||
#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
|
||||
#define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
|
||||
|
||||
#endif
|
@@ -1,58 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_JZ4740_JZ4740_FB_H__
|
||||
#define __ASM_MACH_JZ4740_JZ4740_FB_H__
|
||||
|
||||
#include <linux/fb.h>
|
||||
|
||||
enum jz4740_fb_lcd_type {
|
||||
JZ_LCD_TYPE_GENERIC_16_BIT = 0,
|
||||
JZ_LCD_TYPE_GENERIC_18_BIT = 0 | (1 << 4),
|
||||
JZ_LCD_TYPE_SPECIAL_TFT_1 = 1,
|
||||
JZ_LCD_TYPE_SPECIAL_TFT_2 = 2,
|
||||
JZ_LCD_TYPE_SPECIAL_TFT_3 = 3,
|
||||
JZ_LCD_TYPE_NON_INTERLACED_CCIR656 = 5,
|
||||
JZ_LCD_TYPE_INTERLACED_CCIR656 = 7,
|
||||
JZ_LCD_TYPE_SINGLE_COLOR_STN = 8,
|
||||
JZ_LCD_TYPE_SINGLE_MONOCHROME_STN = 9,
|
||||
JZ_LCD_TYPE_DUAL_COLOR_STN = 10,
|
||||
JZ_LCD_TYPE_DUAL_MONOCHROME_STN = 11,
|
||||
JZ_LCD_TYPE_8BIT_SERIAL = 12,
|
||||
};
|
||||
|
||||
#define JZ4740_FB_SPECIAL_TFT_CONFIG(start, stop) (((start) << 16) | (stop))
|
||||
|
||||
/*
|
||||
* width: width of the lcd display in mm
|
||||
* height: height of the lcd display in mm
|
||||
* num_modes: size of modes
|
||||
* modes: list of valid video modes
|
||||
* bpp: bits per pixel for the lcd
|
||||
* lcd_type: lcd type
|
||||
*/
|
||||
|
||||
struct jz4740_fb_platform_data {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
|
||||
size_t num_modes;
|
||||
struct fb_videomode *modes;
|
||||
|
||||
unsigned int bpp;
|
||||
enum jz4740_fb_lcd_type lcd_type;
|
||||
|
||||
struct {
|
||||
uint32_t spl;
|
||||
uint32_t cls;
|
||||
uint32_t ps;
|
||||
uint32_t rev;
|
||||
} special_tft_config;
|
||||
|
||||
unsigned pixclk_falling_edge:1;
|
||||
unsigned date_enable_active_low:1;
|
||||
};
|
||||
|
||||
#endif
|
@@ -1,12 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __LINUX_MMC_JZ4740_MMC
|
||||
#define __LINUX_MMC_JZ4740_MMC
|
||||
|
||||
struct jz4740_mmc_platform_data {
|
||||
unsigned card_detect_active_low:1;
|
||||
unsigned read_only_active_low:1;
|
||||
|
||||
unsigned data_1bit:1;
|
||||
};
|
||||
|
||||
#endif
|
@@ -1,26 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
|
||||
* JZ4740 platform device definitions
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __JZ4740_PLATFORM_H
|
||||
#define __JZ4740_PLATFORM_H
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
extern struct platform_device jz4740_udc_device;
|
||||
extern struct platform_device jz4740_udc_xceiv_device;
|
||||
extern struct platform_device jz4740_mmc_device;
|
||||
extern struct platform_device jz4740_i2c_device;
|
||||
extern struct platform_device jz4740_nand_device;
|
||||
extern struct platform_device jz4740_framebuffer_device;
|
||||
extern struct platform_device jz4740_i2s_device;
|
||||
extern struct platform_device jz4740_pcm_device;
|
||||
extern struct platform_device jz4740_codec_device;
|
||||
extern struct platform_device jz4740_adc_device;
|
||||
extern struct platform_device jz4740_pwm_device;
|
||||
extern struct platform_device jz4740_dma_device;
|
||||
|
||||
#endif
|
@@ -43,7 +43,6 @@
|
||||
#define cpu_has_vint 0
|
||||
#define cpu_has_vtag_icache 0
|
||||
#define cpu_has_watch 1
|
||||
#define cpu_has_local_ebase 0
|
||||
|
||||
#ifdef CONFIG_CPU_LOONGSON3
|
||||
#define cpu_has_wsbh 1
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 1
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 1
|
||||
|
@@ -15,7 +15,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 1
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
|
||||
#if defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
|
||||
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#define R4600_V1_INDEX_ICACHEOP_WAR 0
|
||||
#define R4600_V1_HIT_CACHEOP_WAR 0
|
||||
#define R4600_V2_HIT_CACHEOP_WAR 0
|
||||
#define R5432_CP0_INTERRUPT_WAR 0
|
||||
#define BCM1250_M3_WAR 0
|
||||
#define SIBYTE_1956_WAR 0
|
||||
#define MIPS4K_ICACHE_REFILL_WAR 0
|
||||
|
@@ -689,6 +689,9 @@
|
||||
#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
|
||||
#define MIPS_CONF7_AR (_ULCAST_(1) << 16)
|
||||
|
||||
/* Ingenic Config7 bits */
|
||||
#define MIPS_CONF7_BTB_LOOP_EN (_ULCAST_(1) << 4)
|
||||
|
||||
/* Config7 Bits specific to MIPS Technologies. */
|
||||
|
||||
/* Performance counters implemented Per TC */
|
||||
@@ -2813,6 +2816,7 @@ __BUILD_SET_C0(status)
|
||||
__BUILD_SET_C0(cause)
|
||||
__BUILD_SET_C0(config)
|
||||
__BUILD_SET_C0(config5)
|
||||
__BUILD_SET_C0(config7)
|
||||
__BUILD_SET_C0(intcontrol)
|
||||
__BUILD_SET_C0(intctl)
|
||||
__BUILD_SET_C0(srsmap)
|
||||
|
@@ -103,22 +103,16 @@ search_module_dbetables(unsigned long addr)
|
||||
#define MODULE_PROC_FAMILY "TX39XX "
|
||||
#elif defined CONFIG_CPU_VR41XX
|
||||
#define MODULE_PROC_FAMILY "VR41XX "
|
||||
#elif defined CONFIG_CPU_R4300
|
||||
#define MODULE_PROC_FAMILY "R4300 "
|
||||
#elif defined CONFIG_CPU_R4X00
|
||||
#define MODULE_PROC_FAMILY "R4X00 "
|
||||
#elif defined CONFIG_CPU_TX49XX
|
||||
#define MODULE_PROC_FAMILY "TX49XX "
|
||||
#elif defined CONFIG_CPU_R5000
|
||||
#define MODULE_PROC_FAMILY "R5000 "
|
||||
#elif defined CONFIG_CPU_R5432
|
||||
#define MODULE_PROC_FAMILY "R5432 "
|
||||
#elif defined CONFIG_CPU_R5500
|
||||
#define MODULE_PROC_FAMILY "R5500 "
|
||||
#elif defined CONFIG_CPU_NEVADA
|
||||
#define MODULE_PROC_FAMILY "NEVADA "
|
||||
#elif defined CONFIG_CPU_R8000
|
||||
#define MODULE_PROC_FAMILY "R8000 "
|
||||
#elif defined CONFIG_CPU_R10000
|
||||
#define MODULE_PROC_FAMILY "R10000 "
|
||||
#elif defined CONFIG_CPU_RM7000
|
||||
|
@@ -51,7 +51,7 @@ extern void octeon_setup_delays(void);
|
||||
extern void octeon_io_clk_delay(unsigned long);
|
||||
|
||||
#define OCTEON_ARGV_MAX_ARGS 64
|
||||
#define OCTOEN_SERIAL_LEN 20
|
||||
#define OCTEON_SERIAL_LEN 20
|
||||
|
||||
struct octeon_boot_descriptor {
|
||||
#ifdef __BIG_ENDIAN_BITFIELD
|
||||
@@ -102,7 +102,7 @@ struct octeon_boot_descriptor {
|
||||
uint16_t chip_type;
|
||||
uint8_t chip_rev_major;
|
||||
uint8_t chip_rev_minor;
|
||||
char board_serial_number[OCTOEN_SERIAL_LEN];
|
||||
char board_serial_number[OCTEON_SERIAL_LEN];
|
||||
uint8_t mac_addr_base[6];
|
||||
uint8_t mac_addr_count;
|
||||
uint64_t cvmx_desc_vaddr;
|
||||
|
@@ -23,6 +23,24 @@
|
||||
#include <asm/highmem.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Regarding 32-bit MIPS huge page support (and the tradeoff it entails):
|
||||
*
|
||||
* We use the same huge page sizes as 64-bit MIPS. Assuming a 4KB page size,
|
||||
* our 2-level table layout would normally have a PGD entry cover a contiguous
|
||||
* 4MB virtual address region (pointing to a 4KB PTE page of 1,024 32-bit pte_t
|
||||
* pointers, each pointing to a 4KB physical page). The problem is that 4MB,
|
||||
* spanning both halves of a TLB EntryLo0,1 pair, requires 2MB hardware page
|
||||
* support, not one of the standard supported sizes (1MB,4MB,16MB,...).
|
||||
* To correct for this, when huge pages are enabled, we halve the number of
|
||||
* pointers a PTE page holds, making its last half go to waste. Correspondingly,
|
||||
* we double the number of PGD pages. Overall, page table memory overhead
|
||||
* increases to match 64-bit MIPS, but PTE lookups remain CPU cache-friendly.
|
||||
*
|
||||
* NOTE: We don't yet support huge pages if extended-addressing is enabled
|
||||
* (i.e. EVA, XPA, 36-bit Alchemy/Netlogic).
|
||||
*/
|
||||
|
||||
extern int temp_tlb_entry;
|
||||
|
||||
/*
|
||||
@@ -44,7 +62,12 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
|
||||
*/
|
||||
|
||||
/* PGDIR_SHIFT determines what a third-level page table entry can map */
|
||||
#define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2)
|
||||
#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
|
||||
# define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2 - 1)
|
||||
#else
|
||||
# define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2)
|
||||
#endif
|
||||
|
||||
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
||||
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||
|
||||
@@ -52,14 +75,23 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
|
||||
* Entries per page directory level: we use two-level, so
|
||||
* we don't really have any PUD/PMD directory physically.
|
||||
*/
|
||||
#define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2)
|
||||
#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
|
||||
# define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2 + 1)
|
||||
#else
|
||||
# define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2)
|
||||
#endif
|
||||
|
||||
#define PGD_ORDER (__PGD_ORDER >= 0 ? __PGD_ORDER : 0)
|
||||
#define PUD_ORDER aieeee_attempt_to_allocate_pud
|
||||
#define PMD_ORDER 1
|
||||
#define PMD_ORDER aieeee_attempt_to_allocate_pmd
|
||||
#define PTE_ORDER 0
|
||||
|
||||
#define PTRS_PER_PGD (USER_PTRS_PER_PGD * 2)
|
||||
#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
|
||||
#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
|
||||
# define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t) / 2)
|
||||
#else
|
||||
# define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
|
||||
#endif
|
||||
|
||||
#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE)
|
||||
#define FIRST_USER_ADDRESS 0UL
|
||||
@@ -87,7 +119,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
|
||||
|
||||
extern void load_pgd(unsigned long pg_dir);
|
||||
|
||||
extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
|
||||
extern pte_t invalid_pte_table[PTRS_PER_PTE];
|
||||
|
||||
/*
|
||||
* Empty pgd/pmd entries point to the invalid_pte_table.
|
||||
@@ -97,7 +129,19 @@ static inline int pmd_none(pmd_t pmd)
|
||||
return pmd_val(pmd) == (unsigned long) invalid_pte_table;
|
||||
}
|
||||
|
||||
#define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK)
|
||||
static inline int pmd_bad(pmd_t pmd)
|
||||
{
|
||||
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
|
||||
/* pmd_huge(pmd) but inline */
|
||||
if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (unlikely(pmd_val(pmd) & ~PAGE_MASK))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pmd_present(pmd_t pmd)
|
||||
{
|
||||
@@ -146,6 +190,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
|
||||
#else
|
||||
#define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT))
|
||||
#define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot))
|
||||
#define pfn_pmd(pfn, prot) __pmd(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot))
|
||||
#endif
|
||||
#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */
|
||||
|
||||
@@ -159,6 +204,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
|
||||
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
|
||||
|
||||
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
|
||||
#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
|
||||
|
||||
/* to find an entry in a page-table-directory */
|
||||
#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
|
||||
@@ -175,7 +221,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
|
||||
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
|
||||
#define pte_unmap(pte) ((void)(pte))
|
||||
|
||||
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
#if defined(CONFIG_CPU_R3K_TLB)
|
||||
|
||||
/* Swap entries must have VALID bit cleared. */
|
||||
#define __swp_type(x) (((x).val >> 10) & 0x1f)
|
||||
@@ -220,6 +266,6 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
|
||||
|
||||
#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */
|
||||
|
||||
#endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) */
|
||||
#endif /* defined(CONFIG_CPU_R3K_TLB) */
|
||||
|
||||
#endif /* _ASM_PGTABLE_32_H */
|
||||
|
@@ -52,6 +52,9 @@ enum pgtable_bits {
|
||||
_PAGE_WRITE_SHIFT,
|
||||
_PAGE_ACCESSED_SHIFT,
|
||||
_PAGE_MODIFIED_SHIFT,
|
||||
#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
|
||||
_PAGE_SPECIAL_SHIFT,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -78,9 +81,12 @@ enum pgtable_bits {
|
||||
_PAGE_WRITE_SHIFT,
|
||||
_PAGE_ACCESSED_SHIFT,
|
||||
_PAGE_MODIFIED_SHIFT,
|
||||
#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
|
||||
_PAGE_SPECIAL_SHIFT,
|
||||
#endif
|
||||
};
|
||||
|
||||
#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
#elif defined(CONFIG_CPU_R3K_TLB)
|
||||
|
||||
/* Page table bits used for r3k systems */
|
||||
enum pgtable_bits {
|
||||
@@ -90,6 +96,9 @@ enum pgtable_bits {
|
||||
_PAGE_WRITE_SHIFT,
|
||||
_PAGE_ACCESSED_SHIFT,
|
||||
_PAGE_MODIFIED_SHIFT,
|
||||
#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
|
||||
_PAGE_SPECIAL_SHIFT,
|
||||
#endif
|
||||
|
||||
/* Used by TLB hardware (placed in EntryLo) */
|
||||
_PAGE_GLOBAL_SHIFT = 8,
|
||||
@@ -110,9 +119,12 @@ enum pgtable_bits {
|
||||
_PAGE_WRITE_SHIFT,
|
||||
_PAGE_ACCESSED_SHIFT,
|
||||
_PAGE_MODIFIED_SHIFT,
|
||||
#if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
|
||||
#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
|
||||
_PAGE_HUGE_SHIFT,
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
|
||||
_PAGE_SPECIAL_SHIFT,
|
||||
#endif
|
||||
|
||||
/* Used by TLB hardware (placed in EntryLo*) */
|
||||
#if defined(CONFIG_CPU_HAS_RIXI)
|
||||
@@ -132,9 +144,14 @@ enum pgtable_bits {
|
||||
#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
|
||||
#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
|
||||
#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
|
||||
#if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
|
||||
#if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
|
||||
# define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_HAS_PTE_SPECIAL)
|
||||
# define _PAGE_SPECIAL (1 << _PAGE_SPECIAL_SHIFT)
|
||||
#else
|
||||
# define _PAGE_SPECIAL 0
|
||||
#endif
|
||||
|
||||
/* Used by TLB hardware (placed in EntryLo*) */
|
||||
#if defined(CONFIG_XPA)
|
||||
@@ -146,7 +163,7 @@ enum pgtable_bits {
|
||||
#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
|
||||
#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT)
|
||||
#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT)
|
||||
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
#if defined(CONFIG_CPU_R3K_TLB)
|
||||
# define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT)
|
||||
# define _CACHE_MASK _CACHE_UNCACHED
|
||||
# define _PFN_SHIFT PAGE_SHIFT
|
||||
@@ -204,7 +221,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)
|
||||
/*
|
||||
* Cache attributes
|
||||
*/
|
||||
#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
|
||||
#if defined(CONFIG_CPU_R3K_TLB)
|
||||
|
||||
#define _CACHE_CACHABLE_NONCOHERENT 0
|
||||
#define _CACHE_UNCACHED_ACCELERATED _CACHE_UNCACHED
|
||||
@@ -216,13 +233,6 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)
|
||||
|
||||
#define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT)
|
||||
|
||||
#elif defined(CONFIG_CPU_LOONGSON3)
|
||||
|
||||
/* Using COHERENT flag for NONCOHERENT doesn't hurt. */
|
||||
|
||||
#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* LOONGSON */
|
||||
#define _CACHE_CACHABLE_COHERENT (3<<_CACHE_SHIFT) /* LOONGSON-3 */
|
||||
|
||||
#elif defined(CONFIG_MACH_INGENIC)
|
||||
|
||||
/* Ingenic uses the WA bit to achieve write-combine memory writes */
|
||||
|
@@ -199,7 +199,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
|
||||
static inline void set_pte(pte_t *ptep, pte_t pteval)
|
||||
{
|
||||
*ptep = pteval;
|
||||
#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
|
||||
#if !defined(CONFIG_CPU_R3K_TLB)
|
||||
if (pte_val(pteval) & _PAGE_GLOBAL) {
|
||||
pte_t *buddy = ptep_buddy(ptep);
|
||||
/*
|
||||
@@ -218,7 +218,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
|
||||
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
htw_stop();
|
||||
#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
|
||||
#if !defined(CONFIG_CPU_R3K_TLB)
|
||||
/* Preserve global status for the pair */
|
||||
if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
|
||||
set_pte_at(mm, addr, ptep, __pte(_PAGE_GLOBAL));
|
||||
@@ -277,6 +277,7 @@ extern pgd_t swapper_pg_dir[];
|
||||
static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; }
|
||||
static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; }
|
||||
static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; }
|
||||
static inline int pte_special(pte_t pte) { return pte.pte_low & _PAGE_SPECIAL; }
|
||||
|
||||
static inline pte_t pte_wrprotect(pte_t pte)
|
||||
{
|
||||
@@ -337,10 +338,17 @@ static inline pte_t pte_mkyoung(pte_t pte)
|
||||
}
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline pte_t pte_mkspecial(pte_t pte)
|
||||
{
|
||||
pte.pte_low |= _PAGE_SPECIAL;
|
||||
return pte;
|
||||
}
|
||||
#else
|
||||
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
|
||||
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; }
|
||||
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
|
||||
static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
|
||||
|
||||
static inline pte_t pte_wrprotect(pte_t pte)
|
||||
{
|
||||
@@ -384,6 +392,12 @@ static inline pte_t pte_mkyoung(pte_t pte)
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline pte_t pte_mkspecial(pte_t pte)
|
||||
{
|
||||
pte_val(pte) |= _PAGE_SPECIAL;
|
||||
return pte;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
|
||||
static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_HUGE; }
|
||||
|
||||
@@ -394,8 +408,6 @@ static inline pte_t pte_mkhuge(pte_t pte)
|
||||
}
|
||||
#endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */
|
||||
#endif
|
||||
static inline int pte_special(pte_t pte) { return 0; }
|
||||
static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
|
||||
|
||||
/*
|
||||
* Macro to make mark a page protection value as "uncacheable". Note
|
||||
|
@@ -54,7 +54,7 @@ static inline void mips_syscall_update_nr(struct task_struct *task,
|
||||
task_thread_info(task)->syscall = regs->regs[2];
|
||||
}
|
||||
|
||||
static inline unsigned long mips_get_syscall_arg(unsigned long *arg,
|
||||
static inline void mips_get_syscall_arg(unsigned long *arg,
|
||||
struct task_struct *task, struct pt_regs *regs, unsigned int n)
|
||||
{
|
||||
unsigned long usp __maybe_unused = regs->regs[29];
|
||||
@@ -63,23 +63,24 @@ static inline unsigned long mips_get_syscall_arg(unsigned long *arg,
|
||||
case 0: case 1: case 2: case 3:
|
||||
*arg = regs->regs[4 + n];
|
||||
|
||||
return 0;
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
case 4: case 5: case 6: case 7:
|
||||
return get_user(*arg, (int *)usp + n);
|
||||
get_user(*arg, (int *)usp + n);
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
case 4: case 5: case 6: case 7:
|
||||
#ifdef CONFIG_MIPS32_O32
|
||||
if (test_tsk_thread_flag(task, TIF_32BIT_REGS))
|
||||
return get_user(*arg, (int *)usp + n);
|
||||
get_user(*arg, (int *)usp + n);
|
||||
else
|
||||
#endif
|
||||
*arg = regs->regs[4 + n];
|
||||
|
||||
return 0;
|
||||
return;
|
||||
#endif
|
||||
|
||||
default:
|
||||
@@ -126,21 +127,13 @@ static inline void syscall_get_arguments(struct task_struct *task,
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int n = 6;
|
||||
int ret;
|
||||
|
||||
/* O32 ABI syscall() */
|
||||
if (mips_syscall_is_indirect(task, regs))
|
||||
i++;
|
||||
|
||||
while (n--)
|
||||
ret |= mips_get_syscall_arg(args++, task, regs, i++);
|
||||
|
||||
/*
|
||||
* No way to communicate an error because this is a void function.
|
||||
*/
|
||||
#if 0
|
||||
return ret;
|
||||
#endif
|
||||
mips_get_syscall_arg(args++, task, regs, i++);
|
||||
}
|
||||
|
||||
extern const unsigned long sys_call_table[];
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#define __ASM_VDSO_H
|
||||
|
||||
#include <linux/mm_types.h>
|
||||
#include <vdso/datapage.h>
|
||||
|
||||
#include <asm/barrier.h>
|
||||
|
||||
@@ -49,84 +50,9 @@ extern struct mips_vdso_image vdso_image_o32;
|
||||
extern struct mips_vdso_image vdso_image_n32;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* union mips_vdso_data - Data provided by the kernel for the VDSO.
|
||||
* @xtime_sec: Current real time (seconds part).
|
||||
* @xtime_nsec: Current real time (nanoseconds part, shifted).
|
||||
* @wall_to_mono_sec: Wall-to-monotonic offset (seconds part).
|
||||
* @wall_to_mono_nsec: Wall-to-monotonic offset (nanoseconds part).
|
||||
* @seq_count: Counter to synchronise updates (odd = updating).
|
||||
* @cs_shift: Clocksource shift value.
|
||||
* @clock_mode: Clocksource to use for time functions.
|
||||
* @cs_mult: Clocksource multiplier value.
|
||||
* @cs_cycle_last: Clock cycle value at last update.
|
||||
* @cs_mask: Clocksource mask value.
|
||||
* @tz_minuteswest: Minutes west of Greenwich (from timezone).
|
||||
* @tz_dsttime: Type of DST correction (from timezone).
|
||||
*
|
||||
* This structure contains data needed by functions within the VDSO. It is
|
||||
* populated by the kernel and mapped read-only into user memory. The time
|
||||
* fields are mirrors of internal data from the timekeeping infrastructure.
|
||||
*
|
||||
* Note: Care should be taken when modifying as the layout must remain the same
|
||||
* for both 64- and 32-bit (for 32-bit userland on 64-bit kernel).
|
||||
*/
|
||||
union mips_vdso_data {
|
||||
struct {
|
||||
u64 xtime_sec;
|
||||
u64 xtime_nsec;
|
||||
u64 wall_to_mono_sec;
|
||||
u64 wall_to_mono_nsec;
|
||||
u32 seq_count;
|
||||
u32 cs_shift;
|
||||
u8 clock_mode;
|
||||
u32 cs_mult;
|
||||
u64 cs_cycle_last;
|
||||
u64 cs_mask;
|
||||
s32 tz_minuteswest;
|
||||
s32 tz_dsttime;
|
||||
};
|
||||
|
||||
struct vdso_data data[CS_BASES];
|
||||
u8 page[PAGE_SIZE];
|
||||
};
|
||||
|
||||
static inline u32 vdso_data_read_begin(const union mips_vdso_data *data)
|
||||
{
|
||||
u32 seq;
|
||||
|
||||
while (true) {
|
||||
seq = READ_ONCE(data->seq_count);
|
||||
if (likely(!(seq & 1))) {
|
||||
/* Paired with smp_wmb() in vdso_data_write_*(). */
|
||||
smp_rmb();
|
||||
return seq;
|
||||
}
|
||||
|
||||
cpu_relax();
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool vdso_data_read_retry(const union mips_vdso_data *data,
|
||||
u32 start_seq)
|
||||
{
|
||||
/* Paired with smp_wmb() in vdso_data_write_*(). */
|
||||
smp_rmb();
|
||||
return unlikely(data->seq_count != start_seq);
|
||||
}
|
||||
|
||||
static inline void vdso_data_write_begin(union mips_vdso_data *data)
|
||||
{
|
||||
++data->seq_count;
|
||||
|
||||
/* Ensure sequence update is written before other data page values. */
|
||||
smp_wmb();
|
||||
}
|
||||
|
||||
static inline void vdso_data_write_end(union mips_vdso_data *data)
|
||||
{
|
||||
/* Ensure data values are written before updating sequence again. */
|
||||
smp_wmb();
|
||||
++data->seq_count;
|
||||
}
|
||||
|
||||
#endif /* __ASM_VDSO_H */
|
||||
|
222
arch/mips/include/asm/vdso/gettimeofday.h
Normal file
222
arch/mips/include/asm/vdso/gettimeofday.h
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (C) 2018 ARM Limited
|
||||
* Copyright (C) 2015 Imagination Technologies
|
||||
* Author: Alex Smith <alex.smith@imgtec.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#ifndef __ASM_VDSO_GETTIMEOFDAY_H
|
||||
#define __ASM_VDSO_GETTIMEOFDAY_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <asm/vdso/vdso.h>
|
||||
#include <asm/clocksource.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
#define VDSO_HAS_CLOCK_GETRES 1
|
||||
|
||||
#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
|
||||
|
||||
static __always_inline long gettimeofday_fallback(
|
||||
struct __kernel_old_timeval *_tv,
|
||||
struct timezone *_tz)
|
||||
{
|
||||
register struct timezone *tz asm("a1") = _tz;
|
||||
register struct __kernel_old_timeval *tv asm("a0") = _tv;
|
||||
register long ret asm("v0");
|
||||
register long nr asm("v0") = __NR_gettimeofday;
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (tv), "r" (tz), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static __always_inline long gettimeofday_fallback(
|
||||
struct __kernel_old_timeval *_tv,
|
||||
struct timezone *_tz)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __always_inline long clock_gettime_fallback(
|
||||
clockid_t _clkid,
|
||||
struct __kernel_timespec *_ts)
|
||||
{
|
||||
register struct __kernel_timespec *ts asm("a1") = _ts;
|
||||
register clockid_t clkid asm("a0") = _clkid;
|
||||
register long ret asm("v0");
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
register long nr asm("v0") = __NR_clock_gettime;
|
||||
#else
|
||||
register long nr asm("v0") = __NR_clock_gettime64;
|
||||
#endif
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (clkid), "r" (ts), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
static __always_inline int clock_getres_fallback(
|
||||
clockid_t _clkid,
|
||||
struct __kernel_timespec *_ts)
|
||||
{
|
||||
register struct __kernel_timespec *ts asm("a1") = _ts;
|
||||
register clockid_t clkid asm("a0") = _clkid;
|
||||
register long ret asm("v0");
|
||||
#if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
register long nr asm("v0") = __NR_clock_getres;
|
||||
#else
|
||||
register long nr asm("v0") = __NR_clock_getres_time64;
|
||||
#endif
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (clkid), "r" (ts), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
#if _MIPS_SIM != _MIPS_SIM_ABI64
|
||||
|
||||
#define VDSO_HAS_32BIT_FALLBACK 1
|
||||
|
||||
static __always_inline long clock_gettime32_fallback(
|
||||
clockid_t _clkid,
|
||||
struct old_timespec32 *_ts)
|
||||
{
|
||||
register struct old_timespec32 *ts asm("a1") = _ts;
|
||||
register clockid_t clkid asm("a0") = _clkid;
|
||||
register long ret asm("v0");
|
||||
register long nr asm("v0") = __NR_clock_gettime;
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (clkid), "r" (ts), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
static __always_inline int clock_getres32_fallback(
|
||||
clockid_t _clkid,
|
||||
struct old_timespec32 *_ts)
|
||||
{
|
||||
register struct old_timespec32 *ts asm("a1") = _ts;
|
||||
register clockid_t clkid asm("a0") = _clkid;
|
||||
register long ret asm("v0");
|
||||
register long nr asm("v0") = __NR_clock_getres;
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (clkid), "r" (ts), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CSRC_R4K
|
||||
|
||||
static __always_inline u64 read_r4k_count(void)
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" .set push\n"
|
||||
" .set mips32r2\n"
|
||||
" rdhwr %0, $2\n"
|
||||
" .set pop\n"
|
||||
: "=r" (count));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
|
||||
static __always_inline u64 read_gic_count(const struct vdso_data *data)
|
||||
{
|
||||
void __iomem *gic = get_gic(data);
|
||||
u32 hi, hi2, lo;
|
||||
|
||||
do {
|
||||
hi = __raw_readl(gic + sizeof(lo));
|
||||
lo = __raw_readl(gic);
|
||||
hi2 = __raw_readl(gic + sizeof(lo));
|
||||
} while (hi2 != hi);
|
||||
|
||||
return (((u64)hi) << 32) + lo;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
|
||||
{
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
const struct vdso_data *data = get_vdso_data();
|
||||
#endif
|
||||
u64 cycle_now;
|
||||
|
||||
switch (clock_mode) {
|
||||
#ifdef CONFIG_CSRC_R4K
|
||||
case VDSO_CLOCK_R4K:
|
||||
cycle_now = read_r4k_count();
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
case VDSO_CLOCK_GIC:
|
||||
cycle_now = read_gic_count(data);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cycle_now = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return cycle_now;
|
||||
}
|
||||
|
||||
static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
|
||||
{
|
||||
return get_vdso_data();
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
|
75
arch/mips/include/asm/vdso/vdso.h
Normal file
75
arch/mips/include/asm/vdso/vdso.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2015 Imagination Technologies
|
||||
* Author: Alex Smith <alex.smith@imgtec.com>
|
||||
*/
|
||||
|
||||
#include <asm/sgidefs.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
static inline unsigned long get_vdso_base(void)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
/*
|
||||
* We can't use cpu_has_mips_r6 since it needs the cpu_data[]
|
||||
* kernel symbol.
|
||||
*/
|
||||
#ifdef CONFIG_CPU_MIPSR6
|
||||
/*
|
||||
* lapc <symbol> is an alias to addiupc reg, <symbol> - .
|
||||
*
|
||||
* We can't use addiupc because there is no label-label
|
||||
* support for the addiupc reloc
|
||||
*/
|
||||
__asm__("lapc %0, _start \n"
|
||||
: "=r" (addr) : :);
|
||||
#else
|
||||
/*
|
||||
* Get the base load address of the VDSO. We have to avoid generating
|
||||
* relocations and references to the GOT because ld.so does not peform
|
||||
* relocations on the VDSO. We use the current offset from the VDSO base
|
||||
* and perform a PC-relative branch which gives the absolute address in
|
||||
* ra, and take the difference. The assembler chokes on
|
||||
* "li %0, _start - .", so embed the offset as a word and branch over
|
||||
* it.
|
||||
*
|
||||
*/
|
||||
|
||||
__asm__(
|
||||
" .set push \n"
|
||||
" .set noreorder \n"
|
||||
" bal 1f \n"
|
||||
" nop \n"
|
||||
" .word _start - . \n"
|
||||
"1: lw %0, 0($31) \n"
|
||||
" " STR(PTR_ADDU) " %0, $31, %0 \n"
|
||||
" .set pop \n"
|
||||
: "=r" (addr)
|
||||
:
|
||||
: "$31");
|
||||
#endif /* CONFIG_CPU_MIPSR6 */
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static inline const struct vdso_data *get_vdso_data(void)
|
||||
{
|
||||
return (const struct vdso_data *)(get_vdso_base() - PAGE_SIZE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
|
||||
static inline void __iomem *get_gic(const struct vdso_data *data)
|
||||
{
|
||||
return (void __iomem *)data - PAGE_SIZE;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CLKSRC_MIPS_GIC */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
43
arch/mips/include/asm/vdso/vsyscall.h
Normal file
43
arch/mips/include/asm/vdso/vsyscall.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_VDSO_VSYSCALL_H
|
||||
#define __ASM_VDSO_VSYSCALL_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/timekeeper_internal.h>
|
||||
#include <vdso/datapage.h>
|
||||
|
||||
extern struct vdso_data *vdso_data;
|
||||
|
||||
/*
|
||||
* Update the vDSO data page to keep in sync with kernel timekeeping.
|
||||
*/
|
||||
static __always_inline
|
||||
struct vdso_data *__mips_get_k_vdso_data(void)
|
||||
{
|
||||
return vdso_data;
|
||||
}
|
||||
#define __arch_get_k_vdso_data __mips_get_k_vdso_data
|
||||
|
||||
static __always_inline
|
||||
int __mips_get_clock_mode(struct timekeeper *tk)
|
||||
{
|
||||
u32 clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode;
|
||||
|
||||
return clock_mode;
|
||||
}
|
||||
#define __arch_get_clock_mode __mips_get_clock_mode
|
||||
|
||||
static __always_inline
|
||||
int __mips_use_vsyscall(struct vdso_data *vdata)
|
||||
{
|
||||
return (vdata[CS_HRES_COARSE].clock_mode != VDSO_CLOCK_NONE);
|
||||
}
|
||||
#define __arch_use_vsyscall __mips_use_vsyscall
|
||||
|
||||
/* The asm-generic header needs to be included after the definitions above */
|
||||
#include <asm-generic/vdso/vsyscall.h>
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_VDSO_VSYSCALL_H */
|
@@ -128,19 +128,6 @@
|
||||
#error Check setting of R4600_V2_HIT_CACHEOP_WAR for your platform
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When an interrupt happens on a CP0 register read instruction, CPU may
|
||||
* lock up or read corrupted values of CP0 registers after it enters
|
||||
* the exception handler.
|
||||
*
|
||||
* This workaround makes sure that we read a "safe" CP0 register as the
|
||||
* first thing in the exception handler, which breaks one of the
|
||||
* pre-conditions for this problem.
|
||||
*/
|
||||
#ifndef R5432_CP0_INTERRUPT_WAR
|
||||
#error Check setting of R5432_CP0_INTERRUPT_WAR for your platform
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Workaround for the Sibyte M3 errata the text of which can be found at
|
||||
*
|
||||
|
Reference in New Issue
Block a user