]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/boot/powerpc/ps3/start.S
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / boot / powerpc / ps3 / start.S
1 /*-
2  * Copyright (C) 2010 Nathan Whitehorn
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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.
24  *
25  * $FreeBSD$
26  */
27
28 #define LOCORE
29
30 #include <machine/trap_aim.h>
31
32 /*
33  * KBoot and simulators will start this program from the _start symbol, with
34  * r3 pointing to a flattened device tree (kexec), r4 the physical address
35  * at which we were loaded, and r5 0 (kexec) or a pointer to Open Firmware
36  * (simulator). If r4 is non-zero, the first order of business is relocating
37  * ourselves to 0. In the kboot case, the PPE secondary thread will enter
38  * at 0x60.
39  *
40  * If started directly by the LV1 hypervisor, we are loaded to address 0
41  * and execution on both threads begins at 0x100 (EXC_RST).
42  */
43
44 #define CACHELINE_SIZE                  128
45 #define SPR_CTRL                        136
46
47 /* KBoot thread 0 entry -- do relocation, then jump to main */
48 .global _start
49 _start:
50         mfmsr   %r31
51         clrldi  %r31,%r31,1
52         mtmsrd  %r31
53         isync
54         cmpwi   %r4,0
55         bne     relocate_self
56 relocated_start:
57         lis     %r1,0x100
58         bl      main
59
60 . = 0x40
61 .global secondary_spin_sem
62 secondary_spin_sem:
63         .long   0
64
65 . = 0x60
66 thread1_start_kboot:
67         mfmsr   %r31
68         clrldi  %r31,%r31,1
69         mtmsrd  %r31
70         isync
71
72         ba      thread1_start   /* kboot copies the first 256 bytes to
73                                  * address 0, so we are safe to jump
74                                  * (and stay) there */
75
76 thread1_start:
77         li      %r3,secondary_spin_sem@l
78 1:      lwz     %r1,0(%r3)      /* Spin on SECONDARY_SPIN_SEM_ADDRESS */
79         cmpwi   %r1,0
80         beq     1b              /* If the semaphore is still zero, spin again */
81
82         /* We have been woken up by thread 0 */
83         li      %r0,0x100       /* Invalidate reset vector cache line */
84         icbi    0,%r0
85         isync
86         sync
87         ba      0x100           /* Jump to the reset vector */
88
89 . = EXC_RST
90 exc_rst:
91         mfmsr   %r31
92         clrldi  %r31,%r31,1
93         mtmsrd  %r31
94         isync
95
96         mfspr   %r3,SPR_CTRL
97         /* The first two bits of r0 are 01 (thread 1) or 10 (thread 0) */
98         cntlzw  %r3,%r3         /* Now 0 for thread 0, 1 for thread 1 */
99
100         cmpwi   %r3,0
101         bne     thread1_start   /* Send thread 1 to wait */
102
103         b       relocated_start /* Main entry point for thread 0 */
104
105 #define EXCEPTION_HANDLER(exc) \
106 . = exc; \
107         li      %r3, exc; \
108         mfsrr0  %r4; \
109         mfmsr   %r5; \
110         clrldi  %r6,%r5,1; \
111         mtmsrd  %r6; \
112         isync; \
113         lis     %r1,0x100; \
114         bl      ppc_exception
115
116 EXCEPTION_HANDLER(EXC_MCHK)
117 EXCEPTION_HANDLER(EXC_DSI)
118 EXCEPTION_HANDLER(EXC_DSE)
119 EXCEPTION_HANDLER(EXC_ISI)
120 EXCEPTION_HANDLER(EXC_ISE)
121 EXCEPTION_HANDLER(EXC_EXI)
122 EXCEPTION_HANDLER(EXC_ALI)
123 EXCEPTION_HANDLER(EXC_PGM)
124 EXCEPTION_HANDLER(EXC_FPU)
125 EXCEPTION_HANDLER(EXC_DECR)
126 EXCEPTION_HANDLER(EXC_SC)
127
128 relocate_self:
129         /* We enter this with r4 the physical offset for our relocation */
130         lis     %r8,_end@ha     /* r8: copy length */
131         addi    %r8,%r8,_end@l
132         li      %r5,0x100       /* r5: dest address */
133 1:      add     %r6,%r4,%r5     /* r6: source address */
134         ld      %r7,0(%r6)
135         std     %r7,0(%r5)
136         addi    %r5,%r5,8
137         cmpw    %r5,%r8
138         blt     1b
139
140         /*
141          * Now invalidate the cacheline with the second half of relocate_self,
142          * and do an absolute branch there in case we overwrote part of
143          * ourselves.
144          */
145         
146         lis     %r9,relocate_self_cache@ha
147         addi    %r9,%r9,relocate_self_cache@l
148         dcbst   0,%r9
149         sync
150         icbi    0,%r9
151         sync
152         isync
153         ba      relocate_self_cache
154
155 relocate_self_cache:
156         /* Now invalidate the icache */
157         li      %r5,0x100
158 2:      dcbst   0,%r5
159         sync
160         icbi    0,%r5
161         sync
162         isync
163         cmpw    %r5,%r8
164         addi    %r5,%r5,CACHELINE_SIZE
165         blt     2b
166
167         /* All done: absolute jump to relocated entry point */
168         ba      relocated_start
169