blob: 4624eebbf9c4c92b5e95220282b3f676dd6dbf76 [file] [log] [blame]
Graf Yangc51b4482009-01-07 23:14:39 +08001/*
Robin Getz96f10502009-09-24 14:11:24 +00002 * BF561 coreB bootstrap file
Graf Yangc51b4482009-01-07 23:14:39 +08003 *
Robin Getz96f10502009-09-24 14:11:24 +00004 * Copyright 2007-2009 Analog Devices Inc.
5 * Philippe Gerum <rpm@xenomai.org>
Graf Yangc51b4482009-01-07 23:14:39 +08006 *
Robin Getz96f10502009-09-24 14:11:24 +00007 * Licensed under the GPL-2 or later.
Graf Yangc51b4482009-01-07 23:14:39 +08008 */
9
10#include <linux/linkage.h>
11#include <linux/init.h>
12#include <asm/blackfin.h>
13#include <asm/asm-offsets.h>
Graf Yang0b39db22009-12-28 11:13:51 +000014#include <asm/trace.h>
Graf Yangc51b4482009-01-07 23:14:39 +080015
16__INIT
17
18/* Lay the initial stack into the L1 scratch area of Core B */
19#define INITIAL_STACK (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
20
21ENTRY(_coreb_trampoline_start)
22 /* Set the SYSCFG register */
23 R0 = 0x36;
24 SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
25 R0 = 0;
26
27 /*Clear Out All the data and pointer Registers*/
28 R1 = R0;
29 R2 = R0;
30 R3 = R0;
31 R4 = R0;
32 R5 = R0;
33 R6 = R0;
34 R7 = R0;
35
36 P0 = R0;
37 P1 = R0;
38 P2 = R0;
39 P3 = R0;
40 P4 = R0;
41 P5 = R0;
42
43 LC0 = r0;
44 LC1 = r0;
45 L0 = r0;
46 L1 = r0;
47 L2 = r0;
48 L3 = r0;
49
50 /* Clear Out All the DAG Registers*/
51 B0 = r0;
52 B1 = r0;
53 B2 = r0;
54 B3 = r0;
55
56 I0 = r0;
57 I1 = r0;
58 I2 = r0;
59 I3 = r0;
60
61 M0 = r0;
62 M1 = r0;
63 M2 = r0;
64 M3 = r0;
65
Graf Yang0b39db22009-12-28 11:13:51 +000066 trace_buffer_init(p0,r0);
67
Graf Yangc51b4482009-01-07 23:14:39 +080068 /* Turn off the icache */
69 p0.l = LO(IMEM_CONTROL);
70 p0.h = HI(IMEM_CONTROL);
71 R1 = [p0];
72 R0 = ~ENICPLB;
73 R0 = R0 & R1;
74
Yi Lieb7bd9c2009-08-07 01:20:58 +000075 /* Disabling of CPLBs should be proceeded by a CSYNC */
76 CSYNC;
Graf Yangc51b4482009-01-07 23:14:39 +080077 [p0] = R0;
78 SSYNC;
Graf Yangc51b4482009-01-07 23:14:39 +080079
80 /* Turn off the dcache */
81 p0.l = LO(DMEM_CONTROL);
82 p0.h = HI(DMEM_CONTROL);
83 R1 = [p0];
84 R0 = ~ENDCPLB;
85 R0 = R0 & R1;
86
Yi Lieb7bd9c2009-08-07 01:20:58 +000087 /* Disabling of CPLBs should be proceeded by a CSYNC */
88 CSYNC;
Graf Yangc51b4482009-01-07 23:14:39 +080089 [p0] = R0;
90 SSYNC;
Graf Yangc51b4482009-01-07 23:14:39 +080091
92 /* in case of double faults, save a few things */
93 p0.l = _init_retx_coreb;
94 p0.h = _init_retx_coreb;
95 R0 = RETX;
96 [P0] = R0;
97
98#ifdef CONFIG_DEBUG_DOUBLEFAULT
99 /* Only save these if we are storing them,
100 * This happens here, since L1 gets clobbered
101 * below
102 */
103 GET_PDA(p0, r0);
Graf Yang01b9f4b2009-07-22 11:56:24 +0000104 r7 = [p0 + PDA_DF_RETX];
Graf Yangc51b4482009-01-07 23:14:39 +0800105 p1.l = _init_saved_retx_coreb;
106 p1.h = _init_saved_retx_coreb;
107 [p1] = r7;
108
Graf Yang01b9f4b2009-07-22 11:56:24 +0000109 r7 = [p0 + PDA_DF_DCPLB];
Graf Yangc51b4482009-01-07 23:14:39 +0800110 p1.l = _init_saved_dcplb_fault_addr_coreb;
111 p1.h = _init_saved_dcplb_fault_addr_coreb;
112 [p1] = r7;
113
Graf Yang01b9f4b2009-07-22 11:56:24 +0000114 r7 = [p0 + PDA_DF_ICPLB];
Graf Yangc51b4482009-01-07 23:14:39 +0800115 p1.l = _init_saved_icplb_fault_addr_coreb;
116 p1.h = _init_saved_icplb_fault_addr_coreb;
117 [p1] = r7;
118
Graf Yang01b9f4b2009-07-22 11:56:24 +0000119 r7 = [p0 + PDA_DF_SEQSTAT];
Graf Yangc51b4482009-01-07 23:14:39 +0800120 p1.l = _init_saved_seqstat_coreb;
121 p1.h = _init_saved_seqstat_coreb;
122 [p1] = r7;
123#endif
124
125 /* Initialize stack pointer */
126 sp.l = lo(INITIAL_STACK);
127 sp.h = hi(INITIAL_STACK);
128 fp = sp;
129 usp = sp;
130
131 /* This section keeps the processor in supervisor mode
132 * during core B startup. Branches to the idle task.
133 */
134
135 /* EVT15 = _real_start */
136
137 p0.l = lo(EVT15);
138 p0.h = hi(EVT15);
139 p1.l = _coreb_start;
140 p1.h = _coreb_start;
141 [p0] = p1;
142 csync;
143
144 p0.l = lo(IMASK);
145 p0.h = hi(IMASK);
146 p1.l = IMASK_IVG15;
147 p1.h = 0x0;
148 [p0] = p1;
149 csync;
150
151 raise 15;
152 p0.l = .LWAIT_HERE;
153 p0.h = .LWAIT_HERE;
154 reti = p0;
155#if defined(ANOMALY_05000281)
156 nop; nop; nop;
157#endif
158 rti;
159
160.LWAIT_HERE:
161 jump .LWAIT_HERE;
162ENDPROC(_coreb_trampoline_start)
163ENTRY(_coreb_trampoline_end)
164
Graf Yang0b39db22009-12-28 11:13:51 +0000165.section ".text"
166ENTRY(_set_sicb_iwr)
167 P0.H = hi(SICB_IWR0);
168 P0.L = lo(SICB_IWR0);
169 P1.H = hi(SICB_IWR1);
170 P1.L = lo(SICB_IWR1);
171 [P0] = R0;
172 [P1] = R1;
173 SSYNC;
174 RTS;
175ENDPROC(_set_sicb_iwr)
176
177ENTRY(_coreb_sleep)
178 sp.l = lo(INITIAL_STACK);
179 sp.h = hi(INITIAL_STACK);
180 fp = sp;
181 usp = sp;
182
183 call _set_sicb_iwr;
184
185 CLI R2;
186 SSYNC;
187 IDLE;
188 STI R2;
189
190 R0 = IWR_DISABLE_ALL;
191 R1 = IWR_DISABLE_ALL;
192 call _set_sicb_iwr;
193
194 p0.h = hi(COREB_L1_CODE_START);
195 p0.l = lo(COREB_L1_CODE_START);
196 jump (p0);
197ENDPROC(_coreb_sleep)
198
199__CPUINIT
Graf Yangc51b4482009-01-07 23:14:39 +0800200ENTRY(_coreb_start)
201 [--sp] = reti;
202
203 p0.l = lo(WDOGB_CTL);
204 p0.h = hi(WDOGB_CTL);
205 r0 = 0xAD6(z);
206 w[p0] = r0; /* Clear the watchdog. */
207 ssync;
208
209 /*
210 * switch to IDLE stack.
211 */
212 p0.l = _secondary_stack;
213 p0.h = _secondary_stack;
214 sp = [p0];
215 usp = sp;
216 fp = sp;
Graf Yang0b39db22009-12-28 11:13:51 +0000217#ifdef CONFIG_HOTPLUG_CPU
218 p0.l = _hotplug_coreb;
219 p0.h = _hotplug_coreb;
220 r0 = [p0];
221 cc = BITTST(r0, 0);
222 if cc jump 3f;
223#endif
Graf Yangc51b4482009-01-07 23:14:39 +0800224 sp += -12;
225 call _init_pda
226 sp += 12;
Graf Yang0b39db22009-12-28 11:13:51 +0000227#ifdef CONFIG_HOTPLUG_CPU
2283:
229#endif
Graf Yangc51b4482009-01-07 23:14:39 +0800230 call _secondary_start_kernel;
231.L_exit:
232 jump.s .L_exit;
233ENDPROC(_coreb_start)