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