gic_splfuncs_armv8.S revision 1.1
1/* $NetBSD: gic_splfuncs_armv8.S,v 1.1 2021/10/30 18:44:24 jmcneill Exp $ */ 2 3/*- 4 * Copyright (c) 2021 Jared McNeill <jmcneill@invisible.ca> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <machine/asm.h> 30#include "assym.h" 31 32RCSID("$NetBSD: gic_splfuncs_armv8.S,v 1.1 2021/10/30 18:44:24 jmcneill Exp $") 33 34/* 35 * int 36 * gic_splraise(int newipl) 37 * 38 * w0 = newipl 39 */ 40 .align 7 /* cacheline-aligned */ 41ENTRY_NP(gic_splraise) 42 /* Save cpu_info pointer in x1 */ 43 mrs x1, tpidr_el1 /* get curlwp */ 44 ldr x1, [x1, #L_CPU] /* get curcpu */ 45 46 /* If newipl > cpl, update cpl */ 47 ldr w2, [x1, #CI_CPL] 48 cmp w0, w2 49 b.le .Lnoraise 50 str w0, [x1, #CI_CPL] 51 52.Lnoraise: 53 mov w0, w2 /* return oldipl */ 54 ret 55END(gic_splraise) 56 57 58/* 59 * void 60 * gic_splx(int newipl) 61 * 62 * w0 = newipl 63 */ 64 .align 7 /* cacheline-aligned */ 65ENTRY_NP(gic_splx) 66 /* Save cpu_info pointer in x1 */ 67 mrs x1, tpidr_el1 /* get curlwp */ 68 ldr x1, [x1, #L_CPU] /* get curcpu */ 69 70 /* If newipl >= cpl, just return */ 71 ldr w2, [x1, #CI_CPL] 72 cmp w0, w2 73 b.hs .Ldone 74 75.Lagain: 76 /* Slow path if ci_intr_depth != 0 */ 77 ldr w2, [x1, #CI_INTR_DEPTH] 78 cbnz w2, .Lslow 79 80 /* Save newipl and restart address in cpu info */ 81 str w0, [x1, #CI_SPLX_SAVEDIPL] 82 adr x2, .Lrestart 83 str x2, [x1, #CI_SPLX_RESTART] 84 85 /* Slow path if hwpl > newipl */ 86 ldr w2, [x1, #CI_HWPL] 87 cmp w2, w0 88 b.hi .Lrestore 89 90 /* Update cpl */ 91 str w0, [x1, #CI_CPL] 92 93 /* Clear saved restart address from cpu info */ 94 str xzr, [x1, #CI_SPLX_RESTART] 95 96 /* Check for pending softints */ 97 ldr w2, [x1, #CI_SOFTINTS] 98 lsr w2, w2, w0 99 cbnz w2, _C_LABEL(dosoftints) 100 101.Ldone: 102 ret 103 104.Lrestart: 105 /* Reload w0 and x1 */ 106 mrs x1, tpidr_el1 /* get curlwp */ 107 ldr x1, [x1, #L_CPU] /* get curcpu */ 108 ldr w0, [x1, #CI_SPLX_SAVEDIPL] /* get newipl */ 109 b .Lagain 110 111.Lrestore: 112 /* Clear saved restart address from cpu info */ 113 str xzr, [x1, #CI_SPLX_RESTART] 114 115.Lslow: 116 /* Jump to slow path */ 117 b _C_LABEL(Xgic_splx) 118END(gic_splx) 119