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