Home | History | Annotate | Line # | Download | only in libsa
srt0.S revision 1.5
      1 /*	$NetBSD: srt0.S,v 1.5 2014/08/07 13:56:57 joerg Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2002 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Steve C. Woodford.
      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  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <machine/asm.h>
     33 #include <machine/psl.h>
     34 #include <powerpc/spr.h>
     35 #include <powerpc/oea/spr.h>
     36 
     37 #define	STACK_SIZE	8192
     38 
     39 /*
     40  * The main entry point when loaded by PPC-Bug.
     41  *
     42  * There are two possible entry conditions here:
     43  *
     44  *   1) We were booted in `PReP' mode, either from disk or the network.
     45  *      In this case, we have no control over the load address so we
     46  *      have to relocate ourselves to the appropriate place.
     47  *      The firmware passes us the following registers:
     48  *
     49  *        %r1  -> Temporary stack
     50  *        %r3  -> Residual Data
     51  *        %r4  -> The address we were loaded to
     52  *        %r5  -> Zero
     53  *
     54  *   2) We were booted over the network in Non-PReP mode. In this case,
     55  *      the load address is usually set using PPC-Bug's "niot" command,
     56  *      but we won't depend on it so relocation may be required. The
     57  *      firmware passes us the following registers:
     58  *
     59  *        %r1  -> Temporary stack
     60  *        %r3  -> CLUN of the network device we booted from
     61  *        %r4  -> DLUN of the network device we booted from
     62  *        %r5  -> Non-zero
     63  *        %r6  -> Base address of network device
     64  *        %r7  -> Execution address of loaded program
     65  *        %r8  -> Address of IP-address data structure
     66  *        %r9  -> Pointer to start of filename string
     67  *        %r10 -> Pointer to end+1 of filename string
     68  *        %r11 -> Pointer to start of argument string
     69  *        %r12 -> Pointer to end+1 of argument string
     70  *
     71  * The obvious way to distinguish between the two boot modes is by
     72  * checking the value of %r5.
     73  */
     74 ENTRY(_start)
     75 	bl	1f
     76 1:	xor	%r0,%r0,%r0
     77 
     78 	/* First, switch off Instruction and Data caches. */
     79 	mfspr	%r13,SPR_HID0
     80 	LDCONST(%r14, HID0_DCE|HID0_ICE)
     81 	andc	%r13,%r13,%r14
     82 	sync
     83 	mtspr	SPR_HID0,%r13
     84 
     85 
     86 	/*
     87 	 * All registers now available. Let's see if we need to relocate
     88 	 */
     89 	LDCONST(%r13,_C_LABEL(_start))	/* Where we'd like to be */
     90 	LDCONST(%r14,_C_LABEL(edata))	/* End of data section */
     91 	LDCONST(%r15,0x3)
     92 	add	%r14,%r14,%r15
     93 	andc	%r14,%r14,%r15		/* Rounded up to the nearest 32-bits */
     94 	sub	%r15,%r14,%r13		/* Our size, in bytes */
     95 	mflr	%r16			/* Get address we were loaded to */
     96 	subi	%r16,%r16,0x4		/* Correct for branch */
     97 	cmpw	%r13,%r16		/* Do we need to relocate? */
     98 	beq	_ASM_LABEL(clrbss)	/* No relocation necessary */
     99 	li	%r17,0x4
    100 	bgt	1f			/* Relocate using forward copy? */
    101 
    102 	/* Nope. Need to copy in reverse in case of overlap */
    103 	mr	%r13,%r14		/* dest -> end */
    104 	add	%r16,%r16,%r15		/* src + size */
    105 	subi	%r17,%r17,0x8		/* Increment is -4 */
    106 
    107 	/*
    108 	 * Do the relocation
    109 	 *  %r13  -> dest
    110 	 *  %r15  -> number of bytes
    111 	 *  %r16  -> src
    112 	 *  %r17  -> Increment (+4 or -4)
    113 	 */
    114 1:	srwi	%r15,%r15,0x2		/* Convert length to 32-bit words */
    115 	mtctr	%r15			/* Save in counter register */
    116 
    117 2:	lwz	%r15,0(%r16)
    118 	stw	%r15,0(%r13)
    119 	add	%r16,%r16,%r17
    120 	add	%r13,%r13,%r17
    121 	bdnz	2b
    122 
    123 	/* Now do an absolute jump to the relocated code */
    124 	LDCONST(%r13,_ASM_LABEL(clrbss))
    125 	mtlr	%r13
    126 	blr
    127 
    128 ASENTRY(clrbss)
    129 	LDCONST(%r13,_C_LABEL(edata))	/* End of the data section */
    130 	LDCONST(%r14,_C_LABEL(end))	/* End of BSS */
    131 	LDCONST(%r15,0x3)
    132 	add	%r14,%r14,%r15
    133 	andc	%r14,%r14,%r15		/* Round-up end of BSS to 32-bits */
    134 	sub	%r15,%r14,%r13		/* r15 == length of BSS */
    135 	srwi	%r15,%r15,0x2
    136 	mtctr	%r15			/* CTR == # of 32-bit words in BSS */
    137 1:	stw	%r0,0(%r13)		/* Clear BSS */
    138 	addi	%r13,%r13,4
    139 	bdnz	1b
    140 
    141 	/* Fix up our own stack */
    142 	LDCONST(%r1,stack)
    143 	addi	%r1,%r1,STACK_SIZE-0x10
    144 	LDCONST(%r13,0x0f)
    145 	andc	%r1,%r1,%r13
    146 
    147 	/*
    148 	 * Copy the arguments passed in from Bug into bug_bootinfo
    149 	 *
    150 	 * See bugsyscalls.h for details.
    151 	 */
    152 	LDCONST(%r13,_C_LABEL(bug_bootinfo))
    153 	stw	%r5,0x00(%r13)
    154 	stw	%r3,0x04(%r13)
    155 	stw	%r4,0x08(%r13)
    156 	stw	%r6,0x0c(%r13)
    157 	stw	%r7,0x10(%r13)
    158 	stw	%r8,0x14(%r13)
    159 	stw	%r9,0x18(%r13)
    160 	stw	%r10,0x1c(%r13)
    161 	stw	%r11,0x20(%r13)
    162 	stw	%r12,0x24(%r13)
    163 
    164 	mr	%r3,%r13
    165 	bl	_C_LABEL(main)		/* void main(void) */
    166 	/* FALLTHROUGH */
    167 
    168 /*
    169  * Return to the debugger, either because main() returned or via panic().
    170  */
    171 ENTRY(_rtt)
    172 	addi	%r10,0,0x0063
    173 	sc
    174 1:	nop
    175 	b	1b
    176 
    177 	/*
    178 	 * C code runs on this stack.
    179 	 */
    180 	.comm	stack,STACK_SIZE,4
    181 	.comm	errno,4,4
    182 	.comm	debug,4,4
    183