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