Merge branches 'doc', 'multitouch', 'upstream' and 'upstream-fixes' into for-linus
[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 /*
17  * This code must come first as CoreB is hardcoded (in hardware)
18  * to start at the beginning of its L1 instruction memory.
19  */
20 .section .l1.text.head
21
22 /* Lay the initial stack into the L1 scratch area of Core B */
23 #define INITIAL_STACK   (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
24
25 ENTRY(_coreb_trampoline_start)
26         /* Set the SYSCFG register */
27         R0 = 0x36;
28         SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
29         R0 = 0;
30
31         /*Clear Out All the data and pointer  Registers*/
32         R1 = R0;
33         R2 = R0;
34         R3 = R0;
35         R4 = R0;
36         R5 = R0;
37         R6 = R0;
38         R7 = R0;
39
40         P0 = R0;
41         P1 = R0;
42         P2 = R0;
43         P3 = R0;
44         P4 = R0;
45         P5 = R0;
46
47         LC0 = r0;
48         LC1 = r0;
49         L0 = r0;
50         L1 = r0;
51         L2 = r0;
52         L3 = r0;
53
54         /* Clear Out All the DAG Registers*/
55         B0 = r0;
56         B1 = r0;
57         B2 = r0;
58         B3 = r0;
59
60         I0 = r0;
61         I1 = r0;
62         I2 = r0;
63         I3 = r0;
64
65         M0 = r0;
66         M1 = r0;
67         M2 = r0;
68         M3 = r0;
69
70         trace_buffer_init(p0,r0);
71
72         /* Turn off the icache */
73         p0.l = LO(IMEM_CONTROL);
74         p0.h = HI(IMEM_CONTROL);
75         R1 = [p0];
76         R0 = ~ENICPLB;
77         R0 = R0 & R1;
78
79         /* Disabling of CPLBs should be proceeded by a CSYNC */
80         CSYNC;
81         [p0] = R0;
82         SSYNC;
83
84         /* Turn off the dcache */
85         p0.l = LO(DMEM_CONTROL);
86         p0.h = HI(DMEM_CONTROL);
87         R1 = [p0];
88         R0 = ~ENDCPLB;
89         R0 = R0 & R1;
90
91         /* Disabling of CPLBs should be proceeded by a CSYNC */
92         CSYNC;
93         [p0] = R0;
94         SSYNC;
95
96         /* in case of double faults, save a few things */
97         p0.l = _init_retx_coreb;
98         p0.h = _init_retx_coreb;
99         R0 = RETX;
100         [P0] = R0;
101
102 #ifdef CONFIG_DEBUG_DOUBLEFAULT
103         /* Only save these if we are storing them,
104          * This happens here, since L1 gets clobbered
105          * below
106          */
107         GET_PDA(p0, r0);
108         r7 = [p0 + PDA_DF_RETX];
109         p1.l = _init_saved_retx_coreb;
110         p1.h = _init_saved_retx_coreb;
111         [p1] = r7;
112
113         r7 = [p0 + PDA_DF_DCPLB];
114         p1.l = _init_saved_dcplb_fault_addr_coreb;
115         p1.h = _init_saved_dcplb_fault_addr_coreb;
116         [p1] = r7;
117
118         r7 = [p0 + PDA_DF_ICPLB];
119         p1.l = _init_saved_icplb_fault_addr_coreb;
120         p1.h = _init_saved_icplb_fault_addr_coreb;
121         [p1] = r7;
122
123         r7 = [p0 + PDA_DF_SEQSTAT];
124         p1.l = _init_saved_seqstat_coreb;
125         p1.h = _init_saved_seqstat_coreb;
126         [p1] = r7;
127 #endif
128
129         /* Initialize stack pointer */
130         sp.l = lo(INITIAL_STACK);
131         sp.h = hi(INITIAL_STACK);
132         fp = sp;
133         usp = sp;
134
135         /* This section keeps the processor in supervisor mode
136          * during core B startup.  Branches to the idle task.
137          */
138
139         /* EVT15 = _real_start */
140
141         p0.l = lo(EVT15);
142         p0.h = hi(EVT15);
143         p1.l = _coreb_start;
144         p1.h = _coreb_start;
145         [p0] = p1;
146         csync;
147
148         p0.l = lo(IMASK);
149         p0.h = hi(IMASK);
150         p1.l = IMASK_IVG15;
151         p1.h = 0x0;
152         [p0] = p1;
153         csync;
154
155         raise 15;
156         p0.l = .LWAIT_HERE;
157         p0.h = .LWAIT_HERE;
158         reti = p0;
159 #if defined(ANOMALY_05000281)
160         nop; nop; nop;
161 #endif
162         rti;
163
164 .LWAIT_HERE:
165         jump .LWAIT_HERE;
166 ENDPROC(_coreb_trampoline_start)
167
168 #ifdef CONFIG_HOTPLUG_CPU
169 .section ".text"
170 ENTRY(_coreb_die)
171         sp.l = lo(INITIAL_STACK);
172         sp.h = hi(INITIAL_STACK);
173         fp = sp;
174         usp = sp;
175
176         CLI R2;
177         SSYNC;
178         IDLE;
179         STI R2;
180
181         R0 = IWR_DISABLE_ALL;
182         P0.H = hi(SYSMMR_BASE);
183         P0.L = lo(SYSMMR_BASE);
184         [P0 + (SICB_IWR0 - SYSMMR_BASE)] = R0;
185         [P0 + (SICB_IWR1 - SYSMMR_BASE)] = R0;
186         SSYNC;
187
188         p0.h = hi(COREB_L1_CODE_START);
189         p0.l = lo(COREB_L1_CODE_START);
190         jump (p0);
191 ENDPROC(_coreb_die)
192 #endif
193
194 __INIT
195 ENTRY(_coreb_start)
196         [--sp] = reti;
197
198         p0.l = lo(WDOGB_CTL);
199         p0.h = hi(WDOGB_CTL);
200         r0 = 0xAD6(z);
201         w[p0] = r0;     /* Clear the watchdog. */
202         ssync;
203
204         /*
205          * switch to IDLE stack.
206          */
207         p0.l = _secondary_stack;
208         p0.h = _secondary_stack;
209         sp = [p0];
210         usp = sp;
211         fp = sp;
212 #ifdef CONFIG_HOTPLUG_CPU
213         p0.l = _hotplug_coreb;
214         p0.h = _hotplug_coreb;
215         r0 = [p0];
216         cc = BITTST(r0, 0);
217         if cc jump 3f;
218 #endif
219         sp += -12;
220         call _init_pda
221         sp += 12;
222 #ifdef CONFIG_HOTPLUG_CPU
223 3:
224 #endif
225         call _secondary_start_kernel;
226 .L_exit:
227         jump.s  .L_exit;
228 ENDPROC(_coreb_start)