mm-only debug patch...
[mmotm.git] / arch / blackfin / mach-bf561 / secondary.S
blob8e6050369c060b6d83e960492975e98ec0ca2be4
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  */
10 #include <linux/linkage.h>
11 #include <linux/init.h>
12 #include <asm/blackfin.h>
13 #include <asm/asm-offsets.h>
15 __INIT
17 /* Lay the initial stack into the L1 scratch area of Core B */
18 #define INITIAL_STACK   (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
20 ENTRY(_coreb_trampoline_start)
21         /* Set the SYSCFG register */
22         R0 = 0x36;
23         SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
24         R0 = 0;
26         /*Clear Out All the data and pointer  Registers*/
27         R1 = R0;
28         R2 = R0;
29         R3 = R0;
30         R4 = R0;
31         R5 = R0;
32         R6 = R0;
33         R7 = R0;
35         P0 = R0;
36         P1 = R0;
37         P2 = R0;
38         P3 = R0;
39         P4 = R0;
40         P5 = R0;
42         LC0 = r0;
43         LC1 = r0;
44         L0 = r0;
45         L1 = r0;
46         L2 = r0;
47         L3 = r0;
49         /* Clear Out All the DAG Registers*/
50         B0 = r0;
51         B1 = r0;
52         B2 = r0;
53         B3 = r0;
55         I0 = r0;
56         I1 = r0;
57         I2 = r0;
58         I3 = r0;
60         M0 = r0;
61         M1 = r0;
62         M2 = r0;
63         M3 = r0;
65         /* Turn off the icache */
66         p0.l = LO(IMEM_CONTROL);
67         p0.h = HI(IMEM_CONTROL);
68         R1 = [p0];
69         R0 = ~ENICPLB;
70         R0 = R0 & R1;
72         /* Disabling of CPLBs should be proceeded by a CSYNC */
73         CSYNC;
74         [p0] = R0;
75         SSYNC;
77         /* Turn off the dcache */
78         p0.l = LO(DMEM_CONTROL);
79         p0.h = HI(DMEM_CONTROL);
80         R1 = [p0];
81         R0 = ~ENDCPLB;
82         R0 = R0 & R1;
84         /* Disabling of CPLBs should be proceeded by a CSYNC */
85         CSYNC;
86         [p0] = R0;
87         SSYNC;
89         /* in case of double faults, save a few things */
90         p0.l = _init_retx_coreb;
91         p0.h = _init_retx_coreb;
92         R0 = RETX;
93         [P0] = R0;
95 #ifdef CONFIG_DEBUG_DOUBLEFAULT
96         /* Only save these if we are storing them,
97          * This happens here, since L1 gets clobbered
98          * below
99          */
100         GET_PDA(p0, r0);
101         r7 = [p0 + PDA_DF_RETX];
102         p1.l = _init_saved_retx_coreb;
103         p1.h = _init_saved_retx_coreb;
104         [p1] = r7;
106         r7 = [p0 + PDA_DF_DCPLB];
107         p1.l = _init_saved_dcplb_fault_addr_coreb;
108         p1.h = _init_saved_dcplb_fault_addr_coreb;
109         [p1] = r7;
111         r7 = [p0 + PDA_DF_ICPLB];
112         p1.l = _init_saved_icplb_fault_addr_coreb;
113         p1.h = _init_saved_icplb_fault_addr_coreb;
114         [p1] = r7;
116         r7 = [p0 + PDA_DF_SEQSTAT];
117         p1.l = _init_saved_seqstat_coreb;
118         p1.h = _init_saved_seqstat_coreb;
119         [p1] = r7;
120 #endif
122         /* Initialize stack pointer */
123         sp.l = lo(INITIAL_STACK);
124         sp.h = hi(INITIAL_STACK);
125         fp = sp;
126         usp = sp;
128         /* This section keeps the processor in supervisor mode
129          * during core B startup.  Branches to the idle task.
130          */
132         /* EVT15 = _real_start */
134         p0.l = lo(EVT15);
135         p0.h = hi(EVT15);
136         p1.l = _coreb_start;
137         p1.h = _coreb_start;
138         [p0] = p1;
139         csync;
141         p0.l = lo(IMASK);
142         p0.h = hi(IMASK);
143         p1.l = IMASK_IVG15;
144         p1.h = 0x0;
145         [p0] = p1;
146         csync;
148         raise 15;
149         p0.l = .LWAIT_HERE;
150         p0.h = .LWAIT_HERE;
151         reti = p0;
152 #if defined(ANOMALY_05000281)
153         nop; nop; nop;
154 #endif
155         rti;
157 .LWAIT_HERE:
158         jump .LWAIT_HERE;
159 ENDPROC(_coreb_trampoline_start)
160 ENTRY(_coreb_trampoline_end)
162 ENTRY(_coreb_start)
163         [--sp] = reti;
165         p0.l = lo(WDOGB_CTL);
166         p0.h = hi(WDOGB_CTL);
167         r0 = 0xAD6(z);
168         w[p0] = r0;     /* Clear the watchdog. */
169         ssync;
171         /*
172          * switch to IDLE stack.
173          */
174         p0.l = _secondary_stack;
175         p0.h = _secondary_stack;
176         sp = [p0];
177         usp = sp;
178         fp = sp;
179         sp += -12;
180         call _init_pda
181         sp += 12;
182         call _secondary_start_kernel;
183 .L_exit:
184         jump.s  .L_exit;
185 ENDPROC(_coreb_start)
187 __FINIT