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 #include <riscv/vmm/vmm_vtimer.h> 42 43 struct hypregs { 44 uint64_t hyp_ra; 45 uint64_t hyp_sp; 46 uint64_t hyp_gp; 47 uint64_t hyp_tp; 48 uint64_t hyp_t[7]; 49 uint64_t hyp_s[12]; 50 uint64_t hyp_a[8]; 51 uint64_t hyp_sepc; 52 uint64_t hyp_sstatus; 53 uint64_t hyp_hstatus; 54 }; 55 56 struct hypcsr { 57 uint64_t hvip; 58 uint64_t vsstatus; 59 uint64_t vsie; 60 uint64_t vstvec; 61 uint64_t vsscratch; 62 uint64_t vsepc; 63 uint64_t vscause; 64 uint64_t vstval; 65 uint64_t vsatp; 66 uint64_t scounteren; 67 uint64_t senvcfg; 68 }; 69 70 struct hypctx { 71 struct hypregs host_regs; 72 struct hypregs guest_regs; 73 struct hypcsr guest_csrs; 74 uint64_t host_sscratch; 75 uint64_t host_stvec; 76 uint64_t host_scounteren; 77 uint64_t guest_scounteren; 78 struct hyp *hyp; 79 struct vcpu *vcpu; 80 bool has_exception; 81 int cpu_id; 82 int ipi_pending; 83 int interrupts_pending; 84 struct vtimer vtimer; 85 }; 86 87 struct hyp { 88 struct vm *vm; 89 uint64_t vmid_generation; 90 bool aplic_attached; 91 struct aplic *aplic; 92 struct hypctx *ctx[]; 93 }; 94 95 struct hyptrap { 96 uint64_t sepc; 97 uint64_t scause; 98 uint64_t stval; 99 uint64_t htval; 100 uint64_t htinst; 101 }; 102 103 #define DEFINE_VMMOPS_IFUNC(ret_type, opname, args) \ 104 ret_type vmmops_##opname args; 105 106 DEFINE_VMMOPS_IFUNC(int, modinit, (void)) 107 DEFINE_VMMOPS_IFUNC(int, modcleanup, (void)) 108 DEFINE_VMMOPS_IFUNC(void *, init, (struct vm *vm, struct pmap *pmap)) 109 DEFINE_VMMOPS_IFUNC(int, gla2gpa, (void *vcpui, struct vm_guest_paging *paging, 110 uint64_t gla, int prot, uint64_t *gpa, int *is_fault)) 111 DEFINE_VMMOPS_IFUNC(int, run, (void *vcpui, register_t pc, struct pmap *pmap, 112 struct vm_eventinfo *info)) 113 DEFINE_VMMOPS_IFUNC(void, cleanup, (void *vmi)) 114 DEFINE_VMMOPS_IFUNC(void *, vcpu_init, (void *vmi, struct vcpu *vcpu, 115 int vcpu_id)) 116 DEFINE_VMMOPS_IFUNC(void, vcpu_cleanup, (void *vcpui)) 117 DEFINE_VMMOPS_IFUNC(int, exception, (void *vcpui, uint64_t scause)) 118 DEFINE_VMMOPS_IFUNC(int, getreg, (void *vcpui, int num, uint64_t *retval)) 119 DEFINE_VMMOPS_IFUNC(int, setreg, (void *vcpui, int num, uint64_t val)) 120 DEFINE_VMMOPS_IFUNC(int, getcap, (void *vcpui, int num, int *retval)) 121 DEFINE_VMMOPS_IFUNC(int, setcap, (void *vcpui, int num, int val)) 122 DEFINE_VMMOPS_IFUNC(struct vmspace *, vmspace_alloc, (vm_offset_t min, 123 vm_offset_t max)) 124 DEFINE_VMMOPS_IFUNC(void, vmspace_free, (struct vmspace *vmspace)) 125 126 #define dprintf(fmt, ...) 127 128 struct hypctx *riscv_get_active_vcpu(void); 129 void vmm_switch(struct hypctx *); 130 void vmm_unpriv_trap(struct hyptrap *, uint64_t tmp); 131 int vmm_sbi_ecall(struct vcpu *, bool *); 132 133 void riscv_send_ipi(struct hypctx *hypctx, int hart_id); 134 int riscv_check_ipi(struct hypctx *hypctx, bool clear); 135 bool riscv_check_interrupts_pending(struct hypctx *hypctx); 136 137 #endif /* !_VMM_RISCV_H_ */ 138