diff options
Diffstat (limited to 'arch/mips/include/asm')
26 files changed, 458 insertions, 188 deletions
diff --git a/arch/mips/include/asm/abi.h b/arch/mips/include/asm/abi.h index 37f84078e..940760844 100644 --- a/arch/mips/include/asm/abi.h +++ b/arch/mips/include/asm/abi.h @@ -11,19 +11,20 @@ #include <asm/signal.h> #include <asm/siginfo.h> +#include <asm/vdso.h> struct mips_abi { int (* const setup_frame)(void *sig_return, struct ksignal *ksig, struct pt_regs *regs, sigset_t *set); - const unsigned long signal_return_offset; int (* const setup_rt_frame)(void *sig_return, struct ksignal *ksig, struct pt_regs *regs, sigset_t *set); - const unsigned long rt_signal_return_offset; const unsigned long restart; unsigned off_sc_fpregs; unsigned off_sc_fpc_csr; unsigned off_sc_used_math; + + struct mips_vdso_image *vdso; }; #endif /* _ASM_ABI_H */ diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 4c42fd9af..835b402e4 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -30,7 +30,7 @@ * * Atomically reads the value of @v. */ -#define atomic_read(v) ACCESS_ONCE((v)->counter) +#define atomic_read(v) READ_ONCE((v)->counter) /* * atomic_set - set atomic variable @@ -39,7 +39,7 @@ * * Atomically sets the value of @v to @i. */ -#define atomic_set(v, i) ((v)->counter = (i)) +#define atomic_set(v, i) WRITE_ONCE((v)->counter, (i)) #define ATOMIC_OP(op, c_op, asm_op) \ static __inline__ void atomic_##op(int i, atomic_t * v) \ @@ -315,14 +315,14 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) * @v: pointer of type atomic64_t * */ -#define atomic64_read(v) ACCESS_ONCE((v)->counter) +#define atomic64_read(v) READ_ONCE((v)->counter) /* * atomic64_set - set atomic variable * @v: pointer of type atomic64_t * @i: required value */ -#define atomic64_set(v, i) ((v)->counter = (i)) +#define atomic64_set(v, i) WRITE_ONCE((v)->counter, (i)) #define ATOMIC64_OP(op, c_op, asm_op) \ static __inline__ void atomic64_##op(long i, atomic64_t * v) \ @@ -507,7 +507,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as it was not @u. - * Returns the old value of @v. + * Returns true iff @v was not @u. */ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) { diff --git a/arch/mips/include/asm/bcache.h b/arch/mips/include/asm/bcache.h index 8c34484ce..a00857b13 100644 --- a/arch/mips/include/asm/bcache.h +++ b/arch/mips/include/asm/bcache.h @@ -9,6 +9,7 @@ #ifndef _ASM_BCACHE_H #define _ASM_BCACHE_H +#include <linux/types.h> /* Some R4000 / R4400 / R4600 / R5000 machines may have a non-dma-coherent, chipset implemented caches. On machines with other CPUs the CPU does the @@ -18,6 +19,9 @@ struct bcache_ops { void (*bc_disable)(void); void (*bc_wback_inv)(unsigned long page, unsigned long size); void (*bc_inv)(unsigned long page, unsigned long size); + void (*bc_prefetch_enable)(void); + void (*bc_prefetch_disable)(void); + bool (*bc_prefetch_is_enabled)(void); }; extern void indy_sc_init(void); @@ -46,6 +50,26 @@ static inline void bc_inv(unsigned long page, unsigned long size) bcops->bc_inv(page, size); } +static inline void bc_prefetch_enable(void) +{ + if (bcops->bc_prefetch_enable) + bcops->bc_prefetch_enable(); +} + +static inline void bc_prefetch_disable(void) +{ + if (bcops->bc_prefetch_disable) + bcops->bc_prefetch_disable(); +} + +static inline bool bc_prefetch_is_enabled(void) +{ + if (bcops->bc_prefetch_is_enabled) + return bcops->bc_prefetch_is_enabled(); + + return false; +} + #else /* !defined(CONFIG_BOARD_SCACHE) */ /* Not R4000 / R4400 / R4600 / R5000. */ @@ -54,6 +78,9 @@ static inline void bc_inv(unsigned long page, unsigned long size) #define bc_disable() do { } while (0) #define bc_wback_inv(page, size) do { } while (0) #define bc_inv(page, size) do { } while (0) +#define bc_prefetch_enable() do { } while (0) +#define bc_prefetch_disable() do { } while (0) +#define bc_prefetch_is_enabled() 0 #endif /* !defined(CONFIG_BOARD_SCACHE) */ diff --git a/arch/mips/include/asm/clocksource.h b/arch/mips/include/asm/clocksource.h new file mode 100644 index 000000000..3deb1d0c1 --- /dev/null +++ b/arch/mips/include/asm/clocksource.h @@ -0,0 +1,29 @@ +/* + * 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_CLOCKSOURCE_H +#define __ASM_CLOCKSOURCE_H + +#include <linux/types.h> + +/* VDSO clocksources. */ +#define VDSO_CLOCK_NONE 0 /* No suitable clocksource. */ +#define VDSO_CLOCK_R4K 1 /* Use the coprocessor 0 count. */ +#define VDSO_CLOCK_GIC 2 /* Use the GIC. */ + +/** + * struct arch_clocksource_data - Architecture-specific clocksource information. + * @vdso_clock_mode: Method the VDSO should use to access the clocksource. + */ +struct arch_clocksource_data { + u8 vdso_clock_mode; +}; + +#endif /* __ASM_CLOCKSOURCE_H */ diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index c4bd54a7f..a9580097c 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h @@ -130,6 +130,8 @@ typedef union compat_sigval { compat_uptr_t sival_ptr; } compat_sigval_t; +/* Can't use the generic version because si_code and si_errno are swapped */ + #define SI_PAD_SIZE32 (128/sizeof(int) - 3) typedef struct compat_siginfo { @@ -138,57 +140,61 @@ typedef struct compat_siginfo { int si_errno; union { - int _pad[SI_PAD_SIZE32]; + int _pad[128 / sizeof(int) - 3]; /* kill() */ struct { compat_pid_t _pid; /* sender's pid */ - __compat_uid_t _uid; /* sender's uid */ + __compat_uid32_t _uid; /* sender's uid */ } _kill; + /* POSIX.1b timers */ + struct { + compat_timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + compat_sigval_t _sigval; /* same as below */ + } _timer; + + /* POSIX.1b signals */ + struct { + compat_pid_t _pid; /* sender's pid */ + __compat_uid32_t _uid; /* sender's uid */ + compat_sigval_t _sigval; + } _rt; + /* SIGCHLD */ struct { compat_pid_t _pid; /* which child */ - __compat_uid_t _uid; /* sender's uid */ + __compat_uid32_t _uid; /* sender's uid */ int _status; /* exit code */ compat_clock_t _utime; compat_clock_t _stime; } _sigchld; - /* IRIX SIGCHLD */ - struct { - compat_pid_t _pid; /* which child */ - compat_clock_t _utime; - int _status; /* exit code */ - compat_clock_t _stime; - } _irix_sigchld; - /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ struct { - s32 _addr; /* faulting insn/memory ref. */ + compat_uptr_t _addr; /* faulting insn/memory ref. */ +#ifdef __ARCH_SI_TRAPNO + int _trapno; /* TRAP # which caused the signal */ +#endif + short _addr_lsb; /* LSB of the reported address */ + struct { + compat_uptr_t _lower; + compat_uptr_t _upper; + } _addr_bnd; } _sigfault; - /* SIGPOLL, SIGXFSZ (To do ...) */ + /* SIGPOLL */ struct { - int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */ int _fd; } _sigpoll; - /* POSIX.1b timers */ - struct { - timer_t _tid; /* timer id */ - int _overrun; /* overrun count */ - compat_sigval_t _sigval;/* same as below */ - int _sys_private; /* not to be passed to user */ - } _timer; - - /* POSIX.1b signals */ struct { - compat_pid_t _pid; /* sender's pid */ - __compat_uid_t _uid; /* sender's uid */ - compat_sigval_t _sigval; - } _rt; - + compat_uptr_t _call_addr; /* calling insn */ + int _syscall; /* triggering system call number */ + compat_uint_t _arch; /* AUDIT_ARCH_* of syscall */ + } _sigsys; } _sifields; } compat_siginfo_t; diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index fe67f12ac..d1e04c943 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -131,11 +131,7 @@ #endif #ifndef cpu_has_rixi -# ifdef CONFIG_64BIT -# define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI) -# else /* CONFIG_32BIT */ -# define cpu_has_rixi ((cpu_data[0].options & MIPS_CPU_RIXI) && !cpu_has_64bits) -# endif +#define cpu_has_rixi (cpu_data[0].options & MIPS_CPU_RIXI) #endif #ifndef cpu_has_mmips diff --git a/arch/mips/include/asm/debug.h b/arch/mips/include/asm/debug.h new file mode 100644 index 000000000..254f00deb --- /dev/null +++ b/arch/mips/include/asm/debug.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2015 Imagination Technologies + * + * 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 __MIPS_ASM_DEBUG_H__ +#define __MIPS_ASM_DEBUG_H__ + +#include <linux/dcache.h> + +/* + * mips_debugfs_dir corresponds to the "mips" directory at the top level + * of the DebugFS hierarchy. MIPS-specific DebugFS entires should be + * placed beneath this directory. + */ +extern struct dentry *mips_debugfs_dir; + +#endif /* __MIPS_ASM_DEBUG_H__ */ diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index 53b26933b..b01a6ff46 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -8,6 +8,7 @@ #ifndef _ASM_ELF_H #define _ASM_ELF_H +#include <linux/auxvec.h> #include <linux/fs.h> #include <uapi/linux/elf.h> @@ -419,6 +420,12 @@ extern const char *__elf_platform; #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) #endif +#define ARCH_DLINFO \ +do { \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, \ + (unsigned long)current->mm->context.vdso); \ +} while (0) + #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 struct linux_binprm; extern int arch_setup_additional_pages(struct linux_binprm *bprm, diff --git a/arch/mips/include/asm/fw/fw.h b/arch/mips/include/asm/fw/fw.h index f3e6978aa..d0ef8b489 100644 --- a/arch/mips/include/asm/fw/fw.h +++ b/arch/mips/include/asm/fw/fw.h @@ -10,21 +10,6 @@ #include <asm/bootinfo.h> /* For cleaner code... */ -enum fw_memtypes { - fw_dontuse, - fw_code, - fw_free, -}; - -typedef struct { - unsigned long base; /* Within KSEG0 */ - unsigned int size; /* bytes */ - enum fw_memtypes type; /* fw_memtypes */ -} fw_memblock_t; - -/* Maximum number of memory block descriptors. */ -#define FW_MAX_MEMBLOCKS 32 - extern int fw_argc; extern int *_fw_argv; extern int *_fw_envp; @@ -38,7 +23,6 @@ extern int *_fw_envp; extern void fw_init_cmdline(void); extern char *fw_getcmdline(void); -extern fw_memblock_t *fw_getmdesc(int); extern void fw_meminit(void); extern char *fw_getenv(char *name); extern unsigned long fw_getenvl(char *name); diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index 572e63ec2..01880b34a 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h @@ -49,7 +49,6 @@ extern void kunmap(struct page *page); extern void *kmap_atomic(struct page *page); extern void __kunmap_atomic(void *kvaddr); extern void *kmap_atomic_pfn(unsigned long pfn); -extern struct page *kmap_atomic_to_page(void *ptr); #define flush_cache_kmaps() flush_cache_all() diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 5a1a882e0..6ded8d347 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -847,5 +847,7 @@ static inline void kvm_arch_flush_shadow_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) {} static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {} static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {} +static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {} +static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {} #endif /* __MIPS_KVM_HOST_H__ */ diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h index 1461c10c1..71e4096a2 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h @@ -48,11 +48,6 @@ extern enum bcm47xx_bus_type bcm47xx_bus_type; void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix, bool fallback); -#ifdef CONFIG_BCM47XX_SSB -void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo, - const char *prefix); -#endif - void bcm47xx_set_system_type(u16 chip_id); #endif /* __ASM_BCM47XX_H */ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h index 25737655d..dd2995488 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h @@ -7,48 +7,4 @@ int __init bcm63xx_spi_register(void); -struct bcm63xx_spi_pdata { - unsigned int fifo_size; - unsigned int msg_type_shift; - unsigned int msg_ctl_width; - int bus_num; - int num_chipselect; -}; - -enum bcm63xx_regs_spi { - SPI_CMD, - SPI_INT_STATUS, - SPI_INT_MASK_ST, - SPI_INT_MASK, - SPI_ST, - SPI_CLK_CFG, - SPI_FILL_BYTE, - SPI_MSG_TAIL, - SPI_RX_TAIL, - SPI_MSG_CTL, - SPI_MSG_DATA, - SPI_RX_DATA, -}; - -#define __GEN_SPI_REGS_TABLE(__cpu) \ - [SPI_CMD] = SPI_## __cpu ##_CMD, \ - [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \ - [SPI_INT_MASK_ST] = SPI_## __cpu ##_INT_MASK_ST, \ - [SPI_INT_MASK] = SPI_## __cpu ##_INT_MASK, \ - [SPI_ST] = SPI_## __cpu ##_ST, \ - [SPI_CLK_CFG] = SPI_## __cpu ##_CLK_CFG, \ - [SPI_FILL_BYTE] = SPI_## __cpu ##_FILL_BYTE, \ - [SPI_MSG_TAIL] = SPI_## __cpu ##_MSG_TAIL, \ - [SPI_RX_TAIL] = SPI_## __cpu ##_RX_TAIL, \ - [SPI_MSG_CTL] = SPI_## __cpu ##_MSG_CTL, \ - [SPI_MSG_DATA] = SPI_## __cpu ##_MSG_DATA, \ - [SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA, - -static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg) -{ - extern const unsigned long *bcm63xx_regs_spi; - - return bcm63xx_regs_spi[reg]; -} - #endif /* BCM63XX_DEV_SPI_H */ diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h index 133336b49..dd6005b75 100644 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h @@ -35,6 +35,17 @@ #define SOC_ID_VRX268_2 0x00C /* v1.2 */ #define SOC_ID_GRX288_2 0x00D /* v1.2 */ #define SOC_ID_GRX282_2 0x00E /* v1.2 */ +#define SOC_ID_VRX220 0x000 + +#define SOC_ID_ARX362 0x004 +#define SOC_ID_ARX368 0x005 +#define SOC_ID_ARX382 0x007 +#define SOC_ID_ARX388 0x008 +#define SOC_ID_URX388 0x009 +#define SOC_ID_GRX383 0x010 +#define SOC_ID_GRX369 0x011 +#define SOC_ID_GRX387 0x00F +#define SOC_ID_GRX389 0x012 /* SoC Types */ #define SOC_TYPE_DANUBE 0x01 @@ -43,6 +54,9 @@ #define SOC_TYPE_VR9 0x04 /* v1.1 */ #define SOC_TYPE_VR9_2 0x05 /* v1.2 */ #define SOC_TYPE_AMAZON_SE 0x06 +#define SOC_TYPE_AR10 0x07 +#define SOC_TYPE_GRX390 0x08 +#define SOC_TYPE_VRX220 0x09 /* BOOT_SEL - find what boot media we have */ #define BS_EXT_ROM 0x0 diff --git a/arch/mips/include/asm/mach-malta/malta-dtshim.h b/arch/mips/include/asm/mach-malta/malta-dtshim.h new file mode 100644 index 000000000..cfd777663 --- /dev/null +++ b/arch/mips/include/asm/mach-malta/malta-dtshim.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2015 Imagination Technologies + * Author: Paul Burton <paul.burton@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 __MIPS_MALTA_DTSHIM_H__ +#define __MIPS_MALTA_DTSHIM_H__ + +#include <linux/init.h> + +#ifdef CONFIG_MIPS_MALTA + +extern void __init *malta_dt_shim(void *fdt); + +#else /* !CONFIG_MIPS_MALTA */ + +static inline void *malta_dt_shim(void *fdt) +{ + return fdt; +} + +#endif /* !CONFIG_MIPS_MALTA */ + +#endif /* __MIPS_MALTA_DTSHIM_H__ */ diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h index 1976fb815..455d406e8 100644 --- a/arch/mips/include/asm/mach-ralink/mt7620.h +++ b/arch/mips/include/asm/mach-ralink/mt7620.h @@ -13,17 +13,11 @@ #ifndef _MT7620_REGS_H_ #define _MT7620_REGS_H_ -enum mt762x_soc_type { - MT762X_SOC_UNKNOWN = 0, - MT762X_SOC_MT7620A, - MT762X_SOC_MT7620N, - MT762X_SOC_MT7628AN, -}; - #define MT7620_SYSC_BASE 0x10000000 #define SYSC_REG_CHIP_NAME0 0x00 #define SYSC_REG_CHIP_NAME1 0x04 +#define SYSC_REG_EFUSE_CFG 0x08 #define SYSC_REG_CHIP_REV 0x0c #define SYSC_REG_SYSTEM_CONFIG0 0x10 #define SYSC_REG_SYSTEM_CONFIG1 0x14 diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h index bd9301449..4c9fba68c 100644 --- a/arch/mips/include/asm/mach-ralink/ralink_regs.h +++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h @@ -13,6 +13,23 @@ #ifndef _RALINK_REGS_H_ #define _RALINK_REGS_H_ +enum ralink_soc_type { + RALINK_UNKNOWN = 0, + RT2880_SOC, + RT3883_SOC, + RT305X_SOC_RT3050, + RT305X_SOC_RT3052, + RT305X_SOC_RT3350, + RT305X_SOC_RT3352, + RT305X_SOC_RT5350, + MT762X_SOC_MT7620A, + MT762X_SOC_MT7620N, + MT762X_SOC_MT7621AT, + MT762X_SOC_MT7628AN, + MT762X_SOC_MT7688, +}; +extern enum ralink_soc_type ralink_soc; + extern __iomem void *rt_sysc_membase; extern __iomem void *rt_memc_membase; diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h index 96f731bac..2eea79331 100644 --- a/arch/mips/include/asm/mach-ralink/rt305x.h +++ b/arch/mips/include/asm/mach-ralink/rt305x.h @@ -13,25 +13,16 @@ #ifndef _RT305X_REGS_H_ #define _RT305X_REGS_H_ -enum rt305x_soc_type { - RT305X_SOC_UNKNOWN = 0, - RT305X_SOC_RT3050, - RT305X_SOC_RT3052, - RT305X_SOC_RT3350, - RT305X_SOC_RT3352, - RT305X_SOC_RT5350, -}; - -extern enum rt305x_soc_type rt305x_soc; +extern enum ralink_soc_type ralink_soc; static inline int soc_is_rt3050(void) { - return rt305x_soc == RT305X_SOC_RT3050; + return ralink_soc == RT305X_SOC_RT3050; } static inline int soc_is_rt3052(void) { - return rt305x_soc == RT305X_SOC_RT3052; + return ralink_soc == RT305X_SOC_RT3052; } static inline int soc_is_rt305x(void) @@ -41,17 +32,17 @@ static inline int soc_is_rt305x(void) static inline int soc_is_rt3350(void) { - return rt305x_soc == RT305X_SOC_RT3350; + return ralink_soc == RT305X_SOC_RT3350; } static inline int soc_is_rt3352(void) { - return rt305x_soc == RT305X_SOC_RT3352; + return ralink_soc == RT305X_SOC_RT3352; } static inline int soc_is_rt5350(void) { - return rt305x_soc == RT305X_SOC_RT5350; + return ralink_soc == RT305X_SOC_RT5350; } #define RT305X_SYSC_BASE 0x10000000 diff --git a/arch/mips/include/asm/mach-xilfpga/irq.h b/arch/mips/include/asm/mach-xilfpga/irq.h new file mode 100644 index 000000000..0132a5b91 --- /dev/null +++ b/arch/mips/include/asm/mach-xilfpga/irq.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2015 Imagination Technologies + * Author: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@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 __MIPS_ASM_MACH_XILFPGA_IRQ_H__ +#define __MIPS_ASM_MACH_XILFPGA_IRQ_H__ + +#define NR_IRQS 32 + +#include_next <irq.h> + +#endif /* __MIPS_ASM_MACH_XILFPGA_IRQ_H__ */ diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 1f1927ab4..6516e9da5 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -11,6 +11,7 @@ #ifndef __MIPS_ASM_MIPS_CM_H__ #define __MIPS_ASM_MIPS_CM_H__ +#include <linux/bitops.h> #include <linux/errno.h> #include <linux/io.h> #include <linux/types.h> @@ -36,12 +37,12 @@ extern phys_addr_t __mips_cm_phys_base(void); /* * mips_cm_is64 - determine CM register width * - * The CM register width is processor and CM specific. A 64-bit processor - * usually has a 64-bit CM and a 32-bit one has a 32-bit CM but a 64-bit - * processor could come with a 32-bit CM. Moreover, accesses on 64-bit CMs - * can be done either using regular 64-bit load/store instructions, or 32-bit - * load/store instruction on 32-bit register pairs. We opt for using 64-bit - * accesses on 64-bit CMs and kernels and 32-bit in any other case. + * The CM register width is determined by the version of the CM, with CM3 + * introducing 64 bit GCRs and all prior CM versions having 32 bit GCRs. + * However we may run a kernel built for MIPS32 on a system with 64 bit GCRs, + * or vice-versa. This variable indicates the width of the memory accesses + * that the kernel will perform to GCRs, which may differ from the actual + * width of the GCRs. * * It's set to 0 for 32-bit accesses and 1 for 64-bit accesses. */ @@ -125,7 +126,17 @@ static inline u32 read32_gcr_##name(void) \ \ static inline u64 read64_gcr_##name(void) \ { \ - return __raw_readq(addr_gcr_##name()); \ + void __iomem *addr = addr_gcr_##name(); \ + u64 ret; \ + \ + if (mips_cm_is64) { \ + ret = __raw_readq(addr); \ + } else { \ + ret = __raw_readl(addr); \ + ret |= (u64)__raw_readl(addr + 0x4) << 32; \ + } \ + \ + return ret; \ } \ \ static inline unsigned long read_gcr_##name(void) \ @@ -195,6 +206,8 @@ BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0) BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0) BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130) BUILD_CM_RW(sys_config2, MIPS_CM_GCB_OFS + 0x150) +BUILD_CM_RW(l2_pft_control, MIPS_CM_GCB_OFS + 0x300) +BUILD_CM_RW(l2_pft_control_b, MIPS_CM_GCB_OFS + 0x308) /* Core Local & Core Other register accessor functions */ BUILD_CM_Cx_RW(reset_release, 0x00) @@ -245,11 +258,14 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) ((minor) << CM_GCR_REV_MINOR_SHF)) #define CM_REV_CM2 CM_ENCODE_REV(6, 0) +#define CM_REV_CM2_5 CM_ENCODE_REV(7, 0) #define CM_REV_CM3 CM_ENCODE_REV(8, 0) /* GCR_ERROR_CAUSE register fields */ #define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF 27 #define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK (_ULCAST_(0x1f) << 27) +#define CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF 58 +#define CM3_GCR_ERROR_CAUSE_ERRTYPE_MSK GENMASK_ULL(63, 58) #define CM_GCR_ERROR_CAUSE_ERRINFO_SHF 0 #define CM_GCR_ERROR_CAUSE_ERRINGO_MSK (_ULCAST_(0x7ffffff) << 0) @@ -321,6 +337,20 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) #define CM_GCR_SYS_CONFIG2_MAXVPW_SHF 0 #define CM_GCR_SYS_CONFIG2_MAXVPW_MSK (_ULCAST_(0xf) << 0) +/* GCR_L2_PFT_CONTROL register fields */ +#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_SHF 12 +#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK (_ULCAST_(0xfffff) << 12) +#define CM_GCR_L2_PFT_CONTROL_PFTEN_SHF 8 +#define CM_GCR_L2_PFT_CONTROL_PFTEN_MSK (_ULCAST_(0x1) << 8) +#define CM_GCR_L2_PFT_CONTROL_NPFT_SHF 0 +#define CM_GCR_L2_PFT_CONTROL_NPFT_MSK (_ULCAST_(0xff) << 0) + +/* GCR_L2_PFT_CONTROL_B register fields */ +#define CM_GCR_L2_PFT_CONTROL_B_CEN_SHF 8 +#define CM_GCR_L2_PFT_CONTROL_B_CEN_MSK (_ULCAST_(0x1) << 8) +#define CM_GCR_L2_PFT_CONTROL_B_PORTID_SHF 0 +#define CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK (_ULCAST_(0xff) << 0) + /* GCR_Cx_COHERENCE register fields */ #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0 #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0) @@ -329,11 +359,15 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) #define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF 10 #define CM_GCR_Cx_CONFIG_IOCUTYPE_MSK (_ULCAST_(0x3) << 10) #define CM_GCR_Cx_CONFIG_PVPE_SHF 0 -#define CM_GCR_Cx_CONFIG_PVPE_MSK (_ULCAST_(0x1ff) << 0) +#define CM_GCR_Cx_CONFIG_PVPE_MSK (_ULCAST_(0x3ff) << 0) /* GCR_Cx_OTHER register fields */ #define CM_GCR_Cx_OTHER_CORENUM_SHF 16 #define CM_GCR_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xffff) << 16) +#define CM3_GCR_Cx_OTHER_CORE_SHF 8 +#define CM3_GCR_Cx_OTHER_CORE_MSK (_ULCAST_(0x3f) << 8) +#define CM3_GCR_Cx_OTHER_VP_SHF 0 +#define CM3_GCR_Cx_OTHER_VP_MSK (_ULCAST_(0x7) << 0) /* GCR_Cx_RESET_BASE register fields */ #define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_SHF 12 @@ -444,4 +478,32 @@ static inline unsigned int mips_cm_vp_id(unsigned int cpu) return (core * mips_cm_max_vp_width()) + vp; } +#ifdef CONFIG_MIPS_CM + +/** + * mips_cm_lock_other - lock access to another core + * @core: the other core to be accessed + * @vp: the VP within the other core to be accessed + * + * Call before operating upon a core via the 'other' register region in + * order to prevent the region being moved during access. Must be followed + * by a call to mips_cm_unlock_other. + */ +extern void mips_cm_lock_other(unsigned int core, unsigned int vp); + +/** + * mips_cm_unlock_other - unlock access to another core + * + * Call after operating upon another core via the 'other' register region. + * Must be called after mips_cm_lock_other. + */ +extern void mips_cm_unlock_other(void); + +#else /* !CONFIG_MIPS_CM */ + +static inline void mips_cm_lock_other(unsigned int core) { } +static inline void mips_cm_unlock_other(void) { } + +#endif /* !CONFIG_MIPS_CM */ + #endif /* __MIPS_ASM_MIPS_CM_H__ */ diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h index f386f3270..e09035239 100644 --- a/arch/mips/include/asm/mips-cpc.h +++ b/arch/mips/include/asm/mips-cpc.h @@ -149,7 +149,8 @@ BUILD_CPC_Cx_RW(other, 0x10) * core: the other core to be accessed * * Call before operating upon a core via the 'other' register region in - * order to prevent the region being moved during access. Must be followed + * order to prevent the region being moved during access. Must be called + * within the bounds of a mips_cm_{lock,unlock}_other pair, and followed * by a call to mips_cpc_unlock_other. */ extern void mips_cpc_lock_other(unsigned int core); diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index c64781cf6..e43aca183 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -50,7 +50,9 @@ #define CP0_PAGEMASK $5 #define CP0_WIRED $6 #define CP0_INFO $7 +#define CP0_HWRENA $7, 0 #define CP0_BADVADDR $8 +#define CP0_BADINSTR $8, 1 #define CP0_COUNT $9 #define CP0_ENTRYHI $10 #define CP0_COMPARE $11 @@ -58,7 +60,11 @@ #define CP0_CAUSE $13 #define CP0_EPC $14 #define CP0_PRID $15 +#define CP0_EBASE $15, 1 +#define CP0_CMGCRBASE $15, 3 #define CP0_CONFIG $16 +#define CP0_CONFIG3 $16, 3 +#define CP0_CONFIG5 $16, 5 #define CP0_LLADDR $17 #define CP0_WATCHLO $18 #define CP0_WATCHHI $19 @@ -126,15 +132,9 @@ #define R3K_ENTRYLO_N (_ULCAST_(1) << 11) /* MIPS32/64 EntryLo bit definitions */ -#ifdef CONFIG_64BIT -/* as read by dmfc0 */ -#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 62) -#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 63) -#else -/* as read by mfc0 */ -#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 30) -#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 31) -#endif +#define MIPS_ENTRYLO_PFN_SHIFT 6 +#define MIPS_ENTRYLO_XI (_ULCAST_(1) << (BITS_PER_LONG - 2)) +#define MIPS_ENTRYLO_RI (_ULCAST_(1) << (BITS_PER_LONG - 1)) /* * Values for PageMask register diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index 89dd7fed1..2046c0230 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h @@ -33,7 +33,7 @@ #define PAGE_SHIFT 16 #endif #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) +#define PAGE_MASK (~(PAGE_SIZE - 1)) /* * This is used for calculating the real page sizes @@ -200,8 +200,9 @@ static inline int pfn_valid(unsigned long pfn) { /* avoid <linux/mm.h> include hell */ extern unsigned long max_mapnr; + unsigned long pfn_offset = ARCH_PFN_OFFSET; - return pfn >= ARCH_PFN_OFFSET && pfn < max_mapnr; + return pfn >= pfn_offset && pfn < max_mapnr; } #elif defined(CONFIG_SPARSEMEM) diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 59ee6dcf6..3f832c3dd 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -36,12 +36,6 @@ extern unsigned int vced_count, vcei_count; */ #define HAVE_ARCH_PICK_MMAP_LAYOUT 1 -/* - * A special page (the vdso) is mapped into all processes at the very - * top of the virtual memory space. - */ -#define SPECIAL_PAGES_SIZE PAGE_SIZE - #ifdef CONFIG_32BIT #ifdef CONFIG_KVM_GUEST /* User space process size is limited to 1GB in KVM Guest Mode */ @@ -80,7 +74,7 @@ extern unsigned int vced_count, vcei_count; #endif -#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE) +#define STACK_TOP (TASK_SIZE & PAGE_MASK) /* * This decides where the kernel will search for a free chunk of vm diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 5305d694f..095ecafe6 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -599,7 +599,7 @@ extern void __put_user_unknown(void); * On error, the variable @x is set to zero. */ #define __get_user_unaligned(x,ptr) \ - __get_user__unalignednocheck((x),(ptr),sizeof(*(ptr))) + __get_user_unaligned_nocheck((x),(ptr),sizeof(*(ptr))) /* * Yuck. We need two variants, one for 64bit operation and one @@ -620,8 +620,8 @@ extern void __get_user_unaligned_unknown(void); do { \ switch (size) { \ case 1: __get_data_asm(val, "lb", ptr); break; \ - case 2: __get_user_unaligned_asm(val, "ulh", ptr); break; \ - case 4: __get_user_unaligned_asm(val, "ulw", ptr); break; \ + case 2: __get_data_unaligned_asm(val, "ulh", ptr); break; \ + case 4: __get_data_unaligned_asm(val, "ulw", ptr); break; \ case 8: __GET_USER_UNALIGNED_DW(val, ptr); break; \ default: __get_user_unaligned_unknown(); break; \ } \ @@ -1122,9 +1122,15 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ - might_fault(); \ - __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \ - __cu_len); \ + if (eva_kernel_access()) { \ + __cu_len = __invoke_copy_from_kernel(__cu_to, \ + __cu_from, \ + __cu_len); \ + } else { \ + might_fault(); \ + __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \ + __cu_len); \ + } \ __cu_len; \ }) @@ -1229,16 +1235,28 @@ __clear_user(void __user *addr, __kernel_size_t size) { __kernel_size_t res; - might_fault(); - __asm__ __volatile__( - "move\t$4, %1\n\t" - "move\t$5, $0\n\t" - "move\t$6, %2\n\t" - __MODULE_JAL(__bzero) - "move\t%0, $6" - : "=r" (res) - : "r" (addr), "r" (size) - : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"); + if (eva_kernel_access()) { + __asm__ __volatile__( + "move\t$4, %1\n\t" + "move\t$5, $0\n\t" + "move\t$6, %2\n\t" + __MODULE_JAL(__bzero_kernel) + "move\t%0, $6" + : "=r" (res) + : "r" (addr), "r" (size) + : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"); + } else { + might_fault(); + __asm__ __volatile__( + "move\t$4, %1\n\t" + "move\t$5, $0\n\t" + "move\t$6, %2\n\t" + __MODULE_JAL(__bzero) + "move\t%0, $6" + : "=r" (res) + : "r" (addr), "r" (size) + : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"); + } return res; } @@ -1384,7 +1402,7 @@ static inline long strlen_user(const char __user *s) might_fault(); __asm__ __volatile__( "move\t$4, %1\n\t" - __MODULE_JAL(__strlen_kernel_asm) + __MODULE_JAL(__strlen_user_asm) "move\t%0, $2" : "=r" (res) : "r" (s) diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h index cca56aa40..8f4ca5dd9 100644 --- a/arch/mips/include/asm/vdso.h +++ b/arch/mips/include/asm/vdso.h @@ -1,29 +1,136 @@ /* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * Copyright (C) 2015 Imagination Technologies + * Author: Alex Smith <alex.smith@imgtec.com> * - * Copyright (C) 2009 Cavium Networks + * 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_H #define __ASM_VDSO_H -#include <linux/types.h> +#include <linux/mm_types.h> +#include <asm/barrier.h> -#ifdef CONFIG_32BIT -struct mips_vdso { - u32 signal_trampoline[2]; - u32 rt_signal_trampoline[2]; +/** + * struct mips_vdso_image - Details of a VDSO image. + * @data: Pointer to VDSO image data (page-aligned). + * @size: Size of the VDSO image data (page-aligned). + * @off_sigreturn: Offset of the sigreturn() trampoline. + * @off_rt_sigreturn: Offset of the rt_sigreturn() trampoline. + * @mapping: Special mapping structure. + * + * This structure contains details of a VDSO image, including the image data + * and offsets of certain symbols required by the kernel. It is generated as + * part of the VDSO build process, aside from the mapping page array, which is + * populated at runtime. + */ +struct mips_vdso_image { + void *data; + unsigned long size; + + unsigned long off_sigreturn; + unsigned long off_rt_sigreturn; + + struct vm_special_mapping mapping; }; -#else /* !CONFIG_32BIT */ -struct mips_vdso { - u32 o32_signal_trampoline[2]; - u32 o32_rt_signal_trampoline[2]; - u32 rt_signal_trampoline[2]; - u32 n32_rt_signal_trampoline[2]; + +/* + * The following structures are auto-generated as part of the build for each + * ABI by genvdso, see arch/mips/vdso/Makefile. + */ + +extern struct mips_vdso_image vdso_image; + +#ifdef CONFIG_MIPS32_O32 +extern struct mips_vdso_image vdso_image_o32; +#endif + +#ifdef CONFIG_MIPS32_N32 +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; + u32 wall_to_mono_sec; + u32 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; + }; + + u8 page[PAGE_SIZE]; }; -#endif /* CONFIG_32BIT */ + +static inline u32 vdso_data_read_begin(const union mips_vdso_data *data) +{ + u32 seq; + + while (true) { + seq = ACCESS_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 */ |