freebsd-src/sys/arm64/vmm/hyp.h
Andrew Turner 47e073941f Import the kernel parts of bhyve/arm64
To support virtual machines on arm64 add the vmm code. This is based on
earlier work by Mihai Carabas and Alexandru Elisei at University
Politehnica of Bucharest, with further work by myself and Mark Johnston.

All AArch64 CPUs should work, however only the GICv3 interrupt
controller is supported. There is initial support to allow the GICv2
to be supported in the future. Only pure Armv8.0 virtualisation is
supported, the Virtualization Host Extensions are not currently used.

With a separate userspace patch and U-Boot port FreeBSD guests are able
to boot to multiuser mode, and the hypervisor can be tested with the
kvm unit tests. Linux partially boots, but hangs before entering
userspace. Other operating systems are untested.

Sponsored by:	Arm Ltd
Sponsored by:	Innovate UK
Sponsored by:	The FreeBSD Foundation
Sponsored by:	University Politehnica of Bucharest
Differential Revision:	https://reviews.freebsd.org/D37428
2024-02-21 18:55:32 +00:00

115 lines
4.4 KiB
C

/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2017 Alexandru Elisei <alexandru.elisei@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _VMM_HYP_H_
#define _VMM_HYP_H_
/*
* The translation tables for the hypervisor mode will hold mappings for kernel
* virtual addresses and an identity mapping (VA == PA) necessary when
* enabling/disabling the MMU.
*
* When in EL2 exception level the translation table base register is TTBR0_EL2
* and the virtual addresses generated by the CPU must be at the bottom of the
* memory, with the first 16 bits all set to zero:
*
* 0x0000ffffffffffff End hyp address space
* 0x0000000000000000 Start of hyp address space
*
* To run code in hyp mode we need to convert kernel virtual addresses to
* addreses that fit into this address space.
*
* The kernel virtual address range is:
*
* 0xffff007fffffffff End of KVA
* 0xffff000000000000 Kernel base address & start of KVA
*
* (see /sys/arm64/include/vmparam.h).
*
* We could convert the kernel virtual addresses to valid EL2 addresses by
* setting the first 16 bits to zero and thus mapping the kernel addresses in
* the bottom half of the EL2 address space, but then they might clash with the
* identity mapping addresses. Instead we map the kernel addresses in the upper
* half of the EL2 address space.
*
* The hypervisor address space will look like this:
*
* 0x0000807fffffffff End of KVA mapping
* 0x0000800000000000 Start of KVA mapping
*
* 0x00007fffffffffff End of identity mapping
* 0x0000000000000000 Start of identity mapping
*
* With the scheme we have 47 bits at our disposable for the identity map and
* another 47 bits for the kernel virtual addresses. For a maximum physical
* memory size of 128TB we are guaranteed to not have any clashes between
* addresses.
*/
#define HYP_VM_MIN_ADDRESS 0x0000000000000000
#define HYP_VM_MAX_ADDRESS 0x0001000000000000
/*
* When the vmm code is installed the following handles can be used by
* the host to call into EL2.
*/
#define HYP_CLEANUP 0x00000001
#define HYP_ENTER_GUEST 0x00000002
#define HYP_READ_REGISTER 0x00000003
#define HYP_REG_ICH_VTR 0x1
#define HYP_REG_CNTHCTL 0x2
#define HYP_CLEAN_S2_TLBI 0x00000004
#define HYP_DC_CIVAC 0x00000005
#define HYP_EL2_TLBI 0x00000006
#define HYP_EL2_TLBI_ALL 0x1
#define HYP_EL2_TLBI_VA 0x2
#define HYP_S2_TLBI_RANGE 0x00000010
#define HYP_S2_TLBI_ALL 0x00000011
/*
* When taking asynchronous exceptions, or interrupts, with the exception of the
* SError interrupt, the exception syndrome register is not updated with the
* exception code. We need to differentiate between the different exception
* types taken to EL2.
*/
#define EXCP_TYPE_EL1_SYNC 0
#define EXCP_TYPE_EL1_IRQ 1
#define EXCP_TYPE_EL1_FIQ 2
#define EXCP_TYPE_EL1_ERROR 3
#define EXCP_TYPE_EL2_SYNC 4
#define EXCP_TYPE_EL2_IRQ 5
#define EXCP_TYPE_EL2_FIQ 6
#define EXCP_TYPE_EL2_ERROR 7
#define EXCP_TYPE_MAINT_IRQ 8
/* Used internally in vmm_hyp.c */
#define EXCP_TYPE_REENTER 9
#define HYP_GET_VECTOR_TABLE -1
#endif /* !_VMM_HYP_H_ */