1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Copyright (c) 2023 MediaTek Inc.
4 */
5
6 #ifndef __GZVM_ARCH_COMMON_H__
7 #define __GZVM_ARCH_COMMON_H__
8
9 #include <linux/arm-smccc.h>
10 #include <linux/clocksource.h>
11
12 enum {
13 GZVM_FUNC_CREATE_VM = 0,
14 GZVM_FUNC_DESTROY_VM = 1,
15 GZVM_FUNC_CREATE_VCPU = 2,
16 GZVM_FUNC_DESTROY_VCPU = 3,
17 GZVM_FUNC_SET_MEMREGION = 4,
18 GZVM_FUNC_RUN = 5,
19 GZVM_FUNC_GET_ONE_REG = 8,
20 GZVM_FUNC_SET_ONE_REG = 9,
21 GZVM_FUNC_IRQ_LINE = 10,
22 GZVM_FUNC_CREATE_DEVICE = 11,
23 GZVM_FUNC_PROBE = 12,
24 GZVM_FUNC_ENABLE_CAP = 13,
25 GZVM_FUNC_INFORM_EXIT = 14,
26 GZVM_FUNC_MEMREGION_PURPOSE = 15,
27 GZVM_FUNC_SET_DTB_CONFIG = 16,
28 GZVM_FUNC_MAP_GUEST = 17,
29 GZVM_FUNC_MAP_GUEST_BLOCK = 18,
30 GZVM_FUNC_GET_STATISTICS = 19,
31 NR_GZVM_FUNC,
32 };
33
34 #define SMC_ENTITY_MTK 59
35 #define GZVM_FUNCID_START (0x1000)
36 #define GZVM_HCALL_ID(func) \
37 ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
38 SMC_ENTITY_MTK, (GZVM_FUNCID_START + (func)))
39
40 #define MT_HVC_GZVM_CREATE_VM GZVM_HCALL_ID(GZVM_FUNC_CREATE_VM)
41 #define MT_HVC_GZVM_DESTROY_VM GZVM_HCALL_ID(GZVM_FUNC_DESTROY_VM)
42 #define MT_HVC_GZVM_CREATE_VCPU GZVM_HCALL_ID(GZVM_FUNC_CREATE_VCPU)
43 #define MT_HVC_GZVM_DESTROY_VCPU GZVM_HCALL_ID(GZVM_FUNC_DESTROY_VCPU)
44 #define MT_HVC_GZVM_SET_MEMREGION GZVM_HCALL_ID(GZVM_FUNC_SET_MEMREGION)
45 #define MT_HVC_GZVM_RUN GZVM_HCALL_ID(GZVM_FUNC_RUN)
46 #define MT_HVC_GZVM_GET_ONE_REG GZVM_HCALL_ID(GZVM_FUNC_GET_ONE_REG)
47 #define MT_HVC_GZVM_SET_ONE_REG GZVM_HCALL_ID(GZVM_FUNC_SET_ONE_REG)
48 #define MT_HVC_GZVM_IRQ_LINE GZVM_HCALL_ID(GZVM_FUNC_IRQ_LINE)
49 #define MT_HVC_GZVM_CREATE_DEVICE GZVM_HCALL_ID(GZVM_FUNC_CREATE_DEVICE)
50 #define MT_HVC_GZVM_PROBE GZVM_HCALL_ID(GZVM_FUNC_PROBE)
51 #define MT_HVC_GZVM_ENABLE_CAP GZVM_HCALL_ID(GZVM_FUNC_ENABLE_CAP)
52 #define MT_HVC_GZVM_INFORM_EXIT GZVM_HCALL_ID(GZVM_FUNC_INFORM_EXIT)
53 #define MT_HVC_GZVM_MEMREGION_PURPOSE GZVM_HCALL_ID(GZVM_FUNC_MEMREGION_PURPOSE)
54 #define MT_HVC_GZVM_SET_DTB_CONFIG GZVM_HCALL_ID(GZVM_FUNC_SET_DTB_CONFIG)
55 #define MT_HVC_GZVM_MAP_GUEST GZVM_HCALL_ID(GZVM_FUNC_MAP_GUEST)
56 #define MT_HVC_GZVM_MAP_GUEST_BLOCK GZVM_HCALL_ID(GZVM_FUNC_MAP_GUEST_BLOCK)
57 #define MT_HVC_GZVM_GET_STATISTICS GZVM_HCALL_ID(GZVM_FUNC_GET_STATISTICS)
58
59 #define GIC_V3_NR_LRS 16
60
61 /**
62 * gzvm_hypcall_wrapper() - the wrapper for hvc calls
63 * @a0: argument passed in registers 0
64 * @a1: argument passed in registers 1
65 * @a2: argument passed in registers 2
66 * @a3: argument passed in registers 3
67 * @a4: argument passed in registers 4
68 * @a5: argument passed in registers 5
69 * @a6: argument passed in registers 6
70 * @a7: argument passed in registers 7
71 * @res: result values from registers 0 to 3
72 *
73 * Return: The wrapper helps caller to convert geniezone errno to Linux errno.
74 */
75 int gzvm_hypcall_wrapper(unsigned long a0, unsigned long a1,
76 unsigned long a2, unsigned long a3,
77 unsigned long a4, unsigned long a5,
78 unsigned long a6, unsigned long a7,
79 struct arm_smccc_res *res);
80
81 /**
82 * struct gzvm_vcpu_hwstate: Sync architecture state back to host for handling
83 * @nr_lrs: The available LRs(list registers) in Soc.
84 * @__pad: add an explicit '__u32 __pad;' in the middle to make it clear
85 * what the actual layout is.
86 * @lr: The array of LRs(list registers).
87 * @vtimer_offset: The offset maintained by hypervisor that is host cycle count
88 * when guest VM startup.
89 * @vtimer_delay: The remaining time before the next timer tick is triggered
90 * while the VM is running.
91 * @vtimer_migrate: Indicates whether the guest virtual timer needs to be
92 * migrated to the host software timer.
93 *
94 * - Keep the same layout of hypervisor data struct.
95 * - Sync list registers back for acking virtual device interrupt status.
96 */
97 struct gzvm_vcpu_hwstate {
98 __le32 nr_lrs;
99 __le32 __pad;
100 __le64 lr[GIC_V3_NR_LRS];
101 __le64 vtimer_offset;
102 __le64 vtimer_delay;
103 __le32 vtimer_migrate;
104 };
105
106 struct timecycle {
107 u32 mult;
108 u32 shift;
109 };
110
111 u32 gzvm_vtimer_get_clock_mult(void);
112 u32 gzvm_vtimer_get_clock_shift(void);
113
114 static inline unsigned int
assemble_vm_vcpu_tuple(u16 vmid,u16 vcpuid)115 assemble_vm_vcpu_tuple(u16 vmid, u16 vcpuid)
116 {
117 return ((unsigned int)vmid << 16 | vcpuid);
118 }
119
120 #endif /* __GZVM_ARCH_COMMON_H__ */
121