blob: 35280f06b7b6b0387d475c7921065606e9be4b6a [file] [log] [blame]
Graf Yangc51b4482009-01-07 23:14:39 +08001/*
2 * File: arch/blackfin/mach-bf561/secondary.S
3 * Based on: arch/blackfin/mach-bf561/head.S
4 * Author: Philippe Gerum <rpm@xenomai.org>
5 *
6 * Copyright 2007 Analog Devices Inc.
7 *
8 * Description: BF561 coreB bootstrap file
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/linkage.h>
27#include <linux/init.h>
28#include <asm/blackfin.h>
29#include <asm/asm-offsets.h>
30
31__INIT
32
33/* Lay the initial stack into the L1 scratch area of Core B */
34#define INITIAL_STACK (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
35
36ENTRY(_coreb_trampoline_start)
37 /* Set the SYSCFG register */
38 R0 = 0x36;
39 SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
40 R0 = 0;
41
42 /*Clear Out All the data and pointer Registers*/
43 R1 = R0;
44 R2 = R0;
45 R3 = R0;
46 R4 = R0;
47 R5 = R0;
48 R6 = R0;
49 R7 = R0;
50
51 P0 = R0;
52 P1 = R0;
53 P2 = R0;
54 P3 = R0;
55 P4 = R0;
56 P5 = R0;
57
58 LC0 = r0;
59 LC1 = r0;
60 L0 = r0;
61 L1 = r0;
62 L2 = r0;
63 L3 = r0;
64
65 /* Clear Out All the DAG Registers*/
66 B0 = r0;
67 B1 = r0;
68 B2 = r0;
69 B3 = r0;
70
71 I0 = r0;
72 I1 = r0;
73 I2 = r0;
74 I3 = r0;
75
76 M0 = r0;
77 M1 = r0;
78 M2 = r0;
79 M3 = r0;
80
81 /* Turn off the icache */
82 p0.l = LO(IMEM_CONTROL);
83 p0.h = HI(IMEM_CONTROL);
84 R1 = [p0];
85 R0 = ~ENICPLB;
86 R0 = R0 & R1;
87
88 /* Anomaly 05000125 */
89#ifdef ANOMALY_05000125
90 CLI R2;
91 SSYNC;
92#endif
93 [p0] = R0;
94 SSYNC;
95#ifdef ANOMALY_05000125
96 STI R2;
97#endif
98
99 /* Turn off the dcache */
100 p0.l = LO(DMEM_CONTROL);
101 p0.h = HI(DMEM_CONTROL);
102 R1 = [p0];
103 R0 = ~ENDCPLB;
104 R0 = R0 & R1;
105
106 /* Anomaly 05000125 */
107#ifdef ANOMALY_05000125
108 CLI R2;
109 SSYNC;
110#endif
111 [p0] = R0;
112 SSYNC;
113#ifdef ANOMALY_05000125
114 STI R2;
115#endif
116
117 /* in case of double faults, save a few things */
118 p0.l = _init_retx_coreb;
119 p0.h = _init_retx_coreb;
120 R0 = RETX;
121 [P0] = R0;
122
123#ifdef CONFIG_DEBUG_DOUBLEFAULT
124 /* Only save these if we are storing them,
125 * This happens here, since L1 gets clobbered
126 * below
127 */
128 GET_PDA(p0, r0);
129 r7 = [p0 + PDA_RETX];
130 p1.l = _init_saved_retx_coreb;
131 p1.h = _init_saved_retx_coreb;
132 [p1] = r7;
133
134 r7 = [p0 + PDA_DCPLB];
135 p1.l = _init_saved_dcplb_fault_addr_coreb;
136 p1.h = _init_saved_dcplb_fault_addr_coreb;
137 [p1] = r7;
138
139 r7 = [p0 + PDA_ICPLB];
140 p1.l = _init_saved_icplb_fault_addr_coreb;
141 p1.h = _init_saved_icplb_fault_addr_coreb;
142 [p1] = r7;
143
144 r7 = [p0 + PDA_SEQSTAT];
145 p1.l = _init_saved_seqstat_coreb;
146 p1.h = _init_saved_seqstat_coreb;
147 [p1] = r7;
148#endif
149
150 /* Initialize stack pointer */
151 sp.l = lo(INITIAL_STACK);
152 sp.h = hi(INITIAL_STACK);
153 fp = sp;
154 usp = sp;
155
156 /* This section keeps the processor in supervisor mode
157 * during core B startup. Branches to the idle task.
158 */
159
160 /* EVT15 = _real_start */
161
162 p0.l = lo(EVT15);
163 p0.h = hi(EVT15);
164 p1.l = _coreb_start;
165 p1.h = _coreb_start;
166 [p0] = p1;
167 csync;
168
169 p0.l = lo(IMASK);
170 p0.h = hi(IMASK);
171 p1.l = IMASK_IVG15;
172 p1.h = 0x0;
173 [p0] = p1;
174 csync;
175
176 raise 15;
177 p0.l = .LWAIT_HERE;
178 p0.h = .LWAIT_HERE;
179 reti = p0;
180#if defined(ANOMALY_05000281)
181 nop; nop; nop;
182#endif
183 rti;
184
185.LWAIT_HERE:
186 jump .LWAIT_HERE;
187ENDPROC(_coreb_trampoline_start)
188ENTRY(_coreb_trampoline_end)
189
190ENTRY(_coreb_start)
191 [--sp] = reti;
192
193 p0.l = lo(WDOGB_CTL);
194 p0.h = hi(WDOGB_CTL);
195 r0 = 0xAD6(z);
196 w[p0] = r0; /* Clear the watchdog. */
197 ssync;
198
199 /*
200 * switch to IDLE stack.
201 */
202 p0.l = _secondary_stack;
203 p0.h = _secondary_stack;
204 sp = [p0];
205 usp = sp;
206 fp = sp;
207 sp += -12;
208 call _init_pda
209 sp += 12;
210 call _secondary_start_kernel;
211.L_exit:
212 jump.s .L_exit;
213ENDPROC(_coreb_start)
214
215__FINIT