1/* $NetBSD: 4xx_locore.S,v 1.1 2002/08/23 11:37:55 scw Exp $ */ 2 3/* 4 * Copyright 2001 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38/* 39 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 40 * Copyright (C) 1995, 1996 TooLs GmbH. 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed by TooLs GmbH. 54 * 4. The name of TooLs GmbH may not be used to endorse or promote products 55 * derived from this software without specific prior written permission. 56 * 57 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 58 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 59 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 60 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 61 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 62 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 63 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 64 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 65 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 66 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 67 */ 68 69/* 70 * This is not a standalone file. To use it, #inlcude it at 71 * the end of your port's locore.S 72 */ 73 74/* 75 * Taken straight from Walnut's locore.S, with the following attribution: 76 * $OpenBSD: locore.S,v 1.4 1997/01/26 09:06:38 rahnds Exp $ 77 */ 78 79/* 80 * No processes are runnable, so loop waiting for one. 81 * Separate label here for accounting purposes. 82 * When we get here, interrupts are off (MSR[EE]=0) and sched_lock is held. 83 */ 84ASENTRY(Idle) 85 lis 8,_C_LABEL(sched_whichqs)@ha 86 lwz 9,_C_LABEL(sched_whichqs)@l(8) 87 88 or. 9,9,9 89 bne- .Lsw1 /* at least one queue non-empty */ 90 91 wrteei 1 /* reenable ints again */ 92 93/* May do some power saving here? */ 94/* Check if we can use power saving mode */ 95 lis 8,_C_LABEL(powersave)@ha 96 lwz 9,_C_LABEL(powersave)@l(8) 97 98 or. 9,9,9 99 beq 1f 100 101 /* TODO: Enter power saving mode here */ 1021: 103 104 wrteei 0 /* disable interrupts while manipulating runque */ 105 106 b _ASM_LABEL(Idle) 107 108/* 109 * switchexit gets called from cpu_exit to complete the exit procedure. 110 */ 111ENTRY(switchexit) 112/* First switch to the idle pcb/kernel stack */ 113 lis 6,idle_u@ha 114 lwz 6,idle_u@l(6) 115 lis 7,_C_LABEL(curpcb)@ha 116 stw 6,_C_LABEL(curpcb)@l(7) 117 addi 1,6,USPACE-16 /* 16 bytes are reserved at stack top */ 118 /* 119 * Schedule the vmspace and stack to be freed (the proc arg is 120 * already in r3). 121 */ 122 bl _C_LABEL(exit2) 123 124/* Fall through to cpu_switch to actually select another proc */ 125 li 3,0 /* indicate exited process */ 126 127/* 128 * void cpu_switch(struct proc *p) 129 * Find a runnable process and switch to it. 130 */ 131/* XXX noprofile? --thorpej@netbsd.org */ 132ENTRY(cpu_switch) 133 mflr 0 /* save lr */ 134 stw 0,4(1) 135 stwu 1,-16(1) 136 stw 31,12(1) 137 stw 30,8(1) 138 139 mr 30,3 140 lis 3,_C_LABEL(curproc)@ha 141 xor 31,31,31 142 stw 31,_C_LABEL(curproc)@l(3) /* Zero to not accumulate cpu time */ 143 lis 3,_C_LABEL(curpcb)@ha 144 lwz 31,_C_LABEL(curpcb)@l(3) 145 146 xor 3,3,3 147 bl _C_LABEL(lcsplx) 148 stw 3,PCB_SPL(31) /* save spl */ 149 150 wrteei 0 /* disable interrupts while manipulating runque */ 151 152/* Find a new process */ 153 lis 8,_C_LABEL(sched_whichqs)@ha 154 lwz 9,_C_LABEL(sched_whichqs)@l(8) 155 156 or. 9,9,9 157 beq- _ASM_LABEL(Idle) /* all queues empty */ 158.Lsw1: 159 cntlzw 10,9 160 lis 4,_C_LABEL(sched_qs)@ha 161 addi 4,4,_C_LABEL(sched_qs)@l 162 slwi 3,10,3 163 add 3,3,4 /* select queue */ 164 165 lwz 31,P_FORW(3) /* unlink first proc from queue */ 166 lwz 4,P_FORW(31) 167 stw 4,P_FORW(3) 168 stw 3,P_BACK(4) 169 170 cmpl 0,3,4 /* queue empty? */ 171 bne 1f 172 173 lis 3,0x80000000@h 174 srw 3,3,10 175 andc 9,9,3 176 stw 9,_C_LABEL(sched_whichqs)@l(8) /* mark it empty */ 177 1781: 179 /* just did this resched thing */ 180 xor 3,3,3 181 lis 4,_C_LABEL(want_resched)@ha 182 stw 3,_C_LABEL(want_resched)@l(4) 183 184 stw 3,P_BACK(31) /* probably superfluous */ 185 186 /* Process now running on a processor. */ 187 li 3,SONPROC /* p->p_stat = SONPROC */ 188 stb 3,P_STAT(31) 189 190 /* record new process */ 191 lis 4,_C_LABEL(curproc)@ha 192 stw 31,_C_LABEL(curproc)@l(4) 193 194 wrteei 1 /* Now we can interrupt again */ 195 196 cmpl 0,31,30 /* is it the same process? */ 197 beq switch_return 198 199 or. 30,30,30 /* old process was exiting? */ 200 beq switch_exited 201 202#ifndef PPC_IBM4XX 203 mfsr 10,USER_SR /* save USER_SR for copyin/copyout */ 204#else 205 li 10,0 /* no SR for 4xx CPUs */ 206#endif 207 mfcr 11 /* save cr */ 208 mr 12,2 /* save r2 */ 209 stwu 1,-SFRAMELEN(1) /* still running on old stack */ 210 stmw 10,8(1) 211 lwz 3,P_ADDR(30) 212 stw 1,PCB_SP(3) /* save SP */ 213 214switch_exited: 215 wrteei 0 /* disable interrupts while actually switching */ 216 217 /* indicate new pcb */ 218 lwz 4,P_ADDR(31) 219 lis 5,_C_LABEL(curpcb)@ha 220 stw 4,_C_LABEL(curpcb)@l(5) 221 222 /* save real pmap pointer for spill fill */ 223 lwz 5,PCB_PMR(4) 224 lis 6,_C_LABEL(curpm)@ha 225 stwu 5,_C_LABEL(curpm)@l(6) 226 stwcx. 5,0,6 /* clear possible reservation */ 227 228 /* Switch to the new virtual space */ 229 /* Do not have to do anything here. TLB PID gets updated on return from trap. */ 230 231 lwz 1,PCB_SP(4) /* get new procs SP */ 232 233 wrteei 1 /* interrupts are okay again */ 234 235 lmw 10,8(1) /* get other regs */ 236 lwz 1,0(1) /* get saved SP */ 237 mr 2,12 /* get saved r2 */ 238 mtcr 11 /* get saved cr */ 239 isync 240 241switch_return: 242 mr 30,7 /* save proc pointer */ 243 244 lwz 3,PCB_SPL(4) 245 bl _C_LABEL(lcsplx) 246 2470: 248 lis 3,_C_LABEL(curpm)@ha 249 addi 3,3,_C_LABEL(curpm)@l /* Do we need a context? */ 250 lwz 4,PM_CTX(3) 251 cmpwi 4,0 252# mtspr SPR_SPR0,4 /* Always keep the current ctx here */ 253 mr 3,30 254 bne 1f 255 bl _C_LABEL(ctx_alloc) 256 mr 3,30 /* get curproc for special fork 257 returns */ 258 b 0b /* Reload */ 2591: 260 lwz 31,12(1) 261 lwz 30,8(1) 262 addi 1,1,16 263 lwz 0,4(1) 264 mtlr 0 265 blr 266 267/* 268 * Child comes here at the end of a fork. 269 * Return to userspace via the trap return path. 270 */ 271 .globl _C_LABEL(fork_trampoline) 272_C_LABEL(fork_trampoline): 273 xor 3,3,3 274 bl _C_LABEL(lcsplx) 275 mtlr 31 276 mr 3,30 277 blrl /* jump indirect to r31 */ 278 b trapexit 279 280/* 281 * Pull in common trap vector code. 282 */ 283#include <powerpc/ibm4xx/trap_subr.S> 284#include <powerpc/ibm4xx/4xx_trap_subr.S> 285 286/* 287 * int setfault() 288 * 289 * Similar to setjmp to setup for handling faults on accesses to user memory. 290 * Any routine using this may only call bcopy, either the form below, 291 * or the (currently used) C code optimized, so it doesn't use any non-volatile 292 * registers. 293 */ 294 .globl _C_LABEL(setfault) 295_C_LABEL(setfault): 296 mflr 0 297 mfcr 12 298 lis 4,_C_LABEL(curpcb)@ha 299 lwz 4,_C_LABEL(curpcb)@l(4) 300 stw 3,PCB_FAULT(4) 301 stw 0,0(3) 302 stw 1,4(3) 303 stw 2,8(3) 304 stmw 12,12(3) 305 xor 3,3,3 306 blr 307 308 .globl _C_LABEL(ppc4xx_reset) 309_C_LABEL(ppc4xx_reset): 310 mfspr 3,SPR_DBCR0 311 oris 3,r13,DBCR0_RST_SYSTEM@h 312 mtspr SPR_DBCR0,3 313 ba 0 314 315#if 0 316/* 317 * XXXX the following doesn't quite work right yet. 318 */ 319/* 320 * void bcopy(const void *src, void *dst, size_t len); 321 * 322 * swap r3 and r4 and fall through to memcopy. 323 */ 324 .globl _C_LABEL(bcopy) 325_C_LABEL(bcopy): 326 mr r0,r3 327 mr r3,r4 328 mr r4,r0 329 /* FALLTHROUGH */ 330 331/* 332 * void * memcpy(void *dst (r3), const void *src (r4), size_t len (r5)); 333 * 334 * Copy memory (obviously) 335 * 336 * We will try to do data cache block aligned stores so we 337 * can use block allocate and not have to read from the 338 * destination. 339 * 340 * Register use: 341 * 342 * r1 stack (of course) 343 * r3 dst 344 * r4 src 345 * r5 len 346 * r6 tmp 347 * r7 holds 32 348 * r8 holds dst 349 * r24-r31 block move regs 350 * 351 */ 352 353ENTRY(memcpy) 354 stwu r1,-(10*4)(r1) /* Allocate some RAM to save 8 regs to. */ 355 cmpwi r5, 32 /* Less than 32 bytes ? */ 356 stmw r24,8(r1) /* Save ALL regs (could be optimized) */ 357 358 mr r8,r3 /* save dst */ 359 li r7,32 360 361 dcbt 0,r4 /* Start bringing in cache line. */ 362 blt 1f /* Finish up */ 363 364 neg r6,r3 /* Find how far unaligned we are... */ 365 andi. r6,r6,31 /* Cache-align dest. */ 366 mtxer r6 367 sub r5,r5,r6 /* subtract count */ 368 lswx r24,0,r4 /* Load some. */ 369 add r4,r4,r6 370 dcbt 0,r4 /* Fetch next line */ 371 stswx r24,0,r3 /* Store some */ 372 add r3,r3,r6 373 addic. r6,r5,-32 /* Pre-decrement next line */ 374 ble 1f /* Less than 32-bytes? finishup */ 375 376 /* Dest should not be cache line aligned. */ 377 /* XXX need gas 2.11 to grok dcba insn */ 378#ifdef GAS_2_11 379 dcba 0,r3 /* Allocate a line */ 380#else 381 .long 0x7c001dec /* dcba 0,r3 */ 382#endif 3830: 384 dcbt r7,r4 /* Bring in the next line, too */ 385 386 lswi r24,r4,32 387 addi r4,r4,32 /* Inc src */ 388 mr r5,r6 389 390 addic. r6,r5,-32 391 stswi r24,r3,32 392 addi r3,r3,32 /* Inc dst */ 393#ifdef GAS_2_11 394 dcba 0,r3 /* Allocate another line */ 395#else 396 .long 0x7c071dec /* dcba r7,r3 */ 397#endif 398 bgt 0b 3991: 400 mtxer r5 /* Store byte count */ 401 lswx r24,0,r4 /* Load up to 32 bytes */ 402 stswx r24,0,r3 /* Store up to 32 bytes */ 403 404 mr r3,r8 /* Return dst */ 405 406 lmw r24,8(r1) 407 addi r1,r1,(10*4) 408 blr 409#endif 410