162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci#ifndef _ASM_POWERPC_SWITCH_TO_H
662306a36Sopenharmony_ci#define _ASM_POWERPC_SWITCH_TO_H
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/sched.h>
962306a36Sopenharmony_ci#include <asm/reg.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistruct thread_struct;
1262306a36Sopenharmony_cistruct task_struct;
1362306a36Sopenharmony_cistruct pt_regs;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ciextern struct task_struct *__switch_to(struct task_struct *,
1662306a36Sopenharmony_ci	struct task_struct *);
1762306a36Sopenharmony_ci#define switch_to(prev, next, last)	((last) = __switch_to((prev), (next)))
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciextern struct task_struct *_switch(struct thread_struct *prev,
2062306a36Sopenharmony_ci				   struct thread_struct *next);
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ciextern void switch_booke_debug_regs(struct debug_reg *new_debug);
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciextern int emulate_altivec(struct pt_regs *);
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64
2762306a36Sopenharmony_civoid restore_math(struct pt_regs *regs);
2862306a36Sopenharmony_ci#else
2962306a36Sopenharmony_cistatic inline void restore_math(struct pt_regs *regs)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci}
3262306a36Sopenharmony_ci#endif
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_civoid restore_tm_state(struct pt_regs *regs);
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ciextern void flush_all_to_thread(struct task_struct *);
3762306a36Sopenharmony_ciextern void giveup_all(struct task_struct *);
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#ifdef CONFIG_PPC_FPU
4062306a36Sopenharmony_ciextern void enable_kernel_fp(void);
4162306a36Sopenharmony_ciextern void flush_fp_to_thread(struct task_struct *);
4262306a36Sopenharmony_ciextern void giveup_fpu(struct task_struct *);
4362306a36Sopenharmony_ciextern void save_fpu(struct task_struct *);
4462306a36Sopenharmony_cistatic inline void disable_kernel_fp(void)
4562306a36Sopenharmony_ci{
4662306a36Sopenharmony_ci	msr_check_and_clear(MSR_FP);
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ci#else
4962306a36Sopenharmony_cistatic inline void save_fpu(struct task_struct *t) { }
5062306a36Sopenharmony_cistatic inline void flush_fp_to_thread(struct task_struct *t) { }
5162306a36Sopenharmony_ci#endif
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#ifdef CONFIG_ALTIVEC
5462306a36Sopenharmony_ciextern void enable_kernel_altivec(void);
5562306a36Sopenharmony_ciextern void flush_altivec_to_thread(struct task_struct *);
5662306a36Sopenharmony_ciextern void giveup_altivec(struct task_struct *);
5762306a36Sopenharmony_ciextern void save_altivec(struct task_struct *);
5862306a36Sopenharmony_cistatic inline void disable_kernel_altivec(void)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	msr_check_and_clear(MSR_VEC);
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci#else
6362306a36Sopenharmony_cistatic inline void save_altivec(struct task_struct *t) { }
6462306a36Sopenharmony_cistatic inline void __giveup_altivec(struct task_struct *t) { }
6562306a36Sopenharmony_cistatic inline void enable_kernel_altivec(void)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	BUILD_BUG();
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic inline void disable_kernel_altivec(void)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	BUILD_BUG();
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci#endif
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#ifdef CONFIG_VSX
7762306a36Sopenharmony_ciextern void enable_kernel_vsx(void);
7862306a36Sopenharmony_ciextern void flush_vsx_to_thread(struct task_struct *);
7962306a36Sopenharmony_cistatic inline void disable_kernel_vsx(void)
8062306a36Sopenharmony_ci{
8162306a36Sopenharmony_ci	msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX);
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ci#else
8462306a36Sopenharmony_cistatic inline void enable_kernel_vsx(void)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	BUILD_BUG();
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistatic inline void disable_kernel_vsx(void)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	BUILD_BUG();
9262306a36Sopenharmony_ci}
9362306a36Sopenharmony_ci#endif
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci#ifdef CONFIG_SPE
9662306a36Sopenharmony_ciextern void enable_kernel_spe(void);
9762306a36Sopenharmony_ciextern void flush_spe_to_thread(struct task_struct *);
9862306a36Sopenharmony_ciextern void giveup_spe(struct task_struct *);
9962306a36Sopenharmony_ciextern void __giveup_spe(struct task_struct *);
10062306a36Sopenharmony_cistatic inline void disable_kernel_spe(void)
10162306a36Sopenharmony_ci{
10262306a36Sopenharmony_ci	msr_check_and_clear(MSR_SPE);
10362306a36Sopenharmony_ci}
10462306a36Sopenharmony_ci#else
10562306a36Sopenharmony_cistatic inline void __giveup_spe(struct task_struct *t) { }
10662306a36Sopenharmony_ci#endif
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cistatic inline void clear_task_ebb(struct task_struct *t)
10962306a36Sopenharmony_ci{
11062306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64
11162306a36Sopenharmony_ci    /* EBB perf events are not inherited, so clear all EBB state. */
11262306a36Sopenharmony_ci    t->thread.ebbrr = 0;
11362306a36Sopenharmony_ci    t->thread.ebbhr = 0;
11462306a36Sopenharmony_ci    t->thread.bescr = 0;
11562306a36Sopenharmony_ci    t->thread.mmcr2 = 0;
11662306a36Sopenharmony_ci    t->thread.mmcr0 = 0;
11762306a36Sopenharmony_ci    t->thread.siar = 0;
11862306a36Sopenharmony_ci    t->thread.sdar = 0;
11962306a36Sopenharmony_ci    t->thread.sier = 0;
12062306a36Sopenharmony_ci    t->thread.used_ebb = 0;
12162306a36Sopenharmony_ci#endif
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_civoid kvmppc_save_user_regs(void);
12562306a36Sopenharmony_civoid kvmppc_save_current_sprs(void);
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ciextern int set_thread_tidr(struct task_struct *t);
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci#endif /* _ASM_POWERPC_SWITCH_TO_H */
130