/* $NetBSD: srt0.S,v 1.5 2014/08/07 13:56:57 joerg Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Steve C. Woodford. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #define STACK_SIZE 8192 /* * The main entry point when loaded by PPC-Bug. * * There are two possible entry conditions here: * * 1) We were booted in `PReP' mode, either from disk or the network. * In this case, we have no control over the load address so we * have to relocate ourselves to the appropriate place. * The firmware passes us the following registers: * * %r1 -> Temporary stack * %r3 -> Residual Data * %r4 -> The address we were loaded to * %r5 -> Zero * * 2) We were booted over the network in Non-PReP mode. In this case, * the load address is usually set using PPC-Bug's "niot" command, * but we won't depend on it so relocation may be required. The * firmware passes us the following registers: * * %r1 -> Temporary stack * %r3 -> CLUN of the network device we booted from * %r4 -> DLUN of the network device we booted from * %r5 -> Non-zero * %r6 -> Base address of network device * %r7 -> Execution address of loaded program * %r8 -> Address of IP-address data structure * %r9 -> Pointer to start of filename string * %r10 -> Pointer to end+1 of filename string * %r11 -> Pointer to start of argument string * %r12 -> Pointer to end+1 of argument string * * The obvious way to distinguish between the two boot modes is by * checking the value of %r5. */ ENTRY(_start) bl 1f 1: xor %r0,%r0,%r0 /* First, switch off Instruction and Data caches. */ mfspr %r13,SPR_HID0 LDCONST(%r14, HID0_DCE|HID0_ICE) andc %r13,%r13,%r14 sync mtspr SPR_HID0,%r13 /* * All registers now available. Let's see if we need to relocate */ LDCONST(%r13,_C_LABEL(_start)) /* Where we'd like to be */ LDCONST(%r14,_C_LABEL(edata)) /* End of data section */ LDCONST(%r15,0x3) add %r14,%r14,%r15 andc %r14,%r14,%r15 /* Rounded up to the nearest 32-bits */ sub %r15,%r14,%r13 /* Our size, in bytes */ mflr %r16 /* Get address we were loaded to */ subi %r16,%r16,0x4 /* Correct for branch */ cmpw %r13,%r16 /* Do we need to relocate? */ beq _ASM_LABEL(clrbss) /* No relocation necessary */ li %r17,0x4 bgt 1f /* Relocate using forward copy? */ /* Nope. Need to copy in reverse in case of overlap */ mr %r13,%r14 /* dest -> end */ add %r16,%r16,%r15 /* src + size */ subi %r17,%r17,0x8 /* Increment is -4 */ /* * Do the relocation * %r13 -> dest * %r15 -> number of bytes * %r16 -> src * %r17 -> Increment (+4 or -4) */ 1: srwi %r15,%r15,0x2 /* Convert length to 32-bit words */ mtctr %r15 /* Save in counter register */ 2: lwz %r15,0(%r16) stw %r15,0(%r13) add %r16,%r16,%r17 add %r13,%r13,%r17 bdnz 2b /* Now do an absolute jump to the relocated code */ LDCONST(%r13,_ASM_LABEL(clrbss)) mtlr %r13 blr ASENTRY(clrbss) LDCONST(%r13,_C_LABEL(edata)) /* End of the data section */ LDCONST(%r14,_C_LABEL(end)) /* End of BSS */ LDCONST(%r15,0x3) add %r14,%r14,%r15 andc %r14,%r14,%r15 /* Round-up end of BSS to 32-bits */ sub %r15,%r14,%r13 /* r15 == length of BSS */ srwi %r15,%r15,0x2 mtctr %r15 /* CTR == # of 32-bit words in BSS */ 1: stw %r0,0(%r13) /* Clear BSS */ addi %r13,%r13,4 bdnz 1b /* Fix up our own stack */ LDCONST(%r1,stack) addi %r1,%r1,STACK_SIZE-0x10 LDCONST(%r13,0x0f) andc %r1,%r1,%r13 /* * Copy the arguments passed in from Bug into bug_bootinfo * * See bugsyscalls.h for details. */ LDCONST(%r13,_C_LABEL(bug_bootinfo)) stw %r5,0x00(%r13) stw %r3,0x04(%r13) stw %r4,0x08(%r13) stw %r6,0x0c(%r13) stw %r7,0x10(%r13) stw %r8,0x14(%r13) stw %r9,0x18(%r13) stw %r10,0x1c(%r13) stw %r11,0x20(%r13) stw %r12,0x24(%r13) mr %r3,%r13 bl _C_LABEL(main) /* void main(void) */ /* FALLTHROUGH */ /* * Return to the debugger, either because main() returned or via panic(). */ ENTRY(_rtt) addi %r10,0,0x0063 sc 1: nop b 1b /* * C code runs on this stack. */ .comm stack,STACK_SIZE,4 .comm errno,4,4 .comm debug,4,4