]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/blackfin/mach-common/head.S
Blackfin arch: unify the duplicated portions of __start and split mach-specific piece...
[linux-2.6-omap-h63xx.git] / arch / blackfin / mach-common / head.S
1 /*
2  * Common Blackfin startup code
3  *
4  * Copyright 2004-2008 Analog Devices Inc.
5  *
6  * Enter bugs at http://blackfin.uclinux.org/
7  *
8  * Licensed under the GPL-2 or later.
9  */
10
11 #include <linux/linkage.h>
12 #include <linux/init.h>
13 #include <asm/blackfin.h>
14 #include <asm/thread_info.h>
15 #include <asm/trace.h>
16
17 __INIT
18
19 #define INITIAL_STACK   (L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
20
21 ENTRY(__start)
22         /* R0: argument of command line string, passed from uboot, save it */
23         R7 = R0;
24         /* Enable Cycle Counter and Nesting Of Interrupts */
25 #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
26         R0 = SYSCFG_SNEN;
27 #else
28         R0 = SYSCFG_SNEN | SYSCFG_CCEN;
29 #endif
30         SYSCFG = R0;
31         R0 = 0;
32
33         /* Clear Out All the data and pointer Registers */
34         R1 = R0;
35         R2 = R0;
36         R3 = R0;
37         R4 = R0;
38         R5 = R0;
39         R6 = R0;
40
41         P0 = R0;
42         P1 = R0;
43         P2 = R0;
44         P3 = R0;
45         P4 = R0;
46         P5 = R0;
47
48         LC0 = r0;
49         LC1 = r0;
50         L0 = r0;
51         L1 = r0;
52         L2 = r0;
53         L3 = r0;
54
55         /* Clear Out All the DAG Registers */
56         B0 = r0;
57         B1 = r0;
58         B2 = r0;
59         B3 = r0;
60
61         I0 = r0;
62         I1 = r0;
63         I2 = r0;
64         I3 = r0;
65
66         M0 = r0;
67         M1 = r0;
68         M2 = r0;
69         M3 = r0;
70
71         trace_buffer_init(p0,r0);
72         P0 = R1;
73         R0 = R1;
74
75         /* Turn off the icache */
76         p0.l = LO(IMEM_CONTROL);
77         p0.h = HI(IMEM_CONTROL);
78         R1 = [p0];
79         R0 = ~ENICPLB;
80         R0 = R0 & R1;
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         [p0] = R0;
91         SSYNC;
92
93         /* Let each Blackfin family do its own thing */
94         call _mach_early_start;
95
96         /* Initialize stack pointer */
97         sp.l = lo(INITIAL_STACK);
98         sp.h = hi(INITIAL_STACK);
99         fp = sp;
100         usp = sp;
101
102 #ifdef CONFIG_EARLY_PRINTK
103         call _init_early_exception_vectors;
104 #endif
105
106         /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
107         call _bf53x_relocate_l1_mem;
108 #ifdef CONFIG_BFIN_KERNEL_CLOCK
109         call _start_dma_code;
110 #endif
111
112         /* This section keeps the processor in supervisor mode
113          * during kernel boot.  Switches to user mode at end of boot.
114          * See page 3-9 of Hardware Reference manual for documentation.
115          */
116
117         /* EVT15 = _real_start */
118
119         p0.l = lo(EVT15);
120         p0.h = hi(EVT15);
121         p1.l = _real_start;
122         p1.h = _real_start;
123         [p0] = p1;
124         csync;
125
126         p0.l = lo(IMASK);
127         p0.h = hi(IMASK);
128         p1.l = IMASK_IVG15;
129         p1.h = 0x0;
130         [p0] = p1;
131         csync;
132
133         raise 15;
134         p0.l = .LWAIT_HERE;
135         p0.h = .LWAIT_HERE;
136         reti = p0;
137 #if ANOMALY_05000281
138         nop; nop; nop;
139 #endif
140         rti;
141
142 .LWAIT_HERE:
143         jump .LWAIT_HERE;
144 ENDPROC(__start)
145
146 /* A little BF561 glue ... */
147 #ifndef WDOG_CTL
148 # define WDOG_CTL WDOGA_CTL
149 #endif
150
151 ENTRY(_real_start)
152         /* Enable nested interrupts */
153         [--sp] = reti;
154
155         /* watchdog off for now */
156         p0.l = lo(WDOG_CTL);
157         p0.h = hi(WDOG_CTL);
158         r0 = 0xAD6(z);
159         w[p0] = r0;
160         ssync;
161
162         /* Zero out the bss region
163          * Note: this will fail if bss is 0 bytes ...
164          */
165         r0 = 0 (z);
166         r1.l = ___bss_start;
167         r1.h = ___bss_start;
168         r2.l = ___bss_stop;
169         r2.h = ___bss_stop;
170         r2 = r2 - r1;
171         r2 >>= 2;
172         p1 = r1;
173         p2 = r2;
174         lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2;
175 .L_clear_bss:
176         [p1++] = r0;
177
178         /* In case there is a NULL pointer reference,
179          * zero out region before stext
180          */
181         p1 = r0;
182         r2.l = __stext;
183         r2.h = __stext;
184         r2 >>= 2;
185         p2 = r2;
186         lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2;
187 .L_clear_zero:
188         [p1++] = r0;
189
190         /* Pass the u-boot arguments to the global value command line */
191         R0 = R7;
192         call _cmdline_init;
193
194         /* Load the current thread pointer and stack */
195         sp.l = _init_thread_union;
196         sp.h = _init_thread_union;
197         p1 = THREAD_SIZE (z);
198         sp = sp + p1;
199         usp = sp;
200         fp = sp;
201         jump.l _start_kernel;
202 ENDPROC(_real_start)
203
204 __FINIT