diff options
Diffstat (limited to 'arch/mips/include/asm/processor.h')
| -rw-r--r-- | arch/mips/include/asm/processor.h | 214 |
1 files changed, 131 insertions, 83 deletions
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 087a8884ef0..ad70cba8daf 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -19,7 +19,6 @@ #include <asm/cpu-info.h> #include <asm/mipsregs.h> #include <asm/prefetch.h> -#include <asm/system.h> /* * Return current * instruction pointer ("program counter"). @@ -29,23 +28,38 @@ /* * System setup and hardware flags.. */ -extern void (*cpu_wait)(void); 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 + #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 -#define STACK_TOP TASK_SIZE +#endif + +#ifdef __KERNEL__ +#define STACK_TOP_MAX TASK_SIZE +#endif + +#define TASK_IS_32BIT_ADDR 1 -/* - * This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#define TASK_UNMAPPED_BASE ((TASK_SIZE / 3) & ~(PAGE_SIZE)) #endif #ifdef CONFIG_64BIT @@ -57,39 +71,74 @@ extern unsigned int vced_count, vcei_count; * 8192EB ... */ #define TASK_SIZE32 0x7fff8000UL -#define TASK_SIZE 0x10000000000UL -#define STACK_TOP \ - (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE) +#define TASK_SIZE64 0x10000000000UL +#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) + +#define TASK_IS_32BIT_ADDR test_thread_flag(TIF_32BIT_ADDR) + +#endif + +#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE) /* * This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE \ - (test_thread_flag(TIF_32BIT_ADDR) ? \ - PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3)) -#define TASK_SIZE_OF(tsk) \ - (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE) +#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3) + + +#define NUM_FPU_REGS 32 + +#ifdef CONFIG_CPU_HAS_MSA +# define FPU_REG_WIDTH 128 +#else +# define FPU_REG_WIDTH 64 #endif -#ifdef __KERNEL__ -#define STACK_TOP_MAX TASK_SIZE +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) ((FPU_REG_WIDTH / (width)) - 1 - (idx)) #endif -#define NUM_FPU_REGS 32 +#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; \ +} -typedef __u64 fpureg_t; +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 @@ -97,8 +146,8 @@ struct mips_fpu_struct { typedef __u32 dspreg_t; struct mips_dsp_state { - dspreg_t dspr[NUM_DSP_REGS]; - unsigned int dspcontrol; + dspreg_t dspr[NUM_DSP_REGS]; + unsigned int dspcontrol; }; #define INIT_CPUMASK { \ @@ -118,58 +167,71 @@ union mips_watch_reg_state { struct mips3264_watch_reg_state mips3264; }; -#ifdef CONFIG_CPU_CAVIUM_OCTEON +#if defined(CONFIG_CPU_CAVIUM_OCTEON) struct octeon_cop2_state { /* DMFC2 rt, 0x0201 */ - unsigned long cop2_crc_iv; + unsigned long cop2_crc_iv; /* DMFC2 rt, 0x0202 (Set with DMTC2 rt, 0x1202) */ - unsigned long cop2_crc_length; + unsigned long cop2_crc_length; /* DMFC2 rt, 0x0200 (set with DMTC2 rt, 0x4200) */ - unsigned long cop2_crc_poly; + unsigned long cop2_crc_poly; /* DMFC2 rt, 0x0402; DMFC2 rt, 0x040A */ - unsigned long cop2_llm_dat[2]; + unsigned long cop2_llm_dat[2]; /* DMFC2 rt, 0x0084 */ - unsigned long cop2_3des_iv; + unsigned long cop2_3des_iv; /* DMFC2 rt, 0x0080; DMFC2 rt, 0x0081; DMFC2 rt, 0x0082 */ - unsigned long cop2_3des_key[3]; + unsigned long cop2_3des_key[3]; /* DMFC2 rt, 0x0088 (Set with DMTC2 rt, 0x0098) */ - unsigned long cop2_3des_result; + unsigned long cop2_3des_result; /* DMFC2 rt, 0x0111 (FIXME: Read Pass1 Errata) */ - unsigned long cop2_aes_inp0; + unsigned long cop2_aes_inp0; /* DMFC2 rt, 0x0102; DMFC2 rt, 0x0103 */ - unsigned long cop2_aes_iv[2]; + unsigned long cop2_aes_iv[2]; /* DMFC2 rt, 0x0104; DMFC2 rt, 0x0105; DMFC2 rt, 0x0106; DMFC2 * rt, 0x0107 */ - unsigned long cop2_aes_key[4]; + unsigned long cop2_aes_key[4]; /* DMFC2 rt, 0x0110 */ - unsigned long cop2_aes_keylen; + unsigned long cop2_aes_keylen; /* DMFC2 rt, 0x0100; DMFC2 rt, 0x0101 */ - unsigned long cop2_aes_result[2]; + unsigned long cop2_aes_result[2]; /* DMFC2 rt, 0x0240; DMFC2 rt, 0x0241; DMFC2 rt, 0x0242; DMFC2 * rt, 0x0243; DMFC2 rt, 0x0244; DMFC2 rt, 0x0245; DMFC2 rt, * 0x0246; DMFC2 rt, 0x0247; DMFC2 rt, 0x0248; DMFC2 rt, * 0x0249; DMFC2 rt, 0x024A; DMFC2 rt, 0x024B; DMFC2 rt, * 0x024C; DMFC2 rt, 0x024D; DMFC2 rt, 0x024E - Pass2 */ - unsigned long cop2_hsh_datw[15]; + unsigned long cop2_hsh_datw[15]; /* DMFC2 rt, 0x0250; DMFC2 rt, 0x0251; DMFC2 rt, 0x0252; DMFC2 * rt, 0x0253; DMFC2 rt, 0x0254; DMFC2 rt, 0x0255; DMFC2 rt, * 0x0256; DMFC2 rt, 0x0257 - Pass2 */ - unsigned long cop2_hsh_ivw[8]; + unsigned long cop2_hsh_ivw[8]; /* DMFC2 rt, 0x0258; DMFC2 rt, 0x0259 - Pass2 */ - unsigned long cop2_gfm_mult[2]; + unsigned long cop2_gfm_mult[2]; /* DMFC2 rt, 0x025E - Pass2 */ - unsigned long cop2_gfm_poly; + unsigned long cop2_gfm_poly; /* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */ - unsigned long cop2_gfm_result[2]; + unsigned long cop2_gfm_result[2]; }; -#define INIT_OCTEON_COP2 {0,} +#define COP2_INIT \ + .cp2 = {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}, +#else +#define COP2_INIT #endif typedef struct { @@ -211,12 +273,12 @@ 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_no; - unsigned long irix_trampoline; /* Wheee... */ - unsigned long irix_oldctx; #ifdef CONFIG_CPU_CAVIUM_OCTEON - struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128))); - struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128))); + struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128))); + struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128))); +#endif +#ifdef CONFIG_CPU_XLP + struct nlm_cop2_state cp2; #endif struct mips_abi *abi; }; @@ -229,17 +291,10 @@ struct thread_struct { #define FPAFF_INIT #endif /* CONFIG_MIPS_MT_FPAFF */ -#ifdef CONFIG_CPU_CAVIUM_OCTEON -#define OCTEON_INIT \ - .cp2 = INIT_OCTEON_COP2, -#else -#define OCTEON_INIT -#endif /* CONFIG_CPU_CAVIUM_OCTEON */ - #define INIT_THREAD { \ - /* \ - * Saved main processor registers \ - */ \ + /* \ + * Saved main processor registers \ + */ \ .reg16 = 0, \ .reg17 = 0, \ .reg18 = 0, \ @@ -259,8 +314,9 @@ struct thread_struct { * Saved FPU/FPU emulator stuff \ */ \ .fpu = { \ - .fpr = {0,}, \ + .fpr = {{{0,},},}, \ .fcr31 = 0, \ + .msacsr = 0, \ }, \ /* \ * FPU affinity state (null if not FPAFF) \ @@ -283,13 +339,10 @@ struct thread_struct { .cp0_badvaddr = 0, \ .cp0_baduaddr = 0, \ .error_code = 0, \ - .trap_no = 0, \ - .irix_trampoline = 0, \ - .irix_oldctx = 0, \ /* \ - * Cavium Octeon specifics (null if not Octeon) \ + * Platform specific cop2 registers(null if no COP2) \ */ \ - OCTEON_INIT \ + COP2_INIT \ } struct task_struct; @@ -297,11 +350,6 @@ struct task_struct; /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) -/* Prepare to copy thread state - unlazy all lazy status */ -#define prepare_to_copy(tsk) do { } while (0) - -extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); - extern unsigned long thread_saved_pc(struct task_struct *tsk); /* @@ -323,12 +371,12 @@ unsigned long get_wchan(struct task_struct *p); /* * Return_address is a replacement for __builtin_return_address(count) * which on certain architectures cannot reasonably be implemented in GCC - * (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386). + * (MIPS, Alpha) or is unusable with -fomit-frame-pointer (i386). * Note that __builtin_return_address(x>=1) is forbidden because GCC * aborts compilation on some CPUs. It's simply not possible to unwind * some CPU's stackframes. * - * __builtin_return_address works only for non-leaf functions. We avoid the + * __builtin_return_address works only for non-leaf functions. We avoid the * overhead of a function call by forcing the compiler to save the return * address register on the stack. */ @@ -337,16 +385,16 @@ unsigned long get_wchan(struct task_struct *p); #ifdef CONFIG_CPU_HAS_PREFETCH #define ARCH_HAS_PREFETCH +#define prefetch(x) __builtin_prefetch((x), 0, 1) -static inline void prefetch(const void *addr) -{ - __asm__ __volatile__( - " .set mips4 \n" - " pref %0, (%1) \n" - " .set mips0 \n" - : - : "i" (Pref_Load), "r" (addr)); -} +#define ARCH_HAS_PREFETCHW +#define prefetchw(x) __builtin_prefetch((x), 1, 1) + +/* + * See Documentation/scheduler/sched-arch.txt; prevents deadlock on SMP + * systems. + */ +#define __ARCH_WANT_UNLOCKED_CTXSW #endif |
