Home | History | Annotate | Line # | Download | only in ibm4xx
4xx_locore.S revision 1.1
      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  */
     84 ASENTRY(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 */
    102 1:
    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  */
    111 ENTRY(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 (at) netbsd.org */
    132 ENTRY(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 
    178 1:
    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 
    214 switch_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 
    241 switch_return:
    242 	mr	30,7			/* save proc pointer */
    243 
    244 	lwz	3,PCB_SPL(4)
    245 	bl	_C_LABEL(lcsplx)
    246 
    247 0:
    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 */
    259 1:
    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 
    353 ENTRY(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
    383 0:
    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
    399 1:
    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