1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2015 Mihai Carabas <mihai.carabas@gmail.com> 5 * Copyright (c) 2024 Ruslan Bukin <br@bsdpad.com> 6 * 7 * This software was developed by the University of Cambridge Computer 8 * Laboratory (Department of Computer Science and Technology) under Innovate 9 * UK project 105694, "Digital Security by Design (DSbD) Technology Platform 10 * Prototype". 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef _VMM_RISCV_H_ 35 #define _VMM_RISCV_H_ 36 37 #include <machine/reg.h> 38 #include <machine/pcpu.h> 39 #include <machine/vmm.h> 40 41 struct hypregs { 42 uint64_t hyp_ra; 43 uint64_t hyp_sp; 44 uint64_t hyp_gp; 45 uint64_t hyp_tp; 46 uint64_t hyp_t[7]; 47 uint64_t hyp_s[12]; 48 uint64_t hyp_a[8]; 49 uint64_t hyp_sepc; 50 uint64_t hyp_sstatus; 51 uint64_t hyp_hstatus; 52 }; 53 54 struct hypcsr { 55 uint64_t hvip; 56 uint64_t vsstatus; 57 uint64_t vsie; 58 uint64_t vstvec; 59 uint64_t vsscratch; 60 uint64_t vsepc; 61 uint64_t vscause; 62 uint64_t vstval; 63 uint64_t vsatp; 64 uint64_t scounteren; 65 uint64_t senvcfg; 66 }; 67 68 struct hypctx { 69 struct hypregs host_regs; 70 struct hypregs guest_regs; 71 struct hypcsr guest_csrs; 72 uint64_t host_sscratch; 73 uint64_t host_stvec; 74 uint64_t host_scounteren; 75 uint64_t guest_scounteren; 76 struct hyp *hyp; 77 struct vcpu *vcpu; 78 bool has_exception; 79 int cpu_id; 80 int ipi_pending; 81 }; 82 83 struct hyp { 84 struct vm *vm; 85 uint64_t vmid_generation; 86 bool aplic_attached; 87 struct aplic *aplic; 88 struct hypctx *ctx[]; 89 }; 90 91 struct hyptrap { 92 uint64_t sepc; 93 uint64_t scause; 94 uint64_t stval; 95 uint64_t htval; 96 uint64_t htinst; 97 }; 98 99 #define DEFINE_VMMOPS_IFUNC(ret_type, opname, args) \ 100 ret_type vmmops_##opname args; 101 102 DEFINE_VMMOPS_IFUNC(int, modinit, (void)) 103 DEFINE_VMMOPS_IFUNC(int, modcleanup, (void)) 104 DEFINE_VMMOPS_IFUNC(void *, init, (struct vm *vm, struct pmap *pmap)) 105 DEFINE_VMMOPS_IFUNC(int, gla2gpa, (void *vcpui, struct vm_guest_paging *paging, 106 uint64_t gla, int prot, uint64_t *gpa, int *is_fault)) 107 DEFINE_VMMOPS_IFUNC(int, run, (void *vcpui, register_t pc, struct pmap *pmap, 108 struct vm_eventinfo *info)) 109 DEFINE_VMMOPS_IFUNC(void, cleanup, (void *vmi)) 110 DEFINE_VMMOPS_IFUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu, 111 int vcpu_id)) 112 DEFINE_VMMOPS_IFUNC(void, vcpu_cleanup, (void *vcpui)) 113 DEFINE_VMMOPS_IFUNC(int, exception, (void *vcpui, uint64_t scause)) 114 DEFINE_VMMOPS_IFUNC(int, getreg, (void *vcpui, int num, uint64_t *retval)) 115 DEFINE_VMMOPS_IFUNC(int, setreg, (void *vcpui, int num, uint64_t val)) 116 DEFINE_VMMOPS_IFUNC(int, getcap, (void *vcpui, int num, int *retval)) 117 DEFINE_VMMOPS_IFUNC(int, setcap, (void *vcpui, int num, int val)) 118 DEFINE_VMMOPS_IFUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min, 119 vm_offset_t max)) 120 DEFINE_VMMOPS_IFUNC(void, vmspace_free, (struct vmspace *vmspace)) 121 122 #define dprintf(fmt, ...) 123 124 struct hypctx *riscv_get_active_vcpu(void); 125 void vmm_switch(struct hypctx *); 126 void vmm_unpriv_trap(struct hyptrap *, uint64_t tmp); 127 int vmm_sbi_ecall(struct vcpu *, bool *); 128 129 void riscv_send_ipi(struct hypctx *hypctx, int hart_id); 130 int riscv_check_ipi(struct hypctx *hypctx, bool clear); 131 132 #endif /* !_VMM_RISCV_H_ */ 133