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
39struct vgic_v3;
40struct vgic_v3_cpu;
41
42/*
43 * Per-vCPU hypervisor state.
44 */
45struct hypctx {
46	struct trapframe tf;
47
48	/*
49	 * EL1 control registers.
50	 */
51	uint64_t	elr_el1;	/* Exception Link Register */
52	uint64_t	sp_el0;		/* Stack pointer */
53	uint64_t	tpidr_el0;	/* EL0 Software ID Register */
54	uint64_t	tpidrro_el0;	/* Read-only Thread ID Register */
55	uint64_t	tpidr_el1;	/* EL1 Software ID Register */
56	uint64_t	vbar_el1;	/* Vector Base Address Register */
57
58	uint64_t	actlr_el1;	/* Auxiliary Control Register */
59	uint64_t	afsr0_el1;	/* Auxiliary Fault Status Register 0 */
60	uint64_t	afsr1_el1;	/* Auxiliary Fault Status Register 1 */
61	uint64_t	amair_el1;	/* Auxiliary Memory Attribute Indirection Register */
62	uint64_t	contextidr_el1;	/* Current Process Identifier */
63	uint64_t	cpacr_el1;	/* Architectural Feature Access Control Register */
64	uint64_t	csselr_el1;	/* Cache Size Selection Register */
65	uint64_t	esr_el1;	/* Exception Syndrome Register */
66	uint64_t	far_el1;	/* Fault Address Register */
67	uint64_t	mair_el1;	/* Memory Attribute Indirection Register */
68	uint64_t	mdccint_el1;	/* Monitor DCC Interrupt Enable Register */
69	uint64_t	mdscr_el1;	/* Monitor Debug System Control Register */
70	uint64_t	par_el1;	/* Physical Address Register */
71	uint64_t	sctlr_el1;	/* System Control Register */
72	uint64_t	tcr_el1;	/* Translation Control Register */
73	uint64_t	tcr2_el1;	/* Translation Control Register 2 */
74	uint64_t	ttbr0_el1;	/* Translation Table Base Register 0 */
75	uint64_t	ttbr1_el1;	/* Translation Table Base Register 1 */
76	uint64_t	spsr_el1;	/* Saved Program Status Register */
77
78	uint64_t	pmcr_el0;	/* Performance Monitors Control Register */
79	uint64_t	pmccntr_el0;
80	uint64_t	pmccfiltr_el0;
81	uint64_t	pmcntenset_el0;
82	uint64_t	pmintenset_el1;
83	uint64_t	pmovsset_el0;
84	uint64_t	pmselr_el0;
85	uint64_t	pmuserenr_el0;
86	uint64_t	pmevcntr_el0[31];
87	uint64_t	pmevtyper_el0[31];
88
89	uint64_t	dbgbcr_el1[16];	/* Debug Breakpoint Control Registers */
90	uint64_t	dbgbvr_el1[16];	/* Debug Breakpoint Value Registers */
91	uint64_t	dbgwcr_el1[16];	/* Debug Watchpoint Control Registers */
92	uint64_t	dbgwvr_el1[16];	/* Debug Watchpoint Value Registers */
93
94	/* EL2 control registers */
95	uint64_t	cptr_el2;	/* Architectural Feature Trap Register */
96	uint64_t	hcr_el2;	/* Hypervisor Configuration Register */
97	uint64_t	mdcr_el2;	/* Monitor Debug Configuration Register */
98	uint64_t	vpidr_el2;	/* Virtualization Processor ID Register */
99	uint64_t	vmpidr_el2;	/* Virtualization Multiprocessor ID Register */
100	uint64_t	el2_addr;	/* The address of this in el2 space */
101	struct hyp	*hyp;
102	struct vcpu	*vcpu;
103	struct {
104		uint64_t	far_el2;	/* Fault Address Register */
105		uint64_t	hpfar_el2;	/* Hypervisor IPA Fault Address Register */
106	} exit_info;
107
108	struct vtimer_cpu 	vtimer_cpu;
109
110	uint64_t		setcaps;	/* Currently enabled capabilities. */
111
112	/* vCPU state used to handle guest debugging. */
113	uint64_t		debug_spsr;		/* Saved guest SPSR */
114	uint64_t		debug_mdscr;		/* Saved guest MDSCR */
115
116	struct vgic_v3_regs	vgic_v3_regs;
117	struct vgic_v3_cpu	*vgic_cpu;
118	bool			has_exception;
119};
120
121struct hyp {
122	struct vm	*vm;
123	struct vtimer	vtimer;
124	uint64_t	vmid_generation;
125	uint64_t	vttbr_el2;
126	uint64_t	el2_addr;	/* The address of this in el2 space */
127	bool		vgic_attached;
128	struct vgic_v3	*vgic;
129	struct hypctx	*ctx[];
130};
131
132#define	DEFINE_VMMOPS_IFUNC(ret_type, opname, args)			\
133	ret_type vmmops_##opname args;
134
135DEFINE_VMMOPS_IFUNC(int, modinit, (int ipinum))
136DEFINE_VMMOPS_IFUNC(int, modcleanup, (void))
137DEFINE_VMMOPS_IFUNC(void *, init, (struct vm *vm, struct pmap *pmap))
138DEFINE_VMMOPS_IFUNC(int, gla2gpa, (void *vcpui, struct vm_guest_paging *paging,
139    uint64_t gla, int prot, uint64_t *gpa, int *is_fault))
140DEFINE_VMMOPS_IFUNC(int, run, (void *vcpui, register_t pc, struct pmap *pmap,
141    struct vm_eventinfo *info))
142DEFINE_VMMOPS_IFUNC(void, cleanup, (void *vmi))
143DEFINE_VMMOPS_IFUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu,
144    int vcpu_id))
145DEFINE_VMMOPS_IFUNC(void, vcpu_cleanup, (void *vcpui))
146DEFINE_VMMOPS_IFUNC(int, exception, (void *vcpui, uint64_t esr, uint64_t far))
147DEFINE_VMMOPS_IFUNC(int, getreg, (void *vcpui, int num, uint64_t *retval))
148DEFINE_VMMOPS_IFUNC(int, setreg, (void *vcpui, int num, uint64_t val))
149DEFINE_VMMOPS_IFUNC(int, getcap, (void *vcpui, int num, int *retval))
150DEFINE_VMMOPS_IFUNC(int, setcap, (void *vcpui, int num, int val))
151DEFINE_VMMOPS_IFUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min,
152    vm_offset_t max))
153DEFINE_VMMOPS_IFUNC(void, vmspace_free, (struct vmspace *vmspace))
154#ifdef notyet
155#ifdef BHYVE_SNAPSHOT
156DEFINE_VMMOPS_IFUNC(int, snapshot, (void *vmi, struct vm_snapshot_meta *meta))
157DEFINE_VMMOPS_IFUNC(int, vcpu_snapshot, (void *vcpui,
158    struct vm_snapshot_meta *meta))
159DEFINE_VMMOPS_IFUNC(int, restore_tsc, (void *vcpui, uint64_t now))
160#endif
161#endif
162
163uint64_t	vmm_call_hyp(uint64_t, ...);
164
165#if 0
166#define	eprintf(fmt, ...)	printf("%s:%d " fmt, __func__, __LINE__, ##__VA_ARGS__)
167#else
168#define	eprintf(fmt, ...)	do {} while(0)
169#endif
170
171struct hypctx *arm64_get_active_vcpu(void);
172void raise_data_insn_abort(struct hypctx *, uint64_t, bool, int);
173
174#endif /* !_VMM_ARM64_H_ */
175