]> Pileus Git - ~andy/linux/blob - arch/blackfin/mach-bf561/secondary.S
Blackfin: SMP: implement cpu_freq support
[~andy/linux] / 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 #ifdef CONFIG_HOTPLUG_CPU
166 .section ".text"
167 ENTRY(_coreb_die)
168         sp.l = lo(INITIAL_STACK);
169         sp.h = hi(INITIAL_STACK);
170         fp = sp;
171         usp = sp;
172
173         CLI R2;
174         SSYNC;
175         IDLE;
176         STI R2;
177
178         R0 = IWR_DISABLE_ALL;
179         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;
184
185         p0.h = hi(COREB_L1_CODE_START);
186         p0.l = lo(COREB_L1_CODE_START);
187         jump (p0);
188 ENDPROC(_coreb_die)
189 #endif
190
191 __INIT
192 ENTRY(_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;
209 #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
216         sp += -12;
217         call _init_pda
218         sp += 12;
219 #ifdef CONFIG_HOTPLUG_CPU
220 3:
221 #endif
222         call _secondary_start_kernel;
223 .L_exit:
224         jump.s  .L_exit;
225 ENDPROC(_coreb_start)