xref: /openbmc/linux/tools/testing/selftests/kvm/include/aarch64/processor.h (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
10bec140fSAndrew Jones /* SPDX-License-Identifier: GPL-2.0 */
20bec140fSAndrew Jones /*
30bec140fSAndrew Jones  * AArch64 processor specific defines
40bec140fSAndrew Jones  *
50bec140fSAndrew Jones  * Copyright (C) 2018, Red Hat, Inc.
60bec140fSAndrew Jones  */
70bec140fSAndrew Jones #ifndef SELFTEST_KVM_PROCESSOR_H
80bec140fSAndrew Jones #define SELFTEST_KVM_PROCESSOR_H
90bec140fSAndrew Jones 
100bec140fSAndrew Jones #include "kvm_util.h"
11e3db7579SRicardo Koller #include <linux/stringify.h>
1288ec7e25SRaghavendra Rao Ananta #include <linux/types.h>
13272a067dSRaghavendra Rao Ananta #include <asm/sysreg.h>
140bec140fSAndrew Jones 
150bec140fSAndrew Jones 
160bec140fSAndrew Jones #define ARM64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
170bec140fSAndrew Jones 			   KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
180bec140fSAndrew Jones 
19b3c79c61SRaghavendra Rao Ananta /*
20b3c79c61SRaghavendra Rao Ananta  * KVM_ARM64_SYS_REG(sys_reg_id): Helper macro to convert
21b3c79c61SRaghavendra Rao Ananta  * SYS_* register definitions in asm/sysreg.h to use in KVM
22bfff0f60SSean Christopherson  * calls such as vcpu_get_reg() and vcpu_set_reg().
23b3c79c61SRaghavendra Rao Ananta  */
24b3c79c61SRaghavendra Rao Ananta #define KVM_ARM64_SYS_REG(sys_reg_id)			\
25b3c79c61SRaghavendra Rao Ananta 	ARM64_SYS_REG(sys_reg_Op0(sys_reg_id),		\
26b3c79c61SRaghavendra Rao Ananta 			sys_reg_Op1(sys_reg_id),	\
27b3c79c61SRaghavendra Rao Ananta 			sys_reg_CRn(sys_reg_id),	\
28b3c79c61SRaghavendra Rao Ananta 			sys_reg_CRm(sys_reg_id),	\
29b3c79c61SRaghavendra Rao Ananta 			sys_reg_Op2(sys_reg_id))
304f05223aSRicardo Koller 
310bec140fSAndrew Jones /*
320bec140fSAndrew Jones  * Default MAIR
330bec140fSAndrew Jones  *                  index   attribute
340bec140fSAndrew Jones  * DEVICE_nGnRnE      0     0000:0000
350bec140fSAndrew Jones  * DEVICE_nGnRE       1     0000:0100
360bec140fSAndrew Jones  * DEVICE_GRE         2     0000:1100
370bec140fSAndrew Jones  * NORMAL_NC          3     0100:0100
380bec140fSAndrew Jones  * NORMAL             4     1111:1111
390bec140fSAndrew Jones  * NORMAL_WT          5     1011:1011
400bec140fSAndrew Jones  */
4141f5189eSRicardo Koller 
4241f5189eSRicardo Koller /* Linux doesn't use these memory types, so let's define them. */
4341f5189eSRicardo Koller #define MAIR_ATTR_DEVICE_GRE	UL(0x0c)
4441f5189eSRicardo Koller #define MAIR_ATTR_NORMAL_WT	UL(0xbb)
4541f5189eSRicardo Koller 
4641f5189eSRicardo Koller #define MT_DEVICE_nGnRnE	0
4741f5189eSRicardo Koller #define MT_DEVICE_nGnRE		1
4841f5189eSRicardo Koller #define MT_DEVICE_GRE		2
4941f5189eSRicardo Koller #define MT_NORMAL_NC		3
5041f5189eSRicardo Koller #define MT_NORMAL		4
5141f5189eSRicardo Koller #define MT_NORMAL_WT		5
5241f5189eSRicardo Koller 
5341f5189eSRicardo Koller #define DEFAULT_MAIR_EL1							\
5441f5189eSRicardo Koller 	(MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) |		\
5541f5189eSRicardo Koller 	 MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRE, MT_DEVICE_nGnRE) |		\
5641f5189eSRicardo Koller 	 MAIR_ATTRIDX(MAIR_ATTR_DEVICE_GRE, MT_DEVICE_GRE) |			\
5741f5189eSRicardo Koller 	 MAIR_ATTRIDX(MAIR_ATTR_NORMAL_NC, MT_NORMAL_NC) |			\
5841f5189eSRicardo Koller 	 MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL) |				\
5941f5189eSRicardo Koller 	 MAIR_ATTRIDX(MAIR_ATTR_NORMAL_WT, MT_NORMAL_WT))
600bec140fSAndrew Jones 
61cb97cf95SOliver Upton #define MPIDR_HWID_BITMASK (0xff00fffffful)
62cb97cf95SOliver Upton 
63768e9a61SSean Christopherson void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init);
64f742d94fSSean Christopherson struct kvm_vcpu *aarch64_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id,
65f742d94fSSean Christopherson 				  struct kvm_vcpu_init *init, void *guest_code);
66f5dd4ccfSAndrew Jones 
67e3db7579SRicardo Koller struct ex_regs {
68e3db7579SRicardo Koller 	u64 regs[31];
69e3db7579SRicardo Koller 	u64 sp;
70e3db7579SRicardo Koller 	u64 pc;
71e3db7579SRicardo Koller 	u64 pstate;
72e3db7579SRicardo Koller };
73e3db7579SRicardo Koller 
74e3db7579SRicardo Koller #define VECTOR_NUM	16
75e3db7579SRicardo Koller 
76e3db7579SRicardo Koller enum {
77e3db7579SRicardo Koller 	VECTOR_SYNC_CURRENT_SP0,
78e3db7579SRicardo Koller 	VECTOR_IRQ_CURRENT_SP0,
79e3db7579SRicardo Koller 	VECTOR_FIQ_CURRENT_SP0,
80e3db7579SRicardo Koller 	VECTOR_ERROR_CURRENT_SP0,
81e3db7579SRicardo Koller 
82e3db7579SRicardo Koller 	VECTOR_SYNC_CURRENT,
83e3db7579SRicardo Koller 	VECTOR_IRQ_CURRENT,
84e3db7579SRicardo Koller 	VECTOR_FIQ_CURRENT,
85e3db7579SRicardo Koller 	VECTOR_ERROR_CURRENT,
86e3db7579SRicardo Koller 
87e3db7579SRicardo Koller 	VECTOR_SYNC_LOWER_64,
88e3db7579SRicardo Koller 	VECTOR_IRQ_LOWER_64,
89e3db7579SRicardo Koller 	VECTOR_FIQ_LOWER_64,
90e3db7579SRicardo Koller 	VECTOR_ERROR_LOWER_64,
91e3db7579SRicardo Koller 
92e3db7579SRicardo Koller 	VECTOR_SYNC_LOWER_32,
93e3db7579SRicardo Koller 	VECTOR_IRQ_LOWER_32,
94e3db7579SRicardo Koller 	VECTOR_FIQ_LOWER_32,
95e3db7579SRicardo Koller 	VECTOR_ERROR_LOWER_32,
96e3db7579SRicardo Koller };
97e3db7579SRicardo Koller 
98e3db7579SRicardo Koller #define VECTOR_IS_SYNC(v) ((v) == VECTOR_SYNC_CURRENT_SP0 || \
99e3db7579SRicardo Koller 			   (v) == VECTOR_SYNC_CURRENT     || \
100e3db7579SRicardo Koller 			   (v) == VECTOR_SYNC_LOWER_64    || \
101e3db7579SRicardo Koller 			   (v) == VECTOR_SYNC_LOWER_32)
102e3db7579SRicardo Koller 
103e3db7579SRicardo Koller #define ESR_EC_NUM		64
104e3db7579SRicardo Koller #define ESR_EC_SHIFT		26
105e3db7579SRicardo Koller #define ESR_EC_MASK		(ESR_EC_NUM - 1)
106e3db7579SRicardo Koller 
1074f05223aSRicardo Koller #define ESR_EC_SVC64		0x15
10835c58101SRicardo Koller #define ESR_EC_IABT		0x21
10935c58101SRicardo Koller #define ESR_EC_DABT		0x25
1104f05223aSRicardo Koller #define ESR_EC_HW_BP_CURRENT	0x31
1114f05223aSRicardo Koller #define ESR_EC_SSTEP_CURRENT	0x33
1124f05223aSRicardo Koller #define ESR_EC_WP_CURRENT	0x35
1134f05223aSRicardo Koller #define ESR_EC_BRK_INS		0x3c
1144f05223aSRicardo Koller 
11535c58101SRicardo Koller /* Access flag */
11635c58101SRicardo Koller #define PTE_AF			(1ULL << 10)
11735c58101SRicardo Koller 
11835c58101SRicardo Koller /* Access flag update enable/disable */
11935c58101SRicardo Koller #define TCR_EL1_HA		(1ULL << 39)
12035c58101SRicardo Koller 
1210303ffdbSMarc Zyngier void aarch64_get_supported_page_sizes(uint32_t ipa,
1220303ffdbSMarc Zyngier 				      bool *ps4k, bool *ps16k, bool *ps64k);
1230303ffdbSMarc Zyngier 
124e3db7579SRicardo Koller void vm_init_descriptor_tables(struct kvm_vm *vm);
125768e9a61SSean Christopherson void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu);
126e3db7579SRicardo Koller 
127e3db7579SRicardo Koller typedef void(*handler_fn)(struct ex_regs *);
128e3db7579SRicardo Koller void vm_install_exception_handler(struct kvm_vm *vm,
129e3db7579SRicardo Koller 		int vector, handler_fn handler);
130e3db7579SRicardo Koller void vm_install_sync_handler(struct kvm_vm *vm,
131e3db7579SRicardo Koller 		int vector, int ec, handler_fn handler);
132e3db7579SRicardo Koller 
133228f324dSRicardo Koller uint64_t *virt_get_pte_hva(struct kvm_vm *vm, vm_vaddr_t gva);
134228f324dSRicardo Koller 
cpu_relax(void)135740826ecSRaghavendra Rao Ananta static inline void cpu_relax(void)
136740826ecSRaghavendra Rao Ananta {
137740826ecSRaghavendra Rao Ananta 	asm volatile("yield" ::: "memory");
138740826ecSRaghavendra Rao Ananta }
139740826ecSRaghavendra Rao Ananta 
1404f05223aSRicardo Koller #define isb()		asm volatile("isb" : : : "memory")
14188ec7e25SRaghavendra Rao Ananta #define dsb(opt)	asm volatile("dsb " #opt : : : "memory")
14288ec7e25SRaghavendra Rao Ananta #define dmb(opt)	asm volatile("dmb " #opt : : : "memory")
14388ec7e25SRaghavendra Rao Ananta 
14488ec7e25SRaghavendra Rao Ananta #define dma_wmb()	dmb(oshst)
14588ec7e25SRaghavendra Rao Ananta #define __iowmb()	dma_wmb()
14688ec7e25SRaghavendra Rao Ananta 
14788ec7e25SRaghavendra Rao Ananta #define dma_rmb()	dmb(oshld)
14888ec7e25SRaghavendra Rao Ananta 
14988ec7e25SRaghavendra Rao Ananta #define __iormb(v)							\
15088ec7e25SRaghavendra Rao Ananta ({									\
15188ec7e25SRaghavendra Rao Ananta 	unsigned long tmp;						\
15288ec7e25SRaghavendra Rao Ananta 									\
15388ec7e25SRaghavendra Rao Ananta 	dma_rmb();							\
15488ec7e25SRaghavendra Rao Ananta 									\
15588ec7e25SRaghavendra Rao Ananta 	/*								\
15688ec7e25SRaghavendra Rao Ananta 	 * Courtesy of arch/arm64/include/asm/io.h:			\
15788ec7e25SRaghavendra Rao Ananta 	 * Create a dummy control dependency from the IO read to any	\
15888ec7e25SRaghavendra Rao Ananta 	 * later instructions. This ensures that a subsequent call	\
15988ec7e25SRaghavendra Rao Ananta 	 * to udelay() will be ordered due to the ISB in __delay().	\
16088ec7e25SRaghavendra Rao Ananta 	 */								\
16188ec7e25SRaghavendra Rao Ananta 	asm volatile("eor	%0, %1, %1\n"				\
16288ec7e25SRaghavendra Rao Ananta 		     "cbnz	%0, ."					\
16388ec7e25SRaghavendra Rao Ananta 		     : "=r" (tmp) : "r" ((unsigned long)(v))		\
16488ec7e25SRaghavendra Rao Ananta 		     : "memory");					\
16588ec7e25SRaghavendra Rao Ananta })
16688ec7e25SRaghavendra Rao Ananta 
__raw_writel(u32 val,volatile void * addr)16788ec7e25SRaghavendra Rao Ananta static __always_inline void __raw_writel(u32 val, volatile void *addr)
16888ec7e25SRaghavendra Rao Ananta {
16988ec7e25SRaghavendra Rao Ananta 	asm volatile("str %w0, [%1]" : : "rZ" (val), "r" (addr));
17088ec7e25SRaghavendra Rao Ananta }
17188ec7e25SRaghavendra Rao Ananta 
__raw_readl(const volatile void * addr)17288ec7e25SRaghavendra Rao Ananta static __always_inline u32 __raw_readl(const volatile void *addr)
17388ec7e25SRaghavendra Rao Ananta {
17488ec7e25SRaghavendra Rao Ananta 	u32 val;
17588ec7e25SRaghavendra Rao Ananta 	asm volatile("ldr %w0, [%1]" : "=r" (val) : "r" (addr));
17688ec7e25SRaghavendra Rao Ananta 	return val;
17788ec7e25SRaghavendra Rao Ananta }
17888ec7e25SRaghavendra Rao Ananta 
17988ec7e25SRaghavendra Rao Ananta #define writel_relaxed(v,c)	((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
18088ec7e25SRaghavendra Rao Ananta #define readl_relaxed(c)	({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; })
18188ec7e25SRaghavendra Rao Ananta 
18288ec7e25SRaghavendra Rao Ananta #define writel(v,c)		({ __iowmb(); writel_relaxed((v),(c));})
18388ec7e25SRaghavendra Rao Ananta #define readl(c)		({ u32 __v = readl_relaxed(c); __iormb(__v); __v; })
1844f05223aSRicardo Koller 
local_irq_enable(void)1855c636d58SRaghavendra Rao Ananta static inline void local_irq_enable(void)
1865c636d58SRaghavendra Rao Ananta {
1875c636d58SRaghavendra Rao Ananta 	asm volatile("msr daifclr, #3" : : : "memory");
1885c636d58SRaghavendra Rao Ananta }
1895c636d58SRaghavendra Rao Ananta 
local_irq_disable(void)1905c636d58SRaghavendra Rao Ananta static inline void local_irq_disable(void)
1915c636d58SRaghavendra Rao Ananta {
1925c636d58SRaghavendra Rao Ananta 	asm volatile("msr daifset, #3" : : : "memory");
1935c636d58SRaghavendra Rao Ananta }
1945c636d58SRaghavendra Rao Ananta 
195e918e2bcSOliver Upton /**
196e918e2bcSOliver Upton  * struct arm_smccc_res - Result from SMC/HVC call
197e918e2bcSOliver Upton  * @a0-a3 result values from registers 0 to 3
198e918e2bcSOliver Upton  */
199e918e2bcSOliver Upton struct arm_smccc_res {
200e918e2bcSOliver Upton 	unsigned long a0;
201e918e2bcSOliver Upton 	unsigned long a1;
202e918e2bcSOliver Upton 	unsigned long a2;
203e918e2bcSOliver Upton 	unsigned long a3;
204e918e2bcSOliver Upton };
205e918e2bcSOliver Upton 
206e918e2bcSOliver Upton /**
207e918e2bcSOliver Upton  * smccc_hvc - Invoke a SMCCC function using the hvc conduit
208e918e2bcSOliver Upton  * @function_id: the SMCCC function to be called
209e918e2bcSOliver Upton  * @arg0-arg6: SMCCC function arguments, corresponding to registers x1-x7
210e918e2bcSOliver Upton  * @res: pointer to write the return values from registers x0-x3
211e918e2bcSOliver Upton  *
212e918e2bcSOliver Upton  */
213e918e2bcSOliver Upton void smccc_hvc(uint32_t function_id, uint64_t arg0, uint64_t arg1,
214e918e2bcSOliver Upton 	       uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5,
215e918e2bcSOliver Upton 	       uint64_t arg6, struct arm_smccc_res *res);
216e918e2bcSOliver Upton 
217*fab19915SOliver Upton /**
218*fab19915SOliver Upton  * smccc_smc - Invoke a SMCCC function using the smc conduit
219*fab19915SOliver Upton  * @function_id: the SMCCC function to be called
220*fab19915SOliver Upton  * @arg0-arg6: SMCCC function arguments, corresponding to registers x1-x7
221*fab19915SOliver Upton  * @res: pointer to write the return values from registers x0-x3
222*fab19915SOliver Upton  *
223*fab19915SOliver Upton  */
224*fab19915SOliver Upton void smccc_smc(uint32_t function_id, uint64_t arg0, uint64_t arg1,
225*fab19915SOliver Upton 	       uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5,
226*fab19915SOliver Upton 	       uint64_t arg6, struct arm_smccc_res *res);
227*fab19915SOliver Upton 
228*fab19915SOliver Upton 
229*fab19915SOliver Upton 
23003389948SSean Christopherson uint32_t guest_get_vcpuid(void);
23103389948SSean Christopherson 
2320bec140fSAndrew Jones #endif /* SELFTEST_KVM_PROCESSOR_H */
233