• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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#include <asm/asm-offsets.h>
17
18__INIT
19
20ENTRY(__init_clear_bss)
21	r2 = r2 - r1;
22	cc = r2 == 0;
23	if cc jump .L_bss_done;
24	r2 >>= 2;
25	p1 = r1;
26	p2 = r2;
27	lsetup (1f, 1f) lc0 = p2;
281:	[p1++] = r0;
29.L_bss_done:
30	rts;
31ENDPROC(__init_clear_bss)
32
33#define INITIAL_STACK	(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
34
35ENTRY(__start)
36	/* R0: argument of command line string, passed from uboot, save it */
37	R7 = R0;
38	/* Enable Cycle Counter and Nesting Of Interrupts */
39#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
40	R0 = SYSCFG_SNEN;
41#else
42	R0 = SYSCFG_SNEN | SYSCFG_CCEN;
43#endif
44	SYSCFG = R0;
45	R0 = 0;
46
47	/* Clear Out All the data and pointer Registers */
48	R1 = R0;
49	R2 = R0;
50	R3 = R0;
51	R4 = R0;
52	R5 = R0;
53	R6 = R0;
54
55	P0 = R0;
56	P1 = R0;
57	P2 = R0;
58	P3 = R0;
59	P4 = R0;
60	P5 = R0;
61
62	LC0 = r0;
63	LC1 = r0;
64	L0 = r0;
65	L1 = r0;
66	L2 = r0;
67	L3 = r0;
68
69	/* Clear Out All the DAG Registers */
70	B0 = r0;
71	B1 = r0;
72	B2 = r0;
73	B3 = r0;
74
75	I0 = r0;
76	I1 = r0;
77	I2 = r0;
78	I3 = r0;
79
80	M0 = r0;
81	M1 = r0;
82	M2 = r0;
83	M3 = r0;
84
85	/*
86	 * Clear ITEST_COMMAND and DTEST_COMMAND registers,
87	 * Leaving these as non-zero can confuse the emulator
88	 */
89	p0.L = LO(DTEST_COMMAND);
90	p0.H = HI(DTEST_COMMAND);
91	[p0] = R0;
92	[p0 + (ITEST_COMMAND - DTEST_COMMAND)] = R0;
93	CSYNC;
94
95	trace_buffer_init(p0,r0);
96	P0 = R1;
97	R0 = R1;
98
99	/* Turn off the icache */
100	p0.l = LO(IMEM_CONTROL);
101	p0.h = HI(IMEM_CONTROL);
102	R1 = [p0];
103	R0 = ~ENICPLB;
104	R0 = R0 & R1;
105	[p0] = R0;
106	SSYNC;
107
108	/* Turn off the dcache */
109	p0.l = LO(DMEM_CONTROL);
110	p0.h = HI(DMEM_CONTROL);
111	R1 = [p0];
112	R0 = ~ENDCPLB;
113	R0 = R0 & R1;
114	[p0] = R0;
115	SSYNC;
116
117	/* in case of double faults, save a few things */
118	p0.l = _init_retx;
119	p0.h = _init_retx;
120	R0 = RETX;
121	[P0] = R0;
122
123#ifdef CONFIG_DEBUG_DOUBLEFAULT
124	/* Only save these if we are storing them,
125	 * This happens here, since L1 gets clobbered
126	 * below
127	 */
128	GET_PDA(p0, r0);
129	r7 = [p0 + PDA_RETX];
130	p1.l = _init_saved_retx;
131	p1.h = _init_saved_retx;
132	[p1] = r7;
133
134	r7 = [p0 + PDA_DCPLB];
135	p1.l = _init_saved_dcplb_fault_addr;
136	p1.h = _init_saved_dcplb_fault_addr;
137	[p1] = r7;
138
139	r7 = [p0 + PDA_ICPLB];
140	p1.l = _init_saved_icplb_fault_addr;
141	p1.h = _init_saved_icplb_fault_addr;
142	[p1] = r7;
143
144	r7 = [p0 + PDA_SEQSTAT];
145	p1.l = _init_saved_seqstat;
146	p1.h = _init_saved_seqstat;
147	[p1] = r7;
148#endif
149
150	/* Initialize stack pointer */
151	sp.l = lo(INITIAL_STACK);
152	sp.h = hi(INITIAL_STACK);
153	fp = sp;
154	usp = sp;
155
156#ifdef CONFIG_EARLY_PRINTK
157	call _init_early_exception_vectors;
158#endif
159
160	r0 = 0 (x);
161	/* Zero out all of the fun bss regions */
162#if L1_DATA_A_LENGTH > 0
163	r1.l = __sbss_l1;
164	r1.h = __sbss_l1;
165	r2.l = __ebss_l1;
166	r2.h = __ebss_l1;
167	call __init_clear_bss
168#endif
169#if L1_DATA_B_LENGTH > 0
170	r1.l = __sbss_b_l1;
171	r1.h = __sbss_b_l1;
172	r2.l = __ebss_b_l1;
173	r2.h = __ebss_b_l1;
174	call __init_clear_bss
175#endif
176#if L2_LENGTH > 0
177	r1.l = __sbss_l2;
178	r1.h = __sbss_l2;
179	r2.l = __ebss_l2;
180	r2.h = __ebss_l2;
181	call __init_clear_bss
182#endif
183	r1.l = ___bss_start;
184	r1.h = ___bss_start;
185	r2.l = ___bss_stop;
186	r2.h = ___bss_stop;
187	call __init_clear_bss
188
189	/* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
190	call _bfin_relocate_l1_mem;
191#ifdef CONFIG_BFIN_KERNEL_CLOCK
192	call _init_clocks;
193#endif
194
195	/* This section keeps the processor in supervisor mode
196	 * during kernel boot.  Switches to user mode at end of boot.
197	 * See page 3-9 of Hardware Reference manual for documentation.
198	 */
199
200	/* EVT15 = _real_start */
201
202	p0.l = lo(EVT15);
203	p0.h = hi(EVT15);
204	p1.l = _real_start;
205	p1.h = _real_start;
206	[p0] = p1;
207	csync;
208
209	r0 = EVT_IVG15 (z);
210	sti r0;
211
212	raise 15;
213	p0.l = .LWAIT_HERE;
214	p0.h = .LWAIT_HERE;
215	reti = p0;
216#if ANOMALY_05000281
217	nop; nop; nop;
218#endif
219	rti;
220
221.LWAIT_HERE:
222	jump .LWAIT_HERE;
223ENDPROC(__start)
224
225/* A little BF561 glue ... */
226#ifndef WDOG_CTL
227# define WDOG_CTL WDOGA_CTL
228#endif
229
230ENTRY(_real_start)
231	/* Enable nested interrupts */
232	[--sp] = reti;
233
234	/* watchdog off for now */
235	p0.l = lo(WDOG_CTL);
236	p0.h = hi(WDOG_CTL);
237	r0 = 0xAD6(z);
238	w[p0] = r0;
239	ssync;
240
241	/* Pass the u-boot arguments to the global value command line */
242	R0 = R7;
243	call _cmdline_init;
244
245	/* Load the current thread pointer and stack */
246	sp.l = _init_thread_union;
247	sp.h = _init_thread_union;
248	p1 = THREAD_SIZE (z);
249	sp = sp + p1;
250	usp = sp;
251	fp = sp;
252	sp += -12;
253	call _init_pda
254	sp += 12;
255	jump.l _start_kernel;
256ENDPROC(_real_start)
257
258__FINIT
259