xref: /openbsd/sys/arch/arm/arm/cpuswitch7.S (revision bb00e811)
1/*	$OpenBSD: cpuswitch7.S,v 1.18 2023/10/24 13:20:09 claudio Exp $	*/
2/*	$NetBSD: cpuswitch.S,v 1.41 2003/11/15 08:44:18 scw Exp $	*/
3
4/*
5 * Copyright 2003 Wasabi Systems, Inc.
6 * All rights reserved.
7 *
8 * Written by Steve C. Woodford for Wasabi Systems, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *      This product includes software developed for the NetBSD Project by
21 *      Wasabi Systems, Inc.
22 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
23 *    or promote products derived from this software without specific prior
24 *    written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38/*
39 * Copyright (c) 1994-1998 Mark Brinicombe.
40 * Copyright (c) 1994 Brini.
41 * All rights reserved.
42 *
43 * This code is derived from software written for Brini by Mark Brinicombe
44 *
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
47 * are met:
48 * 1. Redistributions of source code must retain the above copyright
49 *    notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 *    notice, this list of conditions and the following disclaimer in the
52 *    documentation and/or other materials provided with the distribution.
53 * 3. All advertising materials mentioning features or use of this software
54 *    must display the following acknowledgement:
55 *	This product includes software developed by Brini.
56 * 4. The name of the company nor the name of the author may be used to
57 *    endorse or promote products derived from this software without specific
58 *    prior written permission.
59 *
60 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
61 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
62 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
63 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
64 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
66 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70 * SUCH DAMAGE.
71 *
72 * RiscBSD kernel project
73 *
74 * cpuswitch.S
75 *
76 * cpu switching functions
77 *
78 * Created      : 15/10/94
79 */
80
81#include "assym.h"
82
83#include <machine/frame.h>
84#include <machine/intr.h>
85#include <machine/asm.h>
86#include <arm/armreg.h>
87#include <arm/sysreg.h>
88
89/* LINTSTUB: include <sys/param.h> */
90
91#define IRQdisableALL \
92	cpsid	if
93
94#define IRQenableALL \
95	cpsie	if
96
97	.text
98
99.Lcpufuncs:
100	.word	cpufuncs
101
102.Lcpu_do_powersave:
103	.word	cpu_do_powersave
104
105/*
106 * Idle loop, exercised while waiting for a process to wake up.
107 */
108ENTRY(cpu_idle_enter)
109	mov	pc, lr
110
111ENTRY(cpu_idle_cycle)
112	stmfd	sp!, {r6, lr}
113
114	ldr	r6, .Lcpu_do_powersave
115	ldr	r6, [r6]		/* r6 = cpu_do_powersave */
116
117	teq	r6, #0			/* cpu_do_powersave non zero? */
118	ldrne	r6, .Lcpufuncs
119	ldrne	r6, [r6, #(CF_SLEEP)]
120
121	teq	r6, #0			/* Powersave idle? */
122	beq	.Lidle_return		/* Nope. Just continue. */
123
124	/*
125	 * Before going into powersave idle mode, disable interrupts.
126	 */
127	IRQdisableALL
128	mov	lr, pc
129	mov	pc, r6			/* If so, do powersave idle */
130	IRQenableALL
131
132.Lidle_return:
133	ldmfd	sp!, {r6, pc}
134
135ENTRY(cpu_idle_leave)
136	mov	pc, lr
137
138
139/*
140 * cpu_switchto(struct proc *oldproc, struct proc *newproc)
141 *
142 * Performs a process context switch from oldproc (which may be NULL)
143 * to newproc.
144 *
145 * Arguments:
146 *	r0	'struct proc *' of the context to switch from
147 *	r1	'struct proc *' of the context to switch to
148 */
149
150ENTRY(cpu_switchto)
151	/* check if old context needs to be saved */
152	teq	r0, #0
153	beq	1f
154
155	/* create switchframe */
156	stmfd	sp!, {r4-r7, lr}
157	sub	sp, sp, #4
158
159	mrc	CP15_TPIDRPRW(r2)		/* load curcpu */
160	ldr	r5, [r2, #(CI_CURPCB)]
161
162	/* save old stack pointer */
163	mrs	r3, cpsr
164	cpsid	i, #(PSR_UND32_MODE)
165	str	sp, [r5, #(PCB_UND_SP)]
166	msr	cpsr_c, r3
167
168	add	r6, r5, #(PCB_R8)
169	stmia	r6, {r8-r13}
170
1711:
172	mrc	CP15_TPIDRPRW(r2)		/* load curcpu */
173	mov	r5, #SONPROC
174	strb	r5, [r1, #(P_STAT)]		/* mark new on cpu */
175	str	r2, [r1, #(P_CPU)]
176	ldr	r5, [r1, #(P_ADDR)]		/* load new pcb */
177	str	r5, [r2, #(CI_CURPCB)]
178	str	r1, [r2, #(CI_CURPROC)]
179
180	ldr	r4, [r5, #(PCB_TCB)]
181	mcr	CP15_TPIDRURO(r4)		/* load user tls */
182
183	add	r6, r5, #PCB_R8
184	ldmia	r6, {r8-r13}
185
186	/* load new stack pointer */
187	mrs	r3, cpsr
188	cps	#(PSR_UND32_MODE)
189	ldr	sp, [r5, #(PCB_UND_SP)]
190	msr	cpsr_c, r3
191
192	IRQdisableALL
193
194	ldr	r0, [r5, #(PCB_PAGEDIR)]
195	ldr	r3, .Lcpufuncs
196	mov	lr, pc
197	ldr	pc, [r3, #CF_CONTEXT_SWITCH]
198
199	IRQenableALL
200
201	add	sp, sp, #4
202	ldmfd	sp!, {r4-r7, pc}
203
204
205ENTRY(savectx)
206	/*
207	 * r0 = pcb
208	 */
209
210	/* Push registers.*/
211	stmfd	sp!, {r4-r7, lr}
212	sub	sp, sp, #4
213
214	/* Store all the registers in the process's pcb */
215	add	r2, r0, #(PCB_R8)
216	stmia	r2, {r8-r13}
217
218	/* Pull the regs of the stack */
219	add	sp, sp, #4
220	ldmfd	sp!, {r4-r7, pc}
221
222
223ENTRY(proc_trampoline)
224	bl	proc_trampoline_mi
225
226	mov	r0, r5
227	mov	r1, sp
228	mov	lr, pc
229	mov	pc, r4
230
231	/* Kill irq's */
232	cpsid	i
233
234	PULLFRAME
235
236	movs	pc, lr			/* Exit */
237	dsb	nsh
238	isb
239