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