1d3916eacSRuslan Bukin /*- 2d3916eacSRuslan Bukin * SPDX-License-Identifier: BSD-2-Clause 3d3916eacSRuslan Bukin * 4d3916eacSRuslan Bukin * Copyright (c) 2015 Mihai Carabas <mihai.carabas@gmail.com> 5d3916eacSRuslan Bukin * Copyright (c) 2024 Ruslan Bukin <br@bsdpad.com> 6d3916eacSRuslan Bukin * 7d3916eacSRuslan Bukin * This software was developed by the University of Cambridge Computer 8d3916eacSRuslan Bukin * Laboratory (Department of Computer Science and Technology) under Innovate 9d3916eacSRuslan Bukin * UK project 105694, "Digital Security by Design (DSbD) Technology Platform 10d3916eacSRuslan Bukin * Prototype". 11d3916eacSRuslan Bukin * 12d3916eacSRuslan Bukin * Redistribution and use in source and binary forms, with or without 13d3916eacSRuslan Bukin * modification, are permitted provided that the following conditions 14d3916eacSRuslan Bukin * are met: 15d3916eacSRuslan Bukin * 1. Redistributions of source code must retain the above copyright 16d3916eacSRuslan Bukin * notice, this list of conditions and the following disclaimer. 17d3916eacSRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright 18d3916eacSRuslan Bukin * notice, this list of conditions and the following disclaimer in the 19d3916eacSRuslan Bukin * documentation and/or other materials provided with the distribution. 20d3916eacSRuslan Bukin * 21d3916eacSRuslan Bukin * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22d3916eacSRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23d3916eacSRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24d3916eacSRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 25d3916eacSRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26d3916eacSRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27d3916eacSRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28d3916eacSRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29d3916eacSRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30d3916eacSRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31d3916eacSRuslan Bukin * SUCH DAMAGE. 32d3916eacSRuslan Bukin */ 33d3916eacSRuslan Bukin 34d3916eacSRuslan Bukin #ifndef _VMM_RISCV_H_ 35d3916eacSRuslan Bukin #define _VMM_RISCV_H_ 36d3916eacSRuslan Bukin 37d3916eacSRuslan Bukin #include <machine/reg.h> 38d3916eacSRuslan Bukin #include <machine/pcpu.h> 39d3916eacSRuslan Bukin #include <machine/vmm.h> 40d3916eacSRuslan Bukin 419be0058eSRuslan Bukin #include <riscv/vmm/vmm_vtimer.h> 429be0058eSRuslan Bukin 43d3916eacSRuslan Bukin struct hypregs { 44d3916eacSRuslan Bukin uint64_t hyp_ra; 45d3916eacSRuslan Bukin uint64_t hyp_sp; 46d3916eacSRuslan Bukin uint64_t hyp_gp; 47d3916eacSRuslan Bukin uint64_t hyp_tp; 48d3916eacSRuslan Bukin uint64_t hyp_t[7]; 49d3916eacSRuslan Bukin uint64_t hyp_s[12]; 50d3916eacSRuslan Bukin uint64_t hyp_a[8]; 51d3916eacSRuslan Bukin uint64_t hyp_sepc; 52d3916eacSRuslan Bukin uint64_t hyp_sstatus; 53d3916eacSRuslan Bukin uint64_t hyp_hstatus; 54d3916eacSRuslan Bukin }; 55d3916eacSRuslan Bukin 56d3916eacSRuslan Bukin struct hypcsr { 57d3916eacSRuslan Bukin uint64_t hvip; 58d3916eacSRuslan Bukin uint64_t vsstatus; 59d3916eacSRuslan Bukin uint64_t vsie; 60d3916eacSRuslan Bukin uint64_t vstvec; 61d3916eacSRuslan Bukin uint64_t vsscratch; 62d3916eacSRuslan Bukin uint64_t vsepc; 63d3916eacSRuslan Bukin uint64_t vscause; 64d3916eacSRuslan Bukin uint64_t vstval; 65d3916eacSRuslan Bukin uint64_t vsatp; 66d3916eacSRuslan Bukin uint64_t scounteren; 67d3916eacSRuslan Bukin uint64_t senvcfg; 68d3916eacSRuslan Bukin }; 69d3916eacSRuslan Bukin 708f6b66a9SRuslan Bukin enum vmm_fence_type { 718f6b66a9SRuslan Bukin VMM_RISCV_FENCE_INVALID = 0, 728f6b66a9SRuslan Bukin VMM_RISCV_FENCE_I, 738f6b66a9SRuslan Bukin VMM_RISCV_FENCE_VMA, 748f6b66a9SRuslan Bukin VMM_RISCV_FENCE_VMA_ASID, 758f6b66a9SRuslan Bukin }; 768f6b66a9SRuslan Bukin 778f6b66a9SRuslan Bukin struct vmm_fence { 788f6b66a9SRuslan Bukin enum vmm_fence_type type; 798f6b66a9SRuslan Bukin size_t start; 808f6b66a9SRuslan Bukin size_t size; 818f6b66a9SRuslan Bukin uint64_t asid; 828f6b66a9SRuslan Bukin }; 838f6b66a9SRuslan Bukin 84d3916eacSRuslan Bukin struct hypctx { 85d3916eacSRuslan Bukin struct hypregs host_regs; 86d3916eacSRuslan Bukin struct hypregs guest_regs; 87d3916eacSRuslan Bukin struct hypcsr guest_csrs; 88d3916eacSRuslan Bukin uint64_t host_sscratch; 89d3916eacSRuslan Bukin uint64_t host_stvec; 90d3916eacSRuslan Bukin uint64_t host_scounteren; 91d3916eacSRuslan Bukin uint64_t guest_scounteren; 92d3916eacSRuslan Bukin struct hyp *hyp; 93d3916eacSRuslan Bukin struct vcpu *vcpu; 94d3916eacSRuslan Bukin bool has_exception; 95d3916eacSRuslan Bukin int cpu_id; 96d3916eacSRuslan Bukin int ipi_pending; 979be0058eSRuslan Bukin int interrupts_pending; 989be0058eSRuslan Bukin struct vtimer vtimer; 998f6b66a9SRuslan Bukin 1008f6b66a9SRuslan Bukin struct vmm_fence *fence_queue; 1018f6b66a9SRuslan Bukin struct mtx fence_queue_mtx; 1028f6b66a9SRuslan Bukin int fence_queue_head; 1038f6b66a9SRuslan Bukin int fence_queue_tail; 1048f6b66a9SRuslan Bukin #define FENCE_REQ_I (1 << 0) 1058f6b66a9SRuslan Bukin #define FENCE_REQ_VMA (1 << 1) 1068f6b66a9SRuslan Bukin int fence_req; 107d3916eacSRuslan Bukin }; 108d3916eacSRuslan Bukin 109d3916eacSRuslan Bukin struct hyp { 110d3916eacSRuslan Bukin struct vm *vm; 111d3916eacSRuslan Bukin uint64_t vmid_generation; 112d3916eacSRuslan Bukin bool aplic_attached; 113d3916eacSRuslan Bukin struct aplic *aplic; 114d3916eacSRuslan Bukin struct hypctx *ctx[]; 115d3916eacSRuslan Bukin }; 116d3916eacSRuslan Bukin 117d3916eacSRuslan Bukin struct hyptrap { 118d3916eacSRuslan Bukin uint64_t sepc; 119d3916eacSRuslan Bukin uint64_t scause; 120d3916eacSRuslan Bukin uint64_t stval; 121d3916eacSRuslan Bukin uint64_t htval; 122d3916eacSRuslan Bukin uint64_t htinst; 123d3916eacSRuslan Bukin }; 124d3916eacSRuslan Bukin 125d3916eacSRuslan Bukin #define DEFINE_VMMOPS_IFUNC(ret_type, opname, args) \ 126d3916eacSRuslan Bukin ret_type vmmops_##opname args; 127d3916eacSRuslan Bukin 128d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(int, modinit, (void)) 129d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(int, modcleanup, (void)) 130d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(void *, init, (struct vm *vm, struct pmap *pmap)) 131d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(int, gla2gpa, (void *vcpui, struct vm_guest_paging *paging, 132d3916eacSRuslan Bukin uint64_t gla, int prot, uint64_t *gpa, int *is_fault)) 133d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(int, run, (void *vcpui, register_t pc, struct pmap *pmap, 134d3916eacSRuslan Bukin struct vm_eventinfo *info)) 135d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(void, cleanup, (void *vmi)) 136d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu, 137d3916eacSRuslan Bukin int vcpu_id)) 138d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(void, vcpu_cleanup, (void *vcpui)) 139d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(int, exception, (void *vcpui, uint64_t scause)) 140d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(int, getreg, (void *vcpui, int num, uint64_t *retval)) 141d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(int, setreg, (void *vcpui, int num, uint64_t val)) 142d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(int, getcap, (void *vcpui, int num, int *retval)) 143d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(int, setcap, (void *vcpui, int num, int val)) 144d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min, 145d3916eacSRuslan Bukin vm_offset_t max)) 146d3916eacSRuslan Bukin DEFINE_VMMOPS_IFUNC(void, vmspace_free, (struct vmspace *vmspace)) 147d3916eacSRuslan Bukin 148d3916eacSRuslan Bukin #define dprintf(fmt, ...) 149d3916eacSRuslan Bukin 150d3916eacSRuslan Bukin struct hypctx *riscv_get_active_vcpu(void); 151d3916eacSRuslan Bukin void vmm_switch(struct hypctx *); 152d3916eacSRuslan Bukin void vmm_unpriv_trap(struct hyptrap *, uint64_t tmp); 153*4eee1381SRuslan Bukin bool vmm_sbi_ecall(struct vcpu *); 154d3916eacSRuslan Bukin 155*4eee1381SRuslan Bukin void riscv_send_ipi(struct hyp *hyp, cpuset_t *cpus); 156d3916eacSRuslan Bukin int riscv_check_ipi(struct hypctx *hypctx, bool clear); 1579be0058eSRuslan Bukin bool riscv_check_interrupts_pending(struct hypctx *hypctx); 158d3916eacSRuslan Bukin 159d3916eacSRuslan Bukin #endif /* !_VMM_RISCV_H_ */ 160