/* $NetBSD: gic_splfuncs_armv8.S,v 1.1 2021/10/30 18:44:24 jmcneill Exp $ */ /*- * Copyright (c) 2021 Jared McNeill * All rights reserved. * * 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 THE AUTHOR ``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 THE AUTHOR 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.h" RCSID("$NetBSD: gic_splfuncs_armv8.S,v 1.1 2021/10/30 18:44:24 jmcneill Exp $") /* * int * gic_splraise(int newipl) * * w0 = newipl */ .align 7 /* cacheline-aligned */ ENTRY_NP(gic_splraise) /* Save cpu_info pointer in x1 */ mrs x1, tpidr_el1 /* get curlwp */ ldr x1, [x1, #L_CPU] /* get curcpu */ /* If newipl > cpl, update cpl */ ldr w2, [x1, #CI_CPL] cmp w0, w2 b.le .Lnoraise str w0, [x1, #CI_CPL] .Lnoraise: mov w0, w2 /* return oldipl */ ret END(gic_splraise) /* * void * gic_splx(int newipl) * * w0 = newipl */ .align 7 /* cacheline-aligned */ ENTRY_NP(gic_splx) /* Save cpu_info pointer in x1 */ mrs x1, tpidr_el1 /* get curlwp */ ldr x1, [x1, #L_CPU] /* get curcpu */ /* If newipl >= cpl, just return */ ldr w2, [x1, #CI_CPL] cmp w0, w2 b.hs .Ldone .Lagain: /* Slow path if ci_intr_depth != 0 */ ldr w2, [x1, #CI_INTR_DEPTH] cbnz w2, .Lslow /* Save newipl and restart address in cpu info */ str w0, [x1, #CI_SPLX_SAVEDIPL] adr x2, .Lrestart str x2, [x1, #CI_SPLX_RESTART] /* Slow path if hwpl > newipl */ ldr w2, [x1, #CI_HWPL] cmp w2, w0 b.hi .Lrestore /* Update cpl */ str w0, [x1, #CI_CPL] /* Clear saved restart address from cpu info */ str xzr, [x1, #CI_SPLX_RESTART] /* Check for pending softints */ ldr w2, [x1, #CI_SOFTINTS] lsr w2, w2, w0 cbnz w2, _C_LABEL(dosoftints) .Ldone: ret .Lrestart: /* Reload w0 and x1 */ mrs x1, tpidr_el1 /* get curlwp */ ldr x1, [x1, #L_CPU] /* get curcpu */ ldr w0, [x1, #CI_SPLX_SAVEDIPL] /* get newipl */ b .Lagain .Lrestore: /* Clear saved restart address from cpu info */ str xzr, [x1, #CI_SPLX_RESTART] .Lslow: /* Jump to slow path */ b _C_LABEL(Xgic_splx) END(gic_splx)