/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2021 Andrew Turner4* Copyright (c) 2024 Arm Ltd5*6* This work was supported by Innovate UK project 105694, "Digital Security7* by Design (DSbD) Technology Platform Prototype".8*9* Redistribution and use in source and binary forms, with or without10* modification, are permitted provided that the following conditions11* are met:12* 1. Redistributions of source code must retain the above copyright13* notice, this list of conditions and the following disclaimer.14* 2. Redistributions in binary form must reproduce the above copyright15* notice, this list of conditions and the following disclaimer in the16* documentation and/or other materials provided with the distribution.17*18* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND19* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE22* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL23* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS24* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)25* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT26* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY27* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF28* SUCH DAMAGE.29*/3031#define VMM_STATIC static32#define VMM_HYP_FUNC(func) vmm_nvhe_ ## func3334#define guest_or_nonvhe(guest) (true)35#define EL1_REG(reg) MRS_REG_ALT_NAME(reg ## _EL1)36#define EL0_REG(reg) MRS_REG_ALT_NAME(reg ## _EL0)3738#include "vmm_hyp.c"3940uint64_t vmm_hyp_enter(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,41uint64_t, uint64_t, uint64_t);4243/*44* Handlers for EL2 addres space. Only needed by non-VHE code as in VHE the45* kernel is in EL2 so pmap will manage the address space.46*/47static int48vmm_dc_civac(uint64_t start, uint64_t len)49{50size_t line_size, end;51uint64_t ctr;5253ctr = READ_SPECIALREG(ctr_el0);54line_size = sizeof(int) << CTR_DLINE_SIZE(ctr);55end = start + len;56dsb(ishst);57/* Clean and Invalidate the D-cache */58for (; start < end; start += line_size)59__asm __volatile("dc civac, %0" :: "r" (start) : "memory");60dsb(ish);61return (0);62}6364static int65vmm_el2_tlbi(uint64_t type, uint64_t start, uint64_t len)66{67uint64_t end, r;6869dsb(ishst);70switch (type) {71default:72case HYP_EL2_TLBI_ALL:73__asm __volatile("tlbi alle2" ::: "memory");74break;75case HYP_EL2_TLBI_VA:76end = TLBI_VA(start + len);77start = TLBI_VA(start);78for (r = start; r < end; r += TLBI_VA_L3_INCR) {79__asm __volatile("tlbi vae2is, %0" :: "r"(r));80}81break;82}83dsb(ish);8485return (0);86}8788uint64_t89vmm_hyp_enter(uint64_t handle, uint64_t x1, uint64_t x2, uint64_t x3,90uint64_t x4, uint64_t x5, uint64_t x6, uint64_t x7)91{92switch (handle) {93case HYP_ENTER_GUEST:94return (VMM_HYP_FUNC(enter_guest)((struct hyp *)x1,95(struct hypctx *)x2));96case HYP_READ_REGISTER:97return (VMM_HYP_FUNC(read_reg)(x1));98case HYP_CLEAN_S2_TLBI:99VMM_HYP_FUNC(clean_s2_tlbi());100return (0);101case HYP_DC_CIVAC:102return (vmm_dc_civac(x1, x2));103case HYP_EL2_TLBI:104return (vmm_el2_tlbi(x1, x2, x3));105case HYP_S2_TLBI_RANGE:106VMM_HYP_FUNC(s2_tlbi_range)(x1, x2, x3, x4);107return (0);108case HYP_S2_TLBI_ALL:109VMM_HYP_FUNC(s2_tlbi_all)(x1);110return (0);111case HYP_CLEANUP: /* Handled in vmm_hyp_exception.S */112default:113break;114}115116return (0);117}118119120