blob: 148e50764555f9dcdf607d4cbecf61e529fdbe7e [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 Yang6f546bc2010-01-28 10:46:55 +0000165#ifdef CONFIG_HOTPLUG_CPU
Graf Yang0b39db22009-12-28 11:13:51 +0000166.section ".text"
Graf Yang6f546bc2010-01-28 10:46:55 +0000167ENTRY(_coreb_die)
Graf Yang0b39db22009-12-28 11:13:51 +0000168 sp.l = lo(INITIAL_STACK);
169 sp.h = hi(INITIAL_STACK);
170 fp = sp;
171 usp = sp;
172
Graf Yang0b39db22009-12-28 11:13:51 +0000173 CLI R2;
174 SSYNC;
175 IDLE;
176 STI R2;
177
178 R0 = IWR_DISABLE_ALL;
Graf Yang6f546bc2010-01-28 10:46:55 +0000179 P0.H = hi(SYSMMR_BASE);
180 P0.L = lo(SYSMMR_BASE);
181 [P0 + (SICB_IWR0 - SYSMMR_BASE)] = R0;
182 [P0 + (SICB_IWR1 - SYSMMR_BASE)] = R0;
183 SSYNC;
Graf Yang0b39db22009-12-28 11:13:51 +0000184
185 p0.h = hi(COREB_L1_CODE_START);
186 p0.l = lo(COREB_L1_CODE_START);
187 jump (p0);
Graf Yang6f546bc2010-01-28 10:46:55 +0000188ENDPROC(_coreb_die)
189#endif
Graf Yang0b39db22009-12-28 11:13:51 +0000190
Sonic Zhang6ce04662010-04-06 09:11:59 +0000191__INIT
Graf Yangc51b4482009-01-07 23:14:39 +0800192ENTRY(_coreb_start)
193 [--sp] = reti;
194
195 p0.l = lo(WDOGB_CTL);
196 p0.h = hi(WDOGB_CTL);
197 r0 = 0xAD6(z);
198 w[p0] = r0; /* Clear the watchdog. */
199 ssync;
200
201 /*
202 * switch to IDLE stack.
203 */
204 p0.l = _secondary_stack;
205 p0.h = _secondary_stack;
206 sp = [p0];
207 usp = sp;
208 fp = sp;
Graf Yang0b39db22009-12-28 11:13:51 +0000209#ifdef CONFIG_HOTPLUG_CPU
210 p0.l = _hotplug_coreb;
211 p0.h = _hotplug_coreb;
212 r0 = [p0];
213 cc = BITTST(r0, 0);
214 if cc jump 3f;
215#endif
Graf Yangc51b4482009-01-07 23:14:39 +0800216 sp += -12;
217 call _init_pda
218 sp += 12;
Graf Yang0b39db22009-12-28 11:13:51 +0000219#ifdef CONFIG_HOTPLUG_CPU
2203:
221#endif
Graf Yangc51b4482009-01-07 23:14:39 +0800222 call _secondary_start_kernel;
223.L_exit:
224 jump.s .L_exit;
225ENDPROC(_coreb_start)