162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci#ifndef _ASM_POWERPC_PROCESSOR_H 362306a36Sopenharmony_ci#define _ASM_POWERPC_PROCESSOR_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * Copyright (C) 2001 PPC 64 Team, IBM Corp 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <vdso/processor.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <asm/reg.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#ifdef CONFIG_VSX 1462306a36Sopenharmony_ci#define TS_FPRWIDTH 2 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#ifdef __BIG_ENDIAN__ 1762306a36Sopenharmony_ci#define TS_FPROFFSET 0 1862306a36Sopenharmony_ci#define TS_VSRLOWOFFSET 1 1962306a36Sopenharmony_ci#else 2062306a36Sopenharmony_ci#define TS_FPROFFSET 1 2162306a36Sopenharmony_ci#define TS_VSRLOWOFFSET 0 2262306a36Sopenharmony_ci#endif 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#else 2562306a36Sopenharmony_ci#define TS_FPRWIDTH 1 2662306a36Sopenharmony_ci#define TS_FPROFFSET 0 2762306a36Sopenharmony_ci#endif 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#ifdef CONFIG_PPC64 3062306a36Sopenharmony_ci/* Default SMT priority is set to 3. Use 11- 13bits to save priority. */ 3162306a36Sopenharmony_ci#define PPR_PRIORITY 3 3262306a36Sopenharmony_ci#ifdef __ASSEMBLY__ 3362306a36Sopenharmony_ci#define DEFAULT_PPR (PPR_PRIORITY << 50) 3462306a36Sopenharmony_ci#else 3562306a36Sopenharmony_ci#define DEFAULT_PPR ((u64)PPR_PRIORITY << 50) 3662306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */ 3762306a36Sopenharmony_ci#endif /* CONFIG_PPC64 */ 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 4062306a36Sopenharmony_ci#include <linux/types.h> 4162306a36Sopenharmony_ci#include <linux/thread_info.h> 4262306a36Sopenharmony_ci#include <asm/ptrace.h> 4362306a36Sopenharmony_ci#include <asm/hw_breakpoint.h> 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci/* We do _not_ want to define new machine types at all, those must die 4662306a36Sopenharmony_ci * in favor of using the device-tree 4762306a36Sopenharmony_ci * -- BenH. 4862306a36Sopenharmony_ci */ 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci/* PREP sub-platform types. Unused */ 5162306a36Sopenharmony_ci#define _PREP_Motorola 0x01 /* motorola prep */ 5262306a36Sopenharmony_ci#define _PREP_Firm 0x02 /* firmworks prep */ 5362306a36Sopenharmony_ci#define _PREP_IBM 0x00 /* ibm prep */ 5462306a36Sopenharmony_ci#define _PREP_Bull 0x03 /* bull prep */ 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* CHRP sub-platform types. These are arbitrary */ 5762306a36Sopenharmony_ci#define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ 5862306a36Sopenharmony_ci#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ 5962306a36Sopenharmony_ci#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */ 6062306a36Sopenharmony_ci#define _CHRP_briq 0x07 /* TotalImpact's briQ */ 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#if defined(__KERNEL__) && defined(CONFIG_PPC32) 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ciextern int _chrp_type; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#endif /* defined(__KERNEL__) && defined(CONFIG_PPC32) */ 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci#ifdef __KERNEL__ 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci#ifdef CONFIG_PPC64 7162306a36Sopenharmony_ci#include <asm/task_size_64.h> 7262306a36Sopenharmony_ci#else 7362306a36Sopenharmony_ci#include <asm/task_size_32.h> 7462306a36Sopenharmony_ci#endif 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistruct task_struct; 7762306a36Sopenharmony_civoid start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci#define TS_FPR(i) fp_state.fpr[i][TS_FPROFFSET] 8062306a36Sopenharmony_ci#define TS_CKFPR(i) ckfp_state.fpr[i][TS_FPROFFSET] 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/* FP and VSX 0-31 register set */ 8362306a36Sopenharmony_cistruct thread_fp_state { 8462306a36Sopenharmony_ci u64 fpr[32][TS_FPRWIDTH] __attribute__((aligned(16))); 8562306a36Sopenharmony_ci u64 fpscr; /* Floating point status */ 8662306a36Sopenharmony_ci}; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci/* Complete AltiVec register set including VSCR */ 8962306a36Sopenharmony_cistruct thread_vr_state { 9062306a36Sopenharmony_ci vector128 vr[32] __attribute__((aligned(16))); 9162306a36Sopenharmony_ci vector128 vscr __attribute__((aligned(16))); 9262306a36Sopenharmony_ci}; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistruct debug_reg { 9562306a36Sopenharmony_ci#ifdef CONFIG_PPC_ADV_DEBUG_REGS 9662306a36Sopenharmony_ci /* 9762306a36Sopenharmony_ci * The following help to manage the use of Debug Control Registers 9862306a36Sopenharmony_ci * om the BookE platforms. 9962306a36Sopenharmony_ci */ 10062306a36Sopenharmony_ci uint32_t dbcr0; 10162306a36Sopenharmony_ci uint32_t dbcr1; 10262306a36Sopenharmony_ci#ifdef CONFIG_BOOKE 10362306a36Sopenharmony_ci uint32_t dbcr2; 10462306a36Sopenharmony_ci#endif 10562306a36Sopenharmony_ci /* 10662306a36Sopenharmony_ci * The stored value of the DBSR register will be the value at the 10762306a36Sopenharmony_ci * last debug interrupt. This register can only be read from the 10862306a36Sopenharmony_ci * user (will never be written to) and has value while helping to 10962306a36Sopenharmony_ci * describe the reason for the last debug trap. Torez 11062306a36Sopenharmony_ci */ 11162306a36Sopenharmony_ci uint32_t dbsr; 11262306a36Sopenharmony_ci /* 11362306a36Sopenharmony_ci * The following will contain addresses used by debug applications 11462306a36Sopenharmony_ci * to help trace and trap on particular address locations. 11562306a36Sopenharmony_ci * The bits in the Debug Control Registers above help define which 11662306a36Sopenharmony_ci * of the following registers will contain valid data and/or addresses. 11762306a36Sopenharmony_ci */ 11862306a36Sopenharmony_ci unsigned long iac1; 11962306a36Sopenharmony_ci unsigned long iac2; 12062306a36Sopenharmony_ci#if CONFIG_PPC_ADV_DEBUG_IACS > 2 12162306a36Sopenharmony_ci unsigned long iac3; 12262306a36Sopenharmony_ci unsigned long iac4; 12362306a36Sopenharmony_ci#endif 12462306a36Sopenharmony_ci unsigned long dac1; 12562306a36Sopenharmony_ci unsigned long dac2; 12662306a36Sopenharmony_ci#if CONFIG_PPC_ADV_DEBUG_DVCS > 0 12762306a36Sopenharmony_ci unsigned long dvc1; 12862306a36Sopenharmony_ci unsigned long dvc2; 12962306a36Sopenharmony_ci#endif 13062306a36Sopenharmony_ci#endif 13162306a36Sopenharmony_ci}; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistruct thread_struct { 13462306a36Sopenharmony_ci unsigned long ksp; /* Kernel stack pointer */ 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci#ifdef CONFIG_PPC64 13762306a36Sopenharmony_ci unsigned long ksp_vsid; 13862306a36Sopenharmony_ci#endif 13962306a36Sopenharmony_ci struct pt_regs *regs; /* Pointer to saved register state */ 14062306a36Sopenharmony_ci#ifdef CONFIG_BOOKE 14162306a36Sopenharmony_ci /* BookE base exception scratch space; align on cacheline */ 14262306a36Sopenharmony_ci unsigned long normsave[8] ____cacheline_aligned; 14362306a36Sopenharmony_ci#endif 14462306a36Sopenharmony_ci#ifdef CONFIG_PPC32 14562306a36Sopenharmony_ci void *pgdir; /* root of page-table tree */ 14662306a36Sopenharmony_ci#ifdef CONFIG_PPC_RTAS 14762306a36Sopenharmony_ci unsigned long rtas_sp; /* stack pointer for when in RTAS */ 14862306a36Sopenharmony_ci#endif 14962306a36Sopenharmony_ci#if defined(CONFIG_PPC_BOOK3S_32) && defined(CONFIG_PPC_KUAP) 15062306a36Sopenharmony_ci unsigned long kuap; /* opened segments for user access */ 15162306a36Sopenharmony_ci#endif 15262306a36Sopenharmony_ci unsigned long srr0; 15362306a36Sopenharmony_ci unsigned long srr1; 15462306a36Sopenharmony_ci unsigned long dar; 15562306a36Sopenharmony_ci unsigned long dsisr; 15662306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_32 15762306a36Sopenharmony_ci unsigned long r0, r3, r4, r5, r6, r8, r9, r11; 15862306a36Sopenharmony_ci unsigned long lr, ctr; 15962306a36Sopenharmony_ci unsigned long sr0; 16062306a36Sopenharmony_ci#endif 16162306a36Sopenharmony_ci#endif /* CONFIG_PPC32 */ 16262306a36Sopenharmony_ci#if defined(CONFIG_BOOKE_OR_40x) && defined(CONFIG_PPC_KUAP) 16362306a36Sopenharmony_ci unsigned long pid; /* value written in PID reg. at interrupt exit */ 16462306a36Sopenharmony_ci#endif 16562306a36Sopenharmony_ci /* Debug Registers */ 16662306a36Sopenharmony_ci struct debug_reg debug; 16762306a36Sopenharmony_ci#ifdef CONFIG_PPC_FPU_REGS 16862306a36Sopenharmony_ci struct thread_fp_state fp_state; 16962306a36Sopenharmony_ci struct thread_fp_state *fp_save_area; 17062306a36Sopenharmony_ci#endif 17162306a36Sopenharmony_ci int fpexc_mode; /* floating-point exception mode */ 17262306a36Sopenharmony_ci unsigned int align_ctl; /* alignment handling control */ 17362306a36Sopenharmony_ci#ifdef CONFIG_HAVE_HW_BREAKPOINT 17462306a36Sopenharmony_ci struct perf_event *ptrace_bps[HBP_NUM_MAX]; 17562306a36Sopenharmony_ci#endif /* CONFIG_HAVE_HW_BREAKPOINT */ 17662306a36Sopenharmony_ci struct arch_hw_breakpoint hw_brk[HBP_NUM_MAX]; /* hardware breakpoint info */ 17762306a36Sopenharmony_ci unsigned long trap_nr; /* last trap # on this thread */ 17862306a36Sopenharmony_ci u8 load_slb; /* Ages out SLB preload cache entries */ 17962306a36Sopenharmony_ci u8 load_fp; 18062306a36Sopenharmony_ci#ifdef CONFIG_ALTIVEC 18162306a36Sopenharmony_ci u8 load_vec; 18262306a36Sopenharmony_ci struct thread_vr_state vr_state; 18362306a36Sopenharmony_ci struct thread_vr_state *vr_save_area; 18462306a36Sopenharmony_ci unsigned long vrsave; 18562306a36Sopenharmony_ci int used_vr; /* set if process has used altivec */ 18662306a36Sopenharmony_ci#endif /* CONFIG_ALTIVEC */ 18762306a36Sopenharmony_ci#ifdef CONFIG_VSX 18862306a36Sopenharmony_ci /* VSR status */ 18962306a36Sopenharmony_ci int used_vsr; /* set if process has used VSX */ 19062306a36Sopenharmony_ci#endif /* CONFIG_VSX */ 19162306a36Sopenharmony_ci#ifdef CONFIG_SPE 19262306a36Sopenharmony_ci struct_group(spe, 19362306a36Sopenharmony_ci unsigned long evr[32]; /* upper 32-bits of SPE regs */ 19462306a36Sopenharmony_ci u64 acc; /* Accumulator */ 19562306a36Sopenharmony_ci ); 19662306a36Sopenharmony_ci unsigned long spefscr; /* SPE & eFP status */ 19762306a36Sopenharmony_ci unsigned long spefscr_last; /* SPEFSCR value on last prctl 19862306a36Sopenharmony_ci call or trap return */ 19962306a36Sopenharmony_ci int used_spe; /* set if process has used spe */ 20062306a36Sopenharmony_ci#endif /* CONFIG_SPE */ 20162306a36Sopenharmony_ci#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 20262306a36Sopenharmony_ci u8 load_tm; 20362306a36Sopenharmony_ci u64 tm_tfhar; /* Transaction fail handler addr */ 20462306a36Sopenharmony_ci u64 tm_texasr; /* Transaction exception & summary */ 20562306a36Sopenharmony_ci u64 tm_tfiar; /* Transaction fail instr address reg */ 20662306a36Sopenharmony_ci struct pt_regs ckpt_regs; /* Checkpointed registers */ 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci unsigned long tm_tar; 20962306a36Sopenharmony_ci unsigned long tm_ppr; 21062306a36Sopenharmony_ci unsigned long tm_dscr; 21162306a36Sopenharmony_ci unsigned long tm_amr; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci /* 21462306a36Sopenharmony_ci * Checkpointed FP and VSX 0-31 register set. 21562306a36Sopenharmony_ci * 21662306a36Sopenharmony_ci * When a transaction is active/signalled/scheduled etc., *regs is the 21762306a36Sopenharmony_ci * most recent set of/speculated GPRs with ckpt_regs being the older 21862306a36Sopenharmony_ci * checkpointed regs to which we roll back if transaction aborts. 21962306a36Sopenharmony_ci * 22062306a36Sopenharmony_ci * These are analogous to how ckpt_regs and pt_regs work 22162306a36Sopenharmony_ci */ 22262306a36Sopenharmony_ci struct thread_fp_state ckfp_state; /* Checkpointed FP state */ 22362306a36Sopenharmony_ci struct thread_vr_state ckvr_state; /* Checkpointed VR state */ 22462306a36Sopenharmony_ci unsigned long ckvrsave; /* Checkpointed VRSAVE */ 22562306a36Sopenharmony_ci#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ 22662306a36Sopenharmony_ci#ifdef CONFIG_KVM_BOOK3S_32_HANDLER 22762306a36Sopenharmony_ci void* kvm_shadow_vcpu; /* KVM internal data */ 22862306a36Sopenharmony_ci#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */ 22962306a36Sopenharmony_ci#if defined(CONFIG_KVM) && defined(CONFIG_BOOKE) 23062306a36Sopenharmony_ci struct kvm_vcpu *kvm_vcpu; 23162306a36Sopenharmony_ci#endif 23262306a36Sopenharmony_ci#ifdef CONFIG_PPC64 23362306a36Sopenharmony_ci unsigned long dscr; 23462306a36Sopenharmony_ci unsigned long fscr; 23562306a36Sopenharmony_ci /* 23662306a36Sopenharmony_ci * This member element dscr_inherit indicates that the process 23762306a36Sopenharmony_ci * has explicitly attempted and changed the DSCR register value 23862306a36Sopenharmony_ci * for itself. Hence kernel wont use the default CPU DSCR value 23962306a36Sopenharmony_ci * contained in the PACA structure anymore during process context 24062306a36Sopenharmony_ci * switch. Once this variable is set, this behaviour will also be 24162306a36Sopenharmony_ci * inherited to all the children of this process from that point 24262306a36Sopenharmony_ci * onwards. 24362306a36Sopenharmony_ci */ 24462306a36Sopenharmony_ci int dscr_inherit; 24562306a36Sopenharmony_ci unsigned long tidr; 24662306a36Sopenharmony_ci#endif 24762306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64 24862306a36Sopenharmony_ci unsigned long tar; 24962306a36Sopenharmony_ci unsigned long ebbrr; 25062306a36Sopenharmony_ci unsigned long ebbhr; 25162306a36Sopenharmony_ci unsigned long bescr; 25262306a36Sopenharmony_ci unsigned long siar; 25362306a36Sopenharmony_ci unsigned long sdar; 25462306a36Sopenharmony_ci unsigned long sier; 25562306a36Sopenharmony_ci unsigned long mmcr2; 25662306a36Sopenharmony_ci unsigned mmcr0; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci unsigned used_ebb; 25962306a36Sopenharmony_ci unsigned long mmcr3; 26062306a36Sopenharmony_ci unsigned long sier2; 26162306a36Sopenharmony_ci unsigned long sier3; 26262306a36Sopenharmony_ci unsigned long hashkeyr; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci#endif 26562306a36Sopenharmony_ci}; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci#define ARCH_MIN_TASKALIGN 16 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci#define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack) 27062306a36Sopenharmony_ci#define INIT_SP_LIMIT ((unsigned long)&init_stack) 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci#ifdef CONFIG_SPE 27362306a36Sopenharmony_ci#define SPEFSCR_INIT \ 27462306a36Sopenharmony_ci .spefscr = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE, \ 27562306a36Sopenharmony_ci .spefscr_last = SPEFSCR_FINVE | SPEFSCR_FDBZE | SPEFSCR_FUNFE | SPEFSCR_FOVFE, 27662306a36Sopenharmony_ci#else 27762306a36Sopenharmony_ci#define SPEFSCR_INIT 27862306a36Sopenharmony_ci#endif 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_32 28162306a36Sopenharmony_ci#define SR0_INIT .sr0 = IS_ENABLED(CONFIG_PPC_KUEP) ? SR_NX : 0, 28262306a36Sopenharmony_ci#else 28362306a36Sopenharmony_ci#define SR0_INIT 28462306a36Sopenharmony_ci#endif 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci#if defined(CONFIG_PPC_BOOK3S_32) && defined(CONFIG_PPC_KUAP) 28762306a36Sopenharmony_ci#define INIT_THREAD { \ 28862306a36Sopenharmony_ci .ksp = INIT_SP, \ 28962306a36Sopenharmony_ci .pgdir = swapper_pg_dir, \ 29062306a36Sopenharmony_ci .kuap = ~0UL, /* KUAP_NONE */ \ 29162306a36Sopenharmony_ci .fpexc_mode = MSR_FE0 | MSR_FE1, \ 29262306a36Sopenharmony_ci SPEFSCR_INIT \ 29362306a36Sopenharmony_ci SR0_INIT \ 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci#elif defined(CONFIG_PPC32) 29662306a36Sopenharmony_ci#define INIT_THREAD { \ 29762306a36Sopenharmony_ci .ksp = INIT_SP, \ 29862306a36Sopenharmony_ci .pgdir = swapper_pg_dir, \ 29962306a36Sopenharmony_ci .fpexc_mode = MSR_FE0 | MSR_FE1, \ 30062306a36Sopenharmony_ci SPEFSCR_INIT \ 30162306a36Sopenharmony_ci SR0_INIT \ 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci#else 30462306a36Sopenharmony_ci#define INIT_THREAD { \ 30562306a36Sopenharmony_ci .ksp = INIT_SP, \ 30662306a36Sopenharmony_ci .fpexc_mode = 0, \ 30762306a36Sopenharmony_ci} 30862306a36Sopenharmony_ci#endif 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci#define task_pt_regs(tsk) ((tsk)->thread.regs) 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ciunsigned long __get_wchan(struct task_struct *p); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) 31562306a36Sopenharmony_ci#define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0) 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci/* Get/set floating-point exception mode */ 31862306a36Sopenharmony_ci#define GET_FPEXC_CTL(tsk, adr) get_fpexc_mode((tsk), (adr)) 31962306a36Sopenharmony_ci#define SET_FPEXC_CTL(tsk, val) set_fpexc_mode((tsk), (val)) 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ciextern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr); 32262306a36Sopenharmony_ciextern int set_fpexc_mode(struct task_struct *tsk, unsigned int val); 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci#define GET_ENDIAN(tsk, adr) get_endian((tsk), (adr)) 32562306a36Sopenharmony_ci#define SET_ENDIAN(tsk, val) set_endian((tsk), (val)) 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ciextern int get_endian(struct task_struct *tsk, unsigned long adr); 32862306a36Sopenharmony_ciextern int set_endian(struct task_struct *tsk, unsigned int val); 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci#define GET_UNALIGN_CTL(tsk, adr) get_unalign_ctl((tsk), (adr)) 33162306a36Sopenharmony_ci#define SET_UNALIGN_CTL(tsk, val) set_unalign_ctl((tsk), (val)) 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ciextern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr); 33462306a36Sopenharmony_ciextern int set_unalign_ctl(struct task_struct *tsk, unsigned int val); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ciextern void load_fp_state(struct thread_fp_state *fp); 33762306a36Sopenharmony_ciextern void store_fp_state(struct thread_fp_state *fp); 33862306a36Sopenharmony_ciextern void load_vr_state(struct thread_vr_state *vr); 33962306a36Sopenharmony_ciextern void store_vr_state(struct thread_vr_state *vr); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_cistatic inline unsigned int __unpack_fe01(unsigned long msr_bits) 34262306a36Sopenharmony_ci{ 34362306a36Sopenharmony_ci return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8); 34462306a36Sopenharmony_ci} 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_cistatic inline unsigned long __pack_fe01(unsigned int fpmode) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci return ((fpmode << 10) & MSR_FE0) | ((fpmode << 8) & MSR_FE1); 34962306a36Sopenharmony_ci} 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci#ifdef CONFIG_PPC64 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci#define spin_begin() \ 35462306a36Sopenharmony_ci asm volatile(ASM_FTR_IFCLR( \ 35562306a36Sopenharmony_ci "or 1,1,1", /* HMT_LOW */ \ 35662306a36Sopenharmony_ci "nop", /* v3.1 uses pause_short in cpu_relax instead */ \ 35762306a36Sopenharmony_ci %0) :: "i" (CPU_FTR_ARCH_31) : "memory") 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci#define spin_cpu_relax() \ 36062306a36Sopenharmony_ci asm volatile(ASM_FTR_IFCLR( \ 36162306a36Sopenharmony_ci "nop", /* Before v3.1 use priority nops in spin_begin/end */ \ 36262306a36Sopenharmony_ci PPC_WAIT(2, 0), /* aka pause_short */ \ 36362306a36Sopenharmony_ci %0) :: "i" (CPU_FTR_ARCH_31) : "memory") 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci#define spin_end() \ 36662306a36Sopenharmony_ci asm volatile(ASM_FTR_IFCLR( \ 36762306a36Sopenharmony_ci "or 2,2,2", /* HMT_MEDIUM */ \ 36862306a36Sopenharmony_ci "nop", \ 36962306a36Sopenharmony_ci %0) :: "i" (CPU_FTR_ARCH_31) : "memory") 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci#endif 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci/* 37462306a36Sopenharmony_ci * Check that a certain kernel stack pointer is a valid (minimum sized) 37562306a36Sopenharmony_ci * stack frame in task_struct p. 37662306a36Sopenharmony_ci */ 37762306a36Sopenharmony_ciint validate_sp(unsigned long sp, struct task_struct *p); 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci/* 38062306a36Sopenharmony_ci * validate the stack frame of a particular minimum size, used for when we are 38162306a36Sopenharmony_ci * looking at a certain object in the stack beyond the minimum. 38262306a36Sopenharmony_ci */ 38362306a36Sopenharmony_ciint validate_sp_size(unsigned long sp, struct task_struct *p, 38462306a36Sopenharmony_ci unsigned long nbytes); 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci/* 38762306a36Sopenharmony_ci * Prefetch macros. 38862306a36Sopenharmony_ci */ 38962306a36Sopenharmony_ci#define ARCH_HAS_PREFETCH 39062306a36Sopenharmony_ci#define ARCH_HAS_PREFETCHW 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_cistatic inline void prefetch(const void *x) 39362306a36Sopenharmony_ci{ 39462306a36Sopenharmony_ci if (unlikely(!x)) 39562306a36Sopenharmony_ci return; 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci __asm__ __volatile__ ("dcbt 0,%0" : : "r" (x)); 39862306a36Sopenharmony_ci} 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_cistatic inline void prefetchw(const void *x) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci if (unlikely(!x)) 40362306a36Sopenharmony_ci return; 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (x)); 40662306a36Sopenharmony_ci} 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci/* asm stubs */ 40962306a36Sopenharmony_ciextern unsigned long isa300_idle_stop_noloss(unsigned long psscr_val); 41062306a36Sopenharmony_ciextern unsigned long isa300_idle_stop_mayloss(unsigned long psscr_val); 41162306a36Sopenharmony_ciextern unsigned long isa206_idle_insn_mayloss(unsigned long type); 41262306a36Sopenharmony_ci#ifdef CONFIG_PPC_970_NAP 41362306a36Sopenharmony_ciextern void power4_idle_nap(void); 41462306a36Sopenharmony_civoid power4_idle_nap_return(void); 41562306a36Sopenharmony_ci#endif 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ciextern unsigned long cpuidle_disable; 41862306a36Sopenharmony_cienum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ciextern int powersave_nap; /* set if nap mode can be used in idle loop */ 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ciextern void power7_idle_type(unsigned long type); 42362306a36Sopenharmony_ciextern void arch300_idle_type(unsigned long stop_psscr_val, 42462306a36Sopenharmony_ci unsigned long stop_psscr_mask); 42562306a36Sopenharmony_civoid pnv_power9_force_smt4_catch(void); 42662306a36Sopenharmony_civoid pnv_power9_force_smt4_release(void); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ciextern int fix_alignment(struct pt_regs *); 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci#ifdef CONFIG_PPC64 43162306a36Sopenharmony_ci/* 43262306a36Sopenharmony_ci * We handle most unaligned accesses in hardware. On the other hand 43362306a36Sopenharmony_ci * unaligned DMA can be very expensive on some ppc64 IO chips (it does 43462306a36Sopenharmony_ci * powers of 2 writes until it reaches sufficient alignment). 43562306a36Sopenharmony_ci * 43662306a36Sopenharmony_ci * Based on this we disable the IP header alignment in network drivers. 43762306a36Sopenharmony_ci */ 43862306a36Sopenharmony_ci#define NET_IP_ALIGN 0 43962306a36Sopenharmony_ci#endif 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ciint do_mathemu(struct pt_regs *regs); 44262306a36Sopenharmony_ciint do_spe_mathemu(struct pt_regs *regs); 44362306a36Sopenharmony_ciint speround_handler(struct pt_regs *regs); 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci/* VMX copying */ 44662306a36Sopenharmony_ciint enter_vmx_usercopy(void); 44762306a36Sopenharmony_ciint exit_vmx_usercopy(void); 44862306a36Sopenharmony_ciint enter_vmx_ops(void); 44962306a36Sopenharmony_civoid *exit_vmx_ops(void *dest); 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci#endif /* __KERNEL__ */ 45262306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */ 45362306a36Sopenharmony_ci#endif /* _ASM_POWERPC_PROCESSOR_H */ 454