162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright SUSE Linux Products GmbH 2009
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Authors: Alexander Graf <agraf@suse.de>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifndef __ASM_KVM_BOOK3S_ASM_H__
1062306a36Sopenharmony_ci#define __ASM_KVM_BOOK3S_ASM_H__
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/* XICS ICP register offsets */
1362306a36Sopenharmony_ci#define XICS_XIRR		4
1462306a36Sopenharmony_ci#define XICS_MFRR		0xc
1562306a36Sopenharmony_ci#define XICS_IPI		2	/* interrupt source # for IPIs */
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/* Maximum number of threads per physical core */
1862306a36Sopenharmony_ci#define MAX_SMT_THREADS		8
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/* Maximum number of subcores per physical core */
2162306a36Sopenharmony_ci#define MAX_SUBCORES		4
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#ifdef __ASSEMBLY__
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#ifdef CONFIG_KVM_BOOK3S_HANDLER
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#include <asm/kvm_asm.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci.macro DO_KVM intno
3062306a36Sopenharmony_ci	.if (\intno == BOOK3S_INTERRUPT_SYSTEM_RESET) || \
3162306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_MACHINE_CHECK) || \
3262306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_DATA_STORAGE) || \
3362306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_INST_STORAGE) || \
3462306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_DATA_SEGMENT) || \
3562306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_INST_SEGMENT) || \
3662306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_EXTERNAL) || \
3762306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_EXTERNAL_HV) || \
3862306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_ALIGNMENT) || \
3962306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_PROGRAM) || \
4062306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_FP_UNAVAIL) || \
4162306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_DECREMENTER) || \
4262306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_SYSCALL) || \
4362306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_TRACE) || \
4462306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_PERFMON) || \
4562306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_ALTIVEC) || \
4662306a36Sopenharmony_ci	    (\intno == BOOK3S_INTERRUPT_VSX)
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	b	kvmppc_trampoline_\intno
4962306a36Sopenharmony_cikvmppc_resume_\intno:
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	.endif
5262306a36Sopenharmony_ci.endm
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#else
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci.macro DO_KVM intno
5762306a36Sopenharmony_ci.endm
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci#endif /* CONFIG_KVM_BOOK3S_HANDLER */
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci#else  /*__ASSEMBLY__ */
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistruct kvmppc_vcore;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci/* Struct used for coordinating micro-threading (split-core) mode changes */
6662306a36Sopenharmony_cistruct kvm_split_mode {
6762306a36Sopenharmony_ci	unsigned long	rpr;
6862306a36Sopenharmony_ci	unsigned long	pmmar;
6962306a36Sopenharmony_ci	unsigned long	ldbar;
7062306a36Sopenharmony_ci	u8		subcore_size;
7162306a36Sopenharmony_ci	u8		do_nap;
7262306a36Sopenharmony_ci	u8		napped[MAX_SMT_THREADS];
7362306a36Sopenharmony_ci	struct kvmppc_vcore *vc[MAX_SUBCORES];
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci/*
7762306a36Sopenharmony_ci * This struct goes in the PACA on 64-bit processors.  It is used
7862306a36Sopenharmony_ci * to store host state that needs to be saved when we enter a guest
7962306a36Sopenharmony_ci * and restored when we exit, but isn't specific to any particular
8062306a36Sopenharmony_ci * guest or vcpu.  It also has some scratch fields used by the guest
8162306a36Sopenharmony_ci * exit code.
8262306a36Sopenharmony_ci */
8362306a36Sopenharmony_cistruct kvmppc_host_state {
8462306a36Sopenharmony_ci	ulong host_r1;
8562306a36Sopenharmony_ci	ulong host_r2;
8662306a36Sopenharmony_ci	ulong host_msr;
8762306a36Sopenharmony_ci	ulong vmhandler;
8862306a36Sopenharmony_ci	ulong scratch0;
8962306a36Sopenharmony_ci	ulong scratch1;
9062306a36Sopenharmony_ci	ulong scratch2;
9162306a36Sopenharmony_ci	u8 in_guest;
9262306a36Sopenharmony_ci	u8 restore_hid5;
9362306a36Sopenharmony_ci	u8 napping;
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
9662306a36Sopenharmony_ci	u8 hwthread_req;
9762306a36Sopenharmony_ci	u8 hwthread_state;
9862306a36Sopenharmony_ci	u8 host_ipi;
9962306a36Sopenharmony_ci	u8 ptid;		/* thread number within subcore when split */
10062306a36Sopenharmony_ci	u8 fake_suspend;
10162306a36Sopenharmony_ci	struct kvm_vcpu *kvm_vcpu;
10262306a36Sopenharmony_ci	struct kvmppc_vcore *kvm_vcore;
10362306a36Sopenharmony_ci	void __iomem *xics_phys;
10462306a36Sopenharmony_ci	void __iomem *xive_tima_phys;
10562306a36Sopenharmony_ci	void __iomem *xive_tima_virt;
10662306a36Sopenharmony_ci	u32 saved_xirr;
10762306a36Sopenharmony_ci	u64 dabr;
10862306a36Sopenharmony_ci	u64 host_mmcr[7];	/* MMCR 0,1,A, SIAR, SDAR, MMCR2, SIER */
10962306a36Sopenharmony_ci	u32 host_pmc[8];
11062306a36Sopenharmony_ci	u64 host_purr;
11162306a36Sopenharmony_ci	u64 host_spurr;
11262306a36Sopenharmony_ci	u64 host_dscr;
11362306a36Sopenharmony_ci	u64 dec_expires;
11462306a36Sopenharmony_ci	struct kvm_split_mode *kvm_split_mode;
11562306a36Sopenharmony_ci#endif
11662306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64
11762306a36Sopenharmony_ci	u64 cfar;
11862306a36Sopenharmony_ci	u64 ppr;
11962306a36Sopenharmony_ci	u64 host_fscr;
12062306a36Sopenharmony_ci#endif
12162306a36Sopenharmony_ci};
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cistruct kvmppc_book3s_shadow_vcpu {
12462306a36Sopenharmony_ci	bool in_use;
12562306a36Sopenharmony_ci	ulong gpr[14];
12662306a36Sopenharmony_ci	u32 cr;
12762306a36Sopenharmony_ci	ulong xer;
12862306a36Sopenharmony_ci	ulong ctr;
12962306a36Sopenharmony_ci	ulong lr;
13062306a36Sopenharmony_ci	ulong pc;
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	ulong shadow_srr1;
13362306a36Sopenharmony_ci	ulong fault_dar;
13462306a36Sopenharmony_ci	u32 fault_dsisr;
13562306a36Sopenharmony_ci	u32 last_inst;
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_32
13862306a36Sopenharmony_ci	u32     sr[16];			/* Guest SRs */
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	struct kvmppc_host_state hstate;
14162306a36Sopenharmony_ci#endif
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64
14462306a36Sopenharmony_ci	u8 slb_max;			/* highest used guest slb entry */
14562306a36Sopenharmony_ci	struct  {
14662306a36Sopenharmony_ci		u64     esid;
14762306a36Sopenharmony_ci		u64     vsid;
14862306a36Sopenharmony_ci	} slb[64];			/* guest SLB */
14962306a36Sopenharmony_ci	u64 shadow_fscr;
15062306a36Sopenharmony_ci#endif
15162306a36Sopenharmony_ci};
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci#endif /*__ASSEMBLY__ */
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci/* Values for kvm_state */
15662306a36Sopenharmony_ci#define KVM_HWTHREAD_IN_KERNEL	0
15762306a36Sopenharmony_ci#define KVM_HWTHREAD_IN_IDLE	1
15862306a36Sopenharmony_ci#define KVM_HWTHREAD_IN_KVM	2
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci#endif /* __ASM_KVM_BOOK3S_ASM_H__ */
161