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