/*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2024 Ruslan Bukin * * This software was developed by the University of Cambridge Computer * Laboratory (Department of Computer Science and Technology) under Innovate * UK project 105694, "Digital Security by Design (DSbD) Technology Platform * Prototype". * * 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. */ #include #include "assym.inc" .text /* * a0 == hypctx * */ ENTRY(vmm_switch) sd ra, (HYP_H_RA)(a0) sd sp, (HYP_H_SP)(a0) sd tp, (HYP_H_TP)(a0) sd gp, (HYP_H_GP)(a0) sd s0, (HYP_H_S + 0 * 8)(a0) sd s1, (HYP_H_S + 1 * 8)(a0) sd s2, (HYP_H_S + 2 * 8)(a0) sd s3, (HYP_H_S + 3 * 8)(a0) sd s4, (HYP_H_S + 4 * 8)(a0) sd s5, (HYP_H_S + 5 * 8)(a0) sd s6, (HYP_H_S + 6 * 8)(a0) sd s7, (HYP_H_S + 7 * 8)(a0) sd s8, (HYP_H_S + 8 * 8)(a0) sd s9, (HYP_H_S + 9 * 8)(a0) sd s10, (HYP_H_S + 10 * 8)(a0) sd s11, (HYP_H_S + 11 * 8)(a0) sd a1, (HYP_H_A + 1 * 8)(a0) sd a2, (HYP_H_A + 2 * 8)(a0) sd a3, (HYP_H_A + 3 * 8)(a0) sd a4, (HYP_H_A + 4 * 8)(a0) sd a5, (HYP_H_A + 5 * 8)(a0) sd a6, (HYP_H_A + 6 * 8)(a0) sd a7, (HYP_H_A + 7 * 8)(a0) ld t0, (HYP_G_SSTATUS)(a0) ld t1, (HYP_G_HSTATUS)(a0) ld t2, (HYP_G_SCOUNTEREN)(a0) la t4, .Lswitch_return ld t5, (HYP_G_SEPC)(a0) csrrw t0, sstatus, t0 csrrw t1, hstatus, t1 csrrw t2, scounteren, t2 csrrw t3, sscratch, a0 csrrw t4, stvec, t4 csrw sepc, t5 sd t0, (HYP_H_SSTATUS)(a0) sd t1, (HYP_H_HSTATUS)(a0) sd t2, (HYP_H_SCOUNTEREN)(a0) sd t3, (HYP_H_SSCRATCH)(a0) sd t4, (HYP_H_STVEC)(a0) ld ra, (HYP_G_RA)(a0) ld sp, (HYP_G_SP)(a0) ld gp, (HYP_G_GP)(a0) ld tp, (HYP_G_TP)(a0) ld t0, (HYP_G_T + 0 * 8)(a0) ld t1, (HYP_G_T + 1 * 8)(a0) ld t2, (HYP_G_T + 2 * 8)(a0) ld t3, (HYP_G_T + 3 * 8)(a0) ld t4, (HYP_G_T + 4 * 8)(a0) ld t5, (HYP_G_T + 5 * 8)(a0) ld t6, (HYP_G_T + 6 * 8)(a0) ld s0, (HYP_G_S + 0 * 8)(a0) ld s1, (HYP_G_S + 1 * 8)(a0) ld s2, (HYP_G_S + 2 * 8)(a0) ld s3, (HYP_G_S + 3 * 8)(a0) ld s4, (HYP_G_S + 4 * 8)(a0) ld s5, (HYP_G_S + 5 * 8)(a0) ld s6, (HYP_G_S + 6 * 8)(a0) ld s7, (HYP_G_S + 7 * 8)(a0) ld s8, (HYP_G_S + 8 * 8)(a0) ld s9, (HYP_G_S + 9 * 8)(a0) ld s10, (HYP_G_S + 10 * 8)(a0) ld s11, (HYP_G_S + 11 * 8)(a0) /* skip a0 for now. */ ld a1, (HYP_G_A + 1 * 8)(a0) ld a2, (HYP_G_A + 2 * 8)(a0) ld a3, (HYP_G_A + 3 * 8)(a0) ld a4, (HYP_G_A + 4 * 8)(a0) ld a5, (HYP_G_A + 5 * 8)(a0) ld a6, (HYP_G_A + 6 * 8)(a0) ld a7, (HYP_G_A + 7 * 8)(a0) /* now load a0. */ ld a0, (HYP_G_A + 0 * 8)(a0) sret .align 2 .Lswitch_return: csrrw a0, sscratch, a0 sd ra, (HYP_G_RA)(a0) sd sp, (HYP_G_SP)(a0) sd gp, (HYP_G_GP)(a0) sd tp, (HYP_G_TP)(a0) sd t0, (HYP_G_T + 0 * 8)(a0) sd t1, (HYP_G_T + 1 * 8)(a0) sd t2, (HYP_G_T + 2 * 8)(a0) sd t3, (HYP_G_T + 3 * 8)(a0) sd t4, (HYP_G_T + 4 * 8)(a0) sd t5, (HYP_G_T + 5 * 8)(a0) sd t6, (HYP_G_T + 6 * 8)(a0) sd s0, (HYP_G_S + 0 * 8)(a0) sd s1, (HYP_G_S + 1 * 8)(a0) sd s2, (HYP_G_S + 2 * 8)(a0) sd s3, (HYP_G_S + 3 * 8)(a0) sd s4, (HYP_G_S + 4 * 8)(a0) sd s5, (HYP_G_S + 5 * 8)(a0) sd s6, (HYP_G_S + 6 * 8)(a0) sd s7, (HYP_G_S + 7 * 8)(a0) sd s8, (HYP_G_S + 8 * 8)(a0) sd s9, (HYP_G_S + 9 * 8)(a0) sd s10, (HYP_G_S + 10 * 8)(a0) sd s11, (HYP_G_S + 11 * 8)(a0) /* skip a0 */ sd a1, (HYP_G_A + 1 * 8)(a0) sd a2, (HYP_G_A + 2 * 8)(a0) sd a3, (HYP_G_A + 3 * 8)(a0) sd a4, (HYP_G_A + 4 * 8)(a0) sd a5, (HYP_G_A + 5 * 8)(a0) sd a6, (HYP_G_A + 6 * 8)(a0) sd a7, (HYP_G_A + 7 * 8)(a0) ld t1, (HYP_H_STVEC)(a0) ld t2, (HYP_H_SSCRATCH)(a0) ld t3, (HYP_H_SCOUNTEREN)(a0) ld t4, (HYP_H_HSTATUS)(a0) ld t5, (HYP_H_SSTATUS)(a0) csrr t0, sepc csrw stvec, t1 csrrw t2, sscratch, t2 csrrw t3, scounteren, t3 csrrw t4, hstatus, t4 csrrw t5, sstatus, t5 sd t0, (HYP_G_SEPC)(a0) sd t2, (HYP_G_A + 0 * 8)(a0) sd t3, (HYP_G_SCOUNTEREN)(a0) sd t4, (HYP_G_HSTATUS)(a0) sd t5, (HYP_G_SSTATUS)(a0) ld ra, (HYP_H_RA)(a0) ld sp, (HYP_H_SP)(a0) ld tp, (HYP_H_TP)(a0) ld gp, (HYP_H_GP)(a0) ld s0, (HYP_H_S + 0 * 8)(a0) ld s1, (HYP_H_S + 1 * 8)(a0) ld s2, (HYP_H_S + 2 * 8)(a0) ld s3, (HYP_H_S + 3 * 8)(a0) ld s4, (HYP_H_S + 4 * 8)(a0) ld s5, (HYP_H_S + 5 * 8)(a0) ld s6, (HYP_H_S + 6 * 8)(a0) ld s7, (HYP_H_S + 7 * 8)(a0) ld s8, (HYP_H_S + 8 * 8)(a0) ld s9, (HYP_H_S + 9 * 8)(a0) ld s10, (HYP_H_S + 10 * 8)(a0) ld s11, (HYP_H_S + 11 * 8)(a0) ld a1, (HYP_H_A + 1 * 8)(a0) ld a2, (HYP_H_A + 2 * 8)(a0) ld a3, (HYP_H_A + 3 * 8)(a0) ld a4, (HYP_H_A + 4 * 8)(a0) ld a5, (HYP_H_A + 5 * 8)(a0) ld a6, (HYP_H_A + 6 * 8)(a0) ld a7, (HYP_H_A + 7 * 8)(a0) ret END(vmm_switch) ENTRY(vmm_unpriv_trap) csrr a1, sepc sd a1, HYP_TRAP_SEPC(a0) addi a1, a1, 4 /* Next instruction after hlvx.hu */ csrw sepc, a1 csrr a1, scause sd a1, HYP_TRAP_SCAUSE(a0) csrr a1, stval sd a1, HYP_TRAP_STVAL(a0) csrr a1, htval sd a1, HYP_TRAP_HTVAL(a0) csrr a1, htinst sd a1, HYP_TRAP_HTINST(a0) sret END(vmm_unpriv_trap)