diff options
Diffstat (limited to 'arch/powerpc/include/asm/processor.h')
| -rw-r--r-- | arch/powerpc/include/asm/processor.h | 111 | 
1 files changed, 64 insertions, 47 deletions
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index ce4de5aed7b..6d59072e13a 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -14,8 +14,18 @@  #ifdef CONFIG_VSX  #define TS_FPRWIDTH 2 + +#ifdef __BIG_ENDIAN__ +#define TS_FPROFFSET 0 +#define TS_VSRLOWOFFSET 1 +#else +#define TS_FPROFFSET 1 +#define TS_VSRLOWOFFSET 0 +#endif +  #else  #define TS_FPRWIDTH 1 +#define TS_FPROFFSET 0  #endif  #ifdef CONFIG_PPC64 @@ -142,26 +152,22 @@ typedef struct {  	unsigned long seg;  } mm_segment_t; -#define TS_FPROFFSET 0 -#define TS_VSRLOWOFFSET 1 -#define TS_FPR(i) fpr[i][TS_FPROFFSET] -#define TS_TRANS_FPR(i) transact_fpr[i][TS_FPROFFSET] +#define TS_FPR(i) fp_state.fpr[i][TS_FPROFFSET] +#define TS_TRANS_FPR(i) transact_fp.fpr[i][TS_FPROFFSET] -struct thread_struct { -	unsigned long	ksp;		/* Kernel stack pointer */ -#ifdef CONFIG_PPC64 -	unsigned long	ksp_vsid; -#endif -	struct pt_regs	*regs;		/* Pointer to saved register state */ -	mm_segment_t	fs;		/* for get_fs() validation */ -#ifdef CONFIG_BOOKE -	/* BookE base exception scratch space; align on cacheline */ -	unsigned long	normsave[8] ____cacheline_aligned; -#endif -#ifdef CONFIG_PPC32 -	void		*pgdir;		/* root of page-table tree */ -	unsigned long	ksp_limit;	/* if ksp <= ksp_limit stack overflow */ -#endif +/* FP and VSX 0-31 register set */ +struct thread_fp_state { +	u64	fpr[32][TS_FPRWIDTH] __attribute__((aligned(16))); +	u64	fpscr;		/* Floating point status */ +}; + +/* Complete AltiVec register set including VSCR */ +struct thread_vr_state { +	vector128	vr[32] __attribute__((aligned(16))); +	vector128	vscr __attribute__((aligned(16))); +}; + +struct debug_reg {  #ifdef CONFIG_PPC_ADV_DEBUG_REGS  	/*  	 * The following help to manage the use of Debug Control Registers @@ -198,13 +204,28 @@ struct thread_struct {  	unsigned long	dvc2;  #endif  #endif -	/* FP and VSX 0-31 register set */ -	double		fpr[32][TS_FPRWIDTH] __attribute__((aligned(16))); -	struct { +}; + +struct thread_struct { +	unsigned long	ksp;		/* Kernel stack pointer */ -		unsigned int pad; -		unsigned int val;	/* Floating point status */ -	} fpscr; +#ifdef CONFIG_PPC64 +	unsigned long	ksp_vsid; +#endif +	struct pt_regs	*regs;		/* Pointer to saved register state */ +	mm_segment_t	fs;		/* for get_fs() validation */ +#ifdef CONFIG_BOOKE +	/* BookE base exception scratch space; align on cacheline */ +	unsigned long	normsave[8] ____cacheline_aligned; +#endif +#ifdef CONFIG_PPC32 +	void		*pgdir;		/* root of page-table tree */ +	unsigned long	ksp_limit;	/* if ksp <= ksp_limit stack overflow */ +#endif +	/* Debug Registers */ +	struct debug_reg debug; +	struct thread_fp_state	fp_state; +	struct thread_fp_state	*fp_save_area;  	int		fpexc_mode;	/* floating-point exception mode */  	unsigned int	align_ctl;	/* alignment handling control */  #ifdef CONFIG_PPC64 @@ -222,10 +243,8 @@ struct thread_struct {  	struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */  	unsigned long	trap_nr;	/* last trap # on this thread */  #ifdef CONFIG_ALTIVEC -	/* Complete AltiVec register set */ -	vector128	vr[32] __attribute__((aligned(16))); -	/* AltiVec status */ -	vector128	vscr __attribute__((aligned(16))); +	struct thread_vr_state vr_state; +	struct thread_vr_state *vr_save_area;  	unsigned long	vrsave;  	int		used_vr;	/* set if process has used altivec */  #endif /* CONFIG_ALTIVEC */ @@ -237,6 +256,8 @@ struct thread_struct {  	unsigned long	evr[32];	/* upper 32-bits of SPE regs */  	u64		acc;		/* Accumulator */  	unsigned long	spefscr;	/* SPE & eFP status */ +	unsigned long	spefscr_last;	/* SPEFSCR value on last prctl +					   call or trap return */  	int		used_spe;	/* set if process has used spe */  #endif /* CONFIG_SPE */  #ifdef CONFIG_PPC_TRANSACTIONAL_MEM @@ -262,13 +283,8 @@ struct thread_struct {  	 * transact_fpr[] is the new set of transactional values.  	 * VRs work the same way.  	 */ -	double		transact_fpr[32][TS_FPRWIDTH]; -	struct { -		unsigned int pad; -		unsigned int val;	/* Floating point status */ -	} transact_fpscr; -	vector128	transact_vr[32] __attribute__((aligned(16))); -	vector128	transact_vscr __attribute__((aligned(16))); +	struct thread_fp_state transact_fp; +	struct thread_vr_state transact_vr;  	unsigned long	transact_vrsave;  #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */  #ifdef CONFIG_KVM_BOOK3S_32_HANDLER @@ -303,7 +319,9 @@ struct thread_struct {  	(_ALIGN_UP(sizeof(init_thread_info), 16) + (unsigned long) &init_stack)  #ifdef CONFIG_SPE -#define SPEFSCR_INIT .spefscr = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE, +#define SPEFSCR_INIT \ +	.spefscr = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE, \ +	.spefscr_last = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE,  #else  #define SPEFSCR_INIT  #endif @@ -322,8 +340,6 @@ struct thread_struct {  	.ksp = INIT_SP, \  	.regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \  	.fs = KERNEL_DS, \ -	.fpr = {{0}}, \ -	.fpscr = { .val = 0, }, \  	.fpexc_mode = 0, \  	.ppr = INIT_PPR, \  } @@ -361,6 +377,13 @@ extern int set_endian(struct task_struct *tsk, unsigned int val);  extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr);  extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val); +extern void fp_enable(void); +extern void vec_enable(void); +extern void load_fp_state(struct thread_fp_state *fp); +extern void store_fp_state(struct thread_fp_state *fp); +extern void load_vr_state(struct thread_vr_state *vr); +extern void store_vr_state(struct thread_vr_state *vr); +  static inline unsigned int __unpack_fe01(unsigned long msr_bits)  {  	return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8); @@ -426,14 +449,8 @@ extern unsigned long cpuidle_disable;  enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};  extern int powersave_nap;	/* set if nap mode can be used in idle loop */ -extern void power7_nap(void); - -#ifdef CONFIG_PSERIES_IDLE -extern void update_smt_snooze_delay(int cpu, int residency); -#else -static inline void update_smt_snooze_delay(int cpu, int residency) {} -#endif - +extern void power7_nap(int check_irq); +extern void power7_sleep(void);  extern void flush_instruction_cache(void);  extern void hard_reset_now(void);  extern void poweroff_now(void);  | 
