Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / arch / blackfin / mach-bf561 / secondary.S
1 /*
2  * BF561 coreB bootstrap file
3  *
4  * Copyright 2007-2009 Analog Devices Inc.
5  *               Philippe Gerum <rpm@xenomai.org>
6  *
7  * Licensed under the GPL-2 or later.
8  */
9
10 #include <linux/linkage.h>
11 #include <linux/init.h>
12 #include <asm/blackfin.h>
13 #include <asm/asm-offsets.h>
14 #include <asm/trace.h>
15
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
21 ENTRY(_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
66         trace_buffer_init(p0,r0);
67
68         /* 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
75         /* Disabling of CPLBs should be proceeded by a CSYNC */
76         CSYNC;
77         [p0] = R0;
78         SSYNC;
79
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
87         /* Disabling of CPLBs should be proceeded by a CSYNC */
88         CSYNC;
89         [p0] = R0;
90         SSYNC;
91
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);
104         r7 = [p0 + PDA_DF_RETX];
105         p1.l = _init_saved_retx_coreb;
106         p1.h = _init_saved_retx_coreb;
107         [p1] = r7;
108
109         r7 = [p0 + PDA_DF_DCPLB];
110         p1.l = _init_saved_dcplb_fault_addr_coreb;
111         p1.h = _init_saved_dcplb_fault_addr_coreb;
112         [p1] = r7;
113
114         r7 = [p0 + PDA_DF_ICPLB];
115         p1.l = _init_saved_icplb_fault_addr_coreb;
116         p1.h = _init_saved_icplb_fault_addr_coreb;
117         [p1] = r7;
118
119         r7 = [p0 + PDA_DF_SEQSTAT];
120         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;
162 ENDPROC(_coreb_trampoline_start)
163 ENTRY(_coreb_trampoline_end)
164
165 .section ".text"
166 ENTRY(_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;
175 ENDPROC(_set_sicb_iwr)
176
177 ENTRY(_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);
197 ENDPROC(_coreb_sleep)
198
199 __CPUINIT
200 ENTRY(_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;
217 #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
224         sp += -12;
225         call _init_pda
226         sp += 12;
227 #ifdef CONFIG_HOTPLUG_CPU
228 3:
229 #endif
230         call _secondary_start_kernel;
231 .L_exit:
232         jump.s  .L_exit;
233 ENDPROC(_coreb_start)