xref: /freebsd/sys/arm64/vmm/arm64.h (revision 8aac90f18aef7c9eea906c3ff9a001ca7b94f375)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (C) 2015 Mihai Carabas <mihai.carabas@gmail.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 #ifndef _VMM_ARM64_H_
29 #define _VMM_ARM64_H_
30 
31 #include <machine/reg.h>
32 #include <machine/hypervisor.h>
33 #include <machine/pcpu.h>
34 
35 #include "mmu.h"
36 #include "io/vgic_v3.h"
37 #include "io/vtimer.h"
38 
39 struct vgic_v3;
40 struct vgic_v3_cpu;
41 
42 struct hypctx {
43 	struct trapframe tf;
44 
45 	/*
46 	 * EL1 control registers.
47 	 */
48 	uint64_t	elr_el1;	/* Exception Link Register */
49 	uint64_t	sp_el0;		/* Stack pointer */
50 	uint64_t	tpidr_el0;	/* EL0 Software ID Register */
51 	uint64_t	tpidrro_el0;	/* Read-only Thread ID Register */
52 	uint64_t	tpidr_el1;	/* EL1 Software ID Register */
53 	uint64_t	vbar_el1;	/* Vector Base Address Register */
54 
55 	uint64_t	actlr_el1;	/* Auxiliary Control Register */
56 	uint64_t	afsr0_el1;	/* Auxiliary Fault Status Register 0 */
57 	uint64_t	afsr1_el1;	/* Auxiliary Fault Status Register 1 */
58 	uint64_t	amair_el1;	/* Auxiliary Memory Attribute Indirection Register */
59 	uint64_t	contextidr_el1;	/* Current Process Identifier */
60 	uint64_t	cpacr_el1;	/* Architectural Feature Access Control Register */
61 	uint64_t	csselr_el1;	/* Cache Size Selection Register */
62 	uint64_t	esr_el1;	/* Exception Syndrome Register */
63 	uint64_t	far_el1;	/* Fault Address Register */
64 	uint64_t	mair_el1;	/* Memory Attribute Indirection Register */
65 	uint64_t	mdccint_el1;	/* Monitor DCC Interrupt Enable Register */
66 	uint64_t	mdscr_el1;	/* Monitor Debug System Control Register */
67 	uint64_t	par_el1;	/* Physical Address Register */
68 	uint64_t	sctlr_el1;	/* System Control Register */
69 	uint64_t	tcr_el1;	/* Translation Control Register */
70 	uint64_t	tcr2_el1;	/* Translation Control Register 2 */
71 	uint64_t	ttbr0_el1;	/* Translation Table Base Register 0 */
72 	uint64_t	ttbr1_el1;	/* Translation Table Base Register 1 */
73 	uint64_t	spsr_el1;	/* Saved Program Status Register */
74 
75 	uint64_t	pmcr_el0;	/* Performance Monitors Control Register */
76 	uint64_t	pmccntr_el0;
77 	uint64_t	pmccfiltr_el0;
78 	uint64_t	pmcntenset_el0;
79 	uint64_t	pmintenset_el1;
80 	uint64_t	pmovsset_el0;
81 	uint64_t	pmselr_el0;
82 	uint64_t	pmuserenr_el0;
83 	uint64_t	pmevcntr_el0[31];
84 	uint64_t	pmevtyper_el0[31];
85 
86 	uint64_t	dbgbcr_el1[16];	/* Debug Breakpoint Control Registers */
87 	uint64_t	dbgbvr_el1[16];	/* Debug Breakpoint Value Registers */
88 	uint64_t	dbgwcr_el1[16];	/* Debug Watchpoint Control Registers */
89 	uint64_t	dbgwvr_el1[16];	/* Debug Watchpoint Value Registers */
90 
91 	/* EL2 control registers */
92 	uint64_t	cptr_el2;	/* Architectural Feature Trap Register */
93 	uint64_t	hcr_el2;	/* Hypervisor Configuration Register */
94 	uint64_t	mdcr_el2;	/* Monitor Debug Configuration Register */
95 	uint64_t	vpidr_el2;	/* Virtualization Processor ID Register */
96 	uint64_t	vmpidr_el2;	/* Virtualization Multiprocessor ID Register */
97 	uint64_t	el2_addr;	/* The address of this in el2 space */
98 	struct hyp	*hyp;
99 	struct vcpu	*vcpu;
100 	struct {
101 		uint64_t	far_el2;	/* Fault Address Register */
102 		uint64_t	hpfar_el2;	/* Hypervisor IPA Fault Address Register */
103 	} exit_info;
104 
105 	struct vtimer_cpu 	vtimer_cpu;
106 
107 	struct vgic_v3_regs	vgic_v3_regs;
108 	struct vgic_v3_cpu	*vgic_cpu;
109 	bool			has_exception;
110 };
111 
112 struct hyp {
113 	struct vm	*vm;
114 	struct vtimer	vtimer;
115 	uint64_t	vmid_generation;
116 	uint64_t	vttbr_el2;
117 	uint64_t	el2_addr;	/* The address of this in el2 space */
118 	bool		vgic_attached;
119 	struct vgic_v3	*vgic;
120 	struct hypctx	*ctx[];
121 };
122 
123 #define	DEFINE_VMMOPS_IFUNC(ret_type, opname, args)			\
124 	ret_type vmmops_##opname args;
125 
126 DEFINE_VMMOPS_IFUNC(int, modinit, (int ipinum))
127 DEFINE_VMMOPS_IFUNC(int, modcleanup, (void))
128 DEFINE_VMMOPS_IFUNC(void *, init, (struct vm *vm, struct pmap *pmap))
129 DEFINE_VMMOPS_IFUNC(int, gla2gpa, (void *vcpui, struct vm_guest_paging *paging,
130     uint64_t gla, int prot, uint64_t *gpa, int *is_fault))
131 DEFINE_VMMOPS_IFUNC(int, run, (void *vcpui, register_t pc, struct pmap *pmap,
132     struct vm_eventinfo *info))
133 DEFINE_VMMOPS_IFUNC(void, cleanup, (void *vmi))
134 DEFINE_VMMOPS_IFUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu,
135     int vcpu_id))
136 DEFINE_VMMOPS_IFUNC(void, vcpu_cleanup, (void *vcpui))
137 DEFINE_VMMOPS_IFUNC(int, exception, (void *vcpui, uint64_t esr, uint64_t far))
138 DEFINE_VMMOPS_IFUNC(int, getreg, (void *vcpui, int num, uint64_t *retval))
139 DEFINE_VMMOPS_IFUNC(int, setreg, (void *vcpui, int num, uint64_t val))
140 DEFINE_VMMOPS_IFUNC(int, getcap, (void *vcpui, int num, int *retval))
141 DEFINE_VMMOPS_IFUNC(int, setcap, (void *vcpui, int num, int val))
142 DEFINE_VMMOPS_IFUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min,
143     vm_offset_t max))
144 DEFINE_VMMOPS_IFUNC(void, vmspace_free, (struct vmspace *vmspace))
145 #ifdef notyet
146 #ifdef BHYVE_SNAPSHOT
147 DEFINE_VMMOPS_IFUNC(int, snapshot, (void *vmi, struct vm_snapshot_meta *meta))
148 DEFINE_VMMOPS_IFUNC(int, vcpu_snapshot, (void *vcpui,
149     struct vm_snapshot_meta *meta))
150 DEFINE_VMMOPS_IFUNC(int, restore_tsc, (void *vcpui, uint64_t now))
151 #endif
152 #endif
153 
154 uint64_t	vmm_call_hyp(uint64_t, ...);
155 
156 #if 0
157 #define	eprintf(fmt, ...)	printf("%s:%d " fmt, __func__, __LINE__, ##__VA_ARGS__)
158 #else
159 #define	eprintf(fmt, ...)	do {} while(0)
160 #endif
161 
162 struct hypctx *arm64_get_active_vcpu(void);
163 void raise_data_insn_abort(struct hypctx *, uint64_t, bool, int);
164 
165 #endif /* !_VMM_ARM64_H_ */
166