xref: /freebsd/sys/arm64/vmm/arm64.h (revision 32111003c3087389cc5e50949ee3a26c4e7b26c4)
147e07394SAndrew Turner /*-
247e07394SAndrew Turner  * SPDX-License-Identifier: BSD-2-Clause
347e07394SAndrew Turner  *
447e07394SAndrew Turner  * Copyright (C) 2015 Mihai Carabas <mihai.carabas@gmail.com>
547e07394SAndrew Turner  * All rights reserved.
647e07394SAndrew Turner  *
747e07394SAndrew Turner  * Redistribution and use in source and binary forms, with or without
847e07394SAndrew Turner  * modification, are permitted provided that the following conditions
947e07394SAndrew Turner  * are met:
1047e07394SAndrew Turner  * 1. Redistributions of source code must retain the above copyright
1147e07394SAndrew Turner  *    notice, this list of conditions and the following disclaimer.
1247e07394SAndrew Turner  * 2. Redistributions in binary form must reproduce the above copyright
1347e07394SAndrew Turner  *    notice, this list of conditions and the following disclaimer in the
1447e07394SAndrew Turner  *    documentation and/or other materials provided with the distribution.
1547e07394SAndrew Turner  *
1647e07394SAndrew Turner  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1747e07394SAndrew Turner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1847e07394SAndrew Turner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1947e07394SAndrew Turner  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
2047e07394SAndrew Turner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2147e07394SAndrew Turner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2247e07394SAndrew Turner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2347e07394SAndrew Turner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2447e07394SAndrew Turner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2547e07394SAndrew Turner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2647e07394SAndrew Turner  * SUCH DAMAGE.
2747e07394SAndrew Turner  */
2847e07394SAndrew Turner #ifndef _VMM_ARM64_H_
2947e07394SAndrew Turner #define _VMM_ARM64_H_
3047e07394SAndrew Turner 
3147e07394SAndrew Turner #include <machine/reg.h>
3247e07394SAndrew Turner #include <machine/hypervisor.h>
3347e07394SAndrew Turner #include <machine/pcpu.h>
3447e07394SAndrew Turner 
3547e07394SAndrew Turner #include "mmu.h"
3647e07394SAndrew Turner #include "io/vgic_v3.h"
3747e07394SAndrew Turner #include "io/vtimer.h"
3847e07394SAndrew Turner 
3947e07394SAndrew Turner struct vgic_v3;
4047e07394SAndrew Turner struct vgic_v3_cpu;
4147e07394SAndrew Turner 
4275cb9492SMark Johnston /*
4375cb9492SMark Johnston  * Per-vCPU hypervisor state.
4475cb9492SMark Johnston  */
4547e07394SAndrew Turner struct hypctx {
4647e07394SAndrew Turner 	struct trapframe tf;
4747e07394SAndrew Turner 
4847e07394SAndrew Turner 	/*
4947e07394SAndrew Turner 	 * EL1 control registers.
5047e07394SAndrew Turner 	 */
5147e07394SAndrew Turner 	uint64_t	elr_el1;	/* Exception Link Register */
5247e07394SAndrew Turner 	uint64_t	sp_el0;		/* Stack pointer */
5347e07394SAndrew Turner 	uint64_t	tpidr_el0;	/* EL0 Software ID Register */
5447e07394SAndrew Turner 	uint64_t	tpidrro_el0;	/* Read-only Thread ID Register */
5547e07394SAndrew Turner 	uint64_t	tpidr_el1;	/* EL1 Software ID Register */
5647e07394SAndrew Turner 	uint64_t	vbar_el1;	/* Vector Base Address Register */
5747e07394SAndrew Turner 
5847e07394SAndrew Turner 	uint64_t	actlr_el1;	/* Auxiliary Control Register */
5947e07394SAndrew Turner 	uint64_t	afsr0_el1;	/* Auxiliary Fault Status Register 0 */
6047e07394SAndrew Turner 	uint64_t	afsr1_el1;	/* Auxiliary Fault Status Register 1 */
6147e07394SAndrew Turner 	uint64_t	amair_el1;	/* Auxiliary Memory Attribute Indirection Register */
6247e07394SAndrew Turner 	uint64_t	contextidr_el1;	/* Current Process Identifier */
6347e07394SAndrew Turner 	uint64_t	cpacr_el1;	/* Architectural Feature Access Control Register */
6447e07394SAndrew Turner 	uint64_t	csselr_el1;	/* Cache Size Selection Register */
6547e07394SAndrew Turner 	uint64_t	esr_el1;	/* Exception Syndrome Register */
6647e07394SAndrew Turner 	uint64_t	far_el1;	/* Fault Address Register */
6747e07394SAndrew Turner 	uint64_t	mair_el1;	/* Memory Attribute Indirection Register */
6847e07394SAndrew Turner 	uint64_t	mdccint_el1;	/* Monitor DCC Interrupt Enable Register */
6947e07394SAndrew Turner 	uint64_t	mdscr_el1;	/* Monitor Debug System Control Register */
7047e07394SAndrew Turner 	uint64_t	par_el1;	/* Physical Address Register */
7147e07394SAndrew Turner 	uint64_t	sctlr_el1;	/* System Control Register */
7247e07394SAndrew Turner 	uint64_t	tcr_el1;	/* Translation Control Register */
7347e07394SAndrew Turner 	uint64_t	tcr2_el1;	/* Translation Control Register 2 */
7447e07394SAndrew Turner 	uint64_t	ttbr0_el1;	/* Translation Table Base Register 0 */
7547e07394SAndrew Turner 	uint64_t	ttbr1_el1;	/* Translation Table Base Register 1 */
7647e07394SAndrew Turner 	uint64_t	spsr_el1;	/* Saved Program Status Register */
7747e07394SAndrew Turner 
7847e07394SAndrew Turner 	uint64_t	pmcr_el0;	/* Performance Monitors Control Register */
7947e07394SAndrew Turner 	uint64_t	pmccntr_el0;
8047e07394SAndrew Turner 	uint64_t	pmccfiltr_el0;
8147e07394SAndrew Turner 	uint64_t	pmcntenset_el0;
8247e07394SAndrew Turner 	uint64_t	pmintenset_el1;
8347e07394SAndrew Turner 	uint64_t	pmovsset_el0;
8447e07394SAndrew Turner 	uint64_t	pmselr_el0;
8547e07394SAndrew Turner 	uint64_t	pmuserenr_el0;
8647e07394SAndrew Turner 	uint64_t	pmevcntr_el0[31];
8747e07394SAndrew Turner 	uint64_t	pmevtyper_el0[31];
8847e07394SAndrew Turner 
8947e07394SAndrew Turner 	uint64_t	dbgbcr_el1[16];	/* Debug Breakpoint Control Registers */
9047e07394SAndrew Turner 	uint64_t	dbgbvr_el1[16];	/* Debug Breakpoint Value Registers */
9147e07394SAndrew Turner 	uint64_t	dbgwcr_el1[16];	/* Debug Watchpoint Control Registers */
9247e07394SAndrew Turner 	uint64_t	dbgwvr_el1[16];	/* Debug Watchpoint Value Registers */
9347e07394SAndrew Turner 
9447e07394SAndrew Turner 	/* EL2 control registers */
9547e07394SAndrew Turner 	uint64_t	cptr_el2;	/* Architectural Feature Trap Register */
9647e07394SAndrew Turner 	uint64_t	hcr_el2;	/* Hypervisor Configuration Register */
97*32111003SHarry Moulton 	uint64_t	hcrx_el2;	/* Extended Hypervisor Configuration Register */
9847e07394SAndrew Turner 	uint64_t	mdcr_el2;	/* Monitor Debug Configuration Register */
9947e07394SAndrew Turner 	uint64_t	vpidr_el2;	/* Virtualization Processor ID Register */
10047e07394SAndrew Turner 	uint64_t	vmpidr_el2;	/* Virtualization Multiprocessor ID Register */
10147e07394SAndrew Turner 	uint64_t	el2_addr;	/* The address of this in el2 space */
10247e07394SAndrew Turner 	struct hyp	*hyp;
10347e07394SAndrew Turner 	struct vcpu	*vcpu;
10447e07394SAndrew Turner 	struct {
10547e07394SAndrew Turner 		uint64_t	far_el2;	/* Fault Address Register */
10647e07394SAndrew Turner 		uint64_t	hpfar_el2;	/* Hypervisor IPA Fault Address Register */
10747e07394SAndrew Turner 	} exit_info;
10847e07394SAndrew Turner 
10947e07394SAndrew Turner 	struct vtimer_cpu 	vtimer_cpu;
11047e07394SAndrew Turner 
11175cb9492SMark Johnston 	uint64_t		setcaps;	/* Currently enabled capabilities. */
11275cb9492SMark Johnston 
11375cb9492SMark Johnston 	/* vCPU state used to handle guest debugging. */
11475cb9492SMark Johnston 	uint64_t		debug_spsr;		/* Saved guest SPSR */
11575cb9492SMark Johnston 	uint64_t		debug_mdscr;		/* Saved guest MDSCR */
11675cb9492SMark Johnston 
11747e07394SAndrew Turner 	struct vgic_v3_regs	vgic_v3_regs;
11847e07394SAndrew Turner 	struct vgic_v3_cpu	*vgic_cpu;
11947e07394SAndrew Turner 	bool			has_exception;
12047e07394SAndrew Turner };
12147e07394SAndrew Turner 
12247e07394SAndrew Turner struct hyp {
12347e07394SAndrew Turner 	struct vm	*vm;
12447e07394SAndrew Turner 	struct vtimer	vtimer;
12547e07394SAndrew Turner 	uint64_t	vmid_generation;
12647e07394SAndrew Turner 	uint64_t	vttbr_el2;
12747e07394SAndrew Turner 	uint64_t	el2_addr;	/* The address of this in el2 space */
12847e07394SAndrew Turner 	bool		vgic_attached;
12947e07394SAndrew Turner 	struct vgic_v3	*vgic;
13047e07394SAndrew Turner 	struct hypctx	*ctx[];
13147e07394SAndrew Turner };
13247e07394SAndrew Turner 
13347e07394SAndrew Turner #define	DEFINE_VMMOPS_IFUNC(ret_type, opname, args)			\
13447e07394SAndrew Turner 	ret_type vmmops_##opname args;
13547e07394SAndrew Turner 
13647e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, modinit, (int ipinum))
13747e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, modcleanup, (void))
13847e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(void *, init, (struct vm *vm, struct pmap *pmap))
13947e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, gla2gpa, (void *vcpui, struct vm_guest_paging *paging,
14047e07394SAndrew Turner     uint64_t gla, int prot, uint64_t *gpa, int *is_fault))
14147e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, run, (void *vcpui, register_t pc, struct pmap *pmap,
14247e07394SAndrew Turner     struct vm_eventinfo *info))
14347e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(void, cleanup, (void *vmi))
14447e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu,
14547e07394SAndrew Turner     int vcpu_id))
14647e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(void, vcpu_cleanup, (void *vcpui))
14747e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, exception, (void *vcpui, uint64_t esr, uint64_t far))
14847e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, getreg, (void *vcpui, int num, uint64_t *retval))
14947e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, setreg, (void *vcpui, int num, uint64_t val))
15047e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, getcap, (void *vcpui, int num, int *retval))
15147e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, setcap, (void *vcpui, int num, int val))
15247e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min,
15347e07394SAndrew Turner     vm_offset_t max))
15447e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(void, vmspace_free, (struct vmspace *vmspace))
15547e07394SAndrew Turner #ifdef notyet
15647e07394SAndrew Turner #ifdef BHYVE_SNAPSHOT
15747e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, snapshot, (void *vmi, struct vm_snapshot_meta *meta))
15847e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, vcpu_snapshot, (void *vcpui,
15947e07394SAndrew Turner     struct vm_snapshot_meta *meta))
16047e07394SAndrew Turner DEFINE_VMMOPS_IFUNC(int, restore_tsc, (void *vcpui, uint64_t now))
16147e07394SAndrew Turner #endif
16247e07394SAndrew Turner #endif
16347e07394SAndrew Turner 
16447e07394SAndrew Turner uint64_t	vmm_call_hyp(uint64_t, ...);
16547e07394SAndrew Turner 
16647e07394SAndrew Turner #if 0
16747e07394SAndrew Turner #define	eprintf(fmt, ...)	printf("%s:%d " fmt, __func__, __LINE__, ##__VA_ARGS__)
16847e07394SAndrew Turner #else
16947e07394SAndrew Turner #define	eprintf(fmt, ...)	do {} while(0)
17047e07394SAndrew Turner #endif
17147e07394SAndrew Turner 
17247e07394SAndrew Turner struct hypctx *arm64_get_active_vcpu(void);
17347e07394SAndrew Turner void raise_data_insn_abort(struct hypctx *, uint64_t, bool, int);
17447e07394SAndrew Turner 
17547e07394SAndrew Turner #endif /* !_VMM_ARM64_H_ */
176