2 * Copyright (C) 2010 Nathan Whitehorn
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <machine/trap_aim.h>
31 * KBoot and simulators will start this program from the _start symbol, with
32 * r3 pointing to a flattened device tree (kexec), r4 the physical address
33 * at which we were loaded, and r5 0 (kexec) or a pointer to Open Firmware
34 * (simulator). If r4 is non-zero, the first order of business is relocating
35 * ourselves to 0. In the kboot case, the PPE secondary thread will enter
38 * If started directly by the LV1 hypervisor, we are loaded to address 0
39 * and execution on both threads begins at 0x100 (EXC_RST).
42 #define CACHELINE_SIZE 128
45 /* KBoot thread 0 entry -- do relocation, then jump to main */
59 .global secondary_spin_sem
70 ba thread1_start /* kboot copies the first 256 bytes to
71 * address 0, so we are safe to jump
75 li %r3,secondary_spin_sem@l
76 1: lwz %r1,0(%r3) /* Spin on SECONDARY_SPIN_SEM_ADDRESS */
78 beq 1b /* If the semaphore is still zero, spin again */
80 /* We have been woken up by thread 0 */
81 li %r0,0x100 /* Invalidate reset vector cache line */
85 ba 0x100 /* Jump to the reset vector */
95 /* The first two bits of r0 are 01 (thread 1) or 10 (thread 0) */
96 cntlzw %r3,%r3 /* Now 0 for thread 0, 1 for thread 1 */
99 bne thread1_start /* Send thread 1 to wait */
101 b relocated_start /* Main entry point for thread 0 */
103 #define EXCEPTION_HANDLER(exc) \
114 EXCEPTION_HANDLER(EXC_MCHK)
115 EXCEPTION_HANDLER(EXC_DSI)
116 EXCEPTION_HANDLER(EXC_DSE)
117 EXCEPTION_HANDLER(EXC_ISI)
118 EXCEPTION_HANDLER(EXC_ISE)
119 EXCEPTION_HANDLER(EXC_EXI)
120 EXCEPTION_HANDLER(EXC_ALI)
121 EXCEPTION_HANDLER(EXC_PGM)
122 EXCEPTION_HANDLER(EXC_FPU)
123 EXCEPTION_HANDLER(EXC_DECR)
124 EXCEPTION_HANDLER(EXC_SC)
127 /* We enter this with r4 the physical offset for our relocation */
128 lis %r8,_end@ha /* r8: copy length */
130 li %r5,0x100 /* r5: dest address */
131 1: add %r6,%r4,%r5 /* r6: source address */
139 * Now invalidate the cacheline with the second half of relocate_self,
140 * and do an absolute branch there in case we overwrote part of
144 lis %r9,relocate_self_cache@ha
145 addi %r9,%r9,relocate_self_cache@l
151 ba relocate_self_cache
154 /* Now invalidate the icache */
162 addi %r5,%r5,CACHELINE_SIZE
165 /* All done: absolute jump to relocated entry point */