diff options
Diffstat (limited to 'arch/mips/include/asm/processor.h')
| -rw-r--r-- | arch/mips/include/asm/processor.h | 181 |
1 files changed, 109 insertions, 72 deletions
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 3605b844ad87..ca7662cc65a7 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -11,52 +11,34 @@ #ifndef _ASM_PROCESSOR_H #define _ASM_PROCESSOR_H +#include <linux/atomic.h> #include <linux/cpumask.h> +#include <linux/sizes.h> #include <linux/threads.h> #include <asm/cachectl.h> #include <asm/cpu.h> #include <asm/cpu-info.h> +#include <asm/dsemul.h> #include <asm/mipsregs.h> #include <asm/prefetch.h> - -/* - * Return current * instruction pointer ("program counter"). - */ -#define current_text_addr() ({ __label__ _l; _l: &&_l;}) +#include <asm/vdso/processor.h> /* * System setup and hardware flags.. */ extern unsigned int vced_count, vcei_count; - -/* - * MIPS does have an arch_pick_mmap_layout() - */ -#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 +extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); #ifdef CONFIG_32BIT -#ifdef CONFIG_KVM_GUEST -/* User space process size is limited to 1GB in KVM Guest Mode */ -#define TASK_SIZE 0x3fff8000UL -#else /* * User space process size: 2GB. This is hardcoded into a few places, * so don't change it unless you know what you are doing. */ -#define TASK_SIZE 0x7fff8000UL -#endif +#define TASK_SIZE 0x80000000UL -#ifdef __KERNEL__ #define STACK_TOP_MAX TASK_SIZE -#endif #define TASK_IS_32BIT_ADDR 1 @@ -71,13 +53,13 @@ extern unsigned int vced_count, vcei_count; * 8192EB ... */ #define TASK_SIZE32 0x7fff8000UL -#define TASK_SIZE64 0x10000000000UL +#ifdef CONFIG_MIPS_VA_BITS_48 +#define TASK_SIZE64 (0x1UL << ((cpu_data[0].vmbits>48)?48:cpu_data[0].vmbits)) +#else +#define TASK_SIZE64 0x10000000000UL +#endif #define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64) - -#ifdef __KERNEL__ #define STACK_TOP_MAX TASK_SIZE64 -#endif - #define TASK_SIZE_OF(tsk) \ (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64) @@ -86,7 +68,10 @@ extern unsigned int vced_count, vcei_count; #endif -#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE) +#define VDSO_RANDOMIZE_SIZE (TASK_IS_32BIT_ADDR ? SZ_1M : SZ_64M) + +extern unsigned long mips_stack_top(void); +#define STACK_TOP mips_stack_top() /* * This decides where the kernel will search for a free chunk of vm @@ -97,23 +82,53 @@ extern unsigned int vced_count, vcei_count; #define NUM_FPU_REGS 32 -typedef __u64 fpureg_t; +#ifdef CONFIG_CPU_HAS_MSA +# define FPU_REG_WIDTH 128 +#else +# define FPU_REG_WIDTH 64 +#endif + +union fpureg { + __u32 val32[FPU_REG_WIDTH / 32]; + __u64 val64[FPU_REG_WIDTH / 64]; +}; + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +# define FPR_IDX(width, idx) (idx) +#else +# define FPR_IDX(width, idx) ((idx) ^ ((64 / (width)) - 1)) +#endif + +#define BUILD_FPR_ACCESS(width) \ +static inline u##width get_fpr##width(union fpureg *fpr, unsigned idx) \ +{ \ + return fpr->val##width[FPR_IDX(width, idx)]; \ +} \ + \ +static inline void set_fpr##width(union fpureg *fpr, unsigned idx, \ + u##width val) \ +{ \ + fpr->val##width[FPR_IDX(width, idx)] = val; \ +} + +BUILD_FPR_ACCESS(32) +BUILD_FPR_ACCESS(64) /* - * It would be nice to add some more fields for emulator statistics, but there - * are a number of fixed offsets in offset.h and elsewhere that would have to - * be recalculated by hand. So the additional information will be private to - * the FPU emulator for now. See asm-mips/fpu_emulator.h. + * It would be nice to add some more fields for emulator statistics, + * the additional information is private to the FPU emulator for now. + * See arch/mips/include/asm/fpu_emulator.h. */ struct mips_fpu_struct { - fpureg_t fpr[NUM_FPU_REGS]; + union fpureg fpr[NUM_FPU_REGS]; unsigned int fcr31; + unsigned int msacsr; }; #define NUM_DSP_REGS 6 -typedef __u32 dspreg_t; +typedef unsigned long dspreg_t; struct mips_dsp_state { dspreg_t dspr[NUM_DSP_REGS]; @@ -181,34 +196,30 @@ struct octeon_cop2_state { unsigned long cop2_gfm_poly; /* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */ unsigned long cop2_gfm_result[2]; + /* DMFC2 rt, 0x24F, DMFC2 rt, 0x50, OCTEON III */ + unsigned long cop2_sha3[2]; }; #define COP2_INIT \ .cp2 = {0,}, +#if defined(CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE) && \ + CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0 struct octeon_cvmseg_state { unsigned long cvmseg[CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE] [cpu_dcache_line_size() / sizeof(unsigned long)]; }; - -#elif defined(CONFIG_CPU_XLP) -struct nlm_cop2_state { - u64 rx[4]; - u64 tx[4]; - u32 tx_msg_status; - u32 rx_msg_status; -}; - -#define COP2_INIT \ - .cp2 = {{0}, {0}, 0, 0}, +#endif #else #define COP2_INIT #endif -typedef struct { - unsigned long seg; -} mm_segment_t; - -#define ARCH_MIN_TASKALIGN 8 +#ifdef CONFIG_CPU_HAS_MSA +# define ARCH_MIN_TASKALIGN 16 +# define FPU_ALIGN __aligned(16) +#else +# define ARCH_MIN_TASKALIGN 8 +# define FPU_ALIGN +#endif struct mips_abi; @@ -224,8 +235,16 @@ struct thread_struct { /* Saved cp0 stuff. */ unsigned long cp0_status; +#ifdef CONFIG_MIPS_FP_SUPPORT /* Saved fpu/fpu emulator stuff. */ - struct mips_fpu_struct fpu; + struct mips_fpu_struct fpu FPU_ALIGN; + /* Assigned branch delay slot 'emulation' frame */ + atomic_t bd_emu_frame; + /* PC of the branch from a branch delay slot 'emulation' */ + unsigned long bd_emu_branch_pc; + /* PC to continue from following a branch delay slot 'emulation' */ + unsigned long bd_emu_cont_pc; +#endif #ifdef CONFIG_MIPS_MT_FPAFF /* Emulated instruction count */ unsigned long emulated_fp; @@ -243,12 +262,13 @@ struct thread_struct { unsigned long cp0_badvaddr; /* Last user fault */ unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ unsigned long error_code; + unsigned long trap_nr; #ifdef CONFIG_CPU_CAVIUM_OCTEON struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128))); +#if defined(CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE) && \ + CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0 struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128))); #endif -#ifdef CONFIG_CPU_XLP - struct nlm_cop2_state cp2; #endif struct mips_abi *abi; }; @@ -261,6 +281,21 @@ struct thread_struct { #define FPAFF_INIT #endif /* CONFIG_MIPS_MT_FPAFF */ +#ifdef CONFIG_MIPS_FP_SUPPORT +# define FPU_INIT \ + .fpu = { \ + .fpr = {{{0,},},}, \ + .fcr31 = 0, \ + .msacsr = 0, \ + }, \ + /* Delay slot emulation */ \ + .bd_emu_frame = ATOMIC_INIT(BD_EMUFRAME_NONE), \ + .bd_emu_branch_pc = 0, \ + .bd_emu_cont_pc = 0, +#else +# define FPU_INIT +#endif + #define INIT_THREAD { \ /* \ * Saved main processor registers \ @@ -283,10 +318,7 @@ struct thread_struct { /* \ * Saved FPU/FPU emulator stuff \ */ \ - .fpu = { \ - .fpr = {0,}, \ - .fcr31 = 0, \ - }, \ + FPU_INIT \ /* \ * FPU affinity state (null if not FPAFF) \ */ \ @@ -308,6 +340,7 @@ struct thread_struct { .cp0_badvaddr = 0, \ .cp0_baduaddr = 0, \ .error_code = 0, \ + .trap_nr = 0, \ /* \ * Platform specific cop2 registers(null if no COP2) \ */ \ @@ -316,17 +349,16 @@ struct thread_struct { struct task_struct; -/* Free all resources held by a thread. */ -#define release_thread(thread) do { } while(0) - -extern unsigned long thread_saved_pc(struct task_struct *tsk); - /* * Do necessary setup to start up a newly executed thread. */ extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); -unsigned long get_wchan(struct task_struct *p); +static inline void flush_thread(void) +{ +} + +unsigned long __get_wchan(struct task_struct *p); #define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \ THREAD_SIZE - 32 - sizeof(struct pt_regs)) @@ -335,8 +367,6 @@ unsigned long get_wchan(struct task_struct *p); #define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29]) #define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status) -#define cpu_relax() barrier() - /* * Return_address is a replacement for __builtin_return_address(count) * which on certain architectures cannot reasonably be implemented in GCC @@ -359,12 +389,19 @@ unsigned long get_wchan(struct task_struct *p); #define ARCH_HAS_PREFETCHW #define prefetchw(x) __builtin_prefetch((x), 1, 1) +#endif + /* - * See Documentation/scheduler/sched-arch.txt; prevents deadlock on SMP - * systems. + * Functions & macros implementing the PR_GET_FP_MODE & PR_SET_FP_MODE options + * to the prctl syscall. */ -#define __ARCH_WANT_UNLOCKED_CTXSW +extern int mips_get_process_fp_mode(struct task_struct *task); +extern int mips_set_process_fp_mode(struct task_struct *task, + unsigned int value); -#endif +#define GET_FP_MODE(task) mips_get_process_fp_mode(task) +#define SET_FP_MODE(task,value) mips_set_process_fp_mode(task, value) + +void show_registers(struct pt_regs *regs); #endif /* _ASM_PROCESSOR_H */ |
