1/* Boot entry point for MN10300 kernel
2 *
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/threads.h>
14#include <linux/linkage.h>
15#include <linux/serial_reg.h>
16#include <asm/thread_info.h>
17#include <asm/page.h>
18#include <asm/pgtable.h>
19#include <asm/frame.inc>
20#include <asm/param.h>
21#include <unit/serial.h>
22#ifdef CONFIG_SMP
23#include <asm/smp.h>
24#include <asm/intctl-regs.h>
25#include <asm/cpu-regs.h>
26#include <proc/smp-regs.h>
27#endif /* CONFIG_SMP */
28
29	__HEAD
30
31###############################################################################
32#
33# bootloader entry point
34#
35###############################################################################
36	.globl	_start
37	.type	_start,@function
38_start:
39#ifdef CONFIG_SMP
40	#
41	# If this is a secondary CPU (AP), then deal with that elsewhere
42	#
43	mov	(CPUID),d3
44	and	CPUID_MASK,d3
45	bne	startup_secondary
46
47	#
48	# We're dealing with the primary CPU (BP) here, then.
49	# Keep BP's D0,D1,D2 register for boot check.
50	#
51
52	# Set up the Boot IPI for each secondary CPU
53	mov	0x1,a0
54loop_set_secondary_icr:
55	mov	a0,a1
56	asl	CROSS_ICR_CPU_SHIFT,a1
57	add	CROSS_GxICR(SMP_BOOT_IRQ,0),a1
58	movhu	(a1),d3
59	or	GxICR_ENABLE|GxICR_LEVEL_0,d3
60	movhu	d3,(a1)
61	movhu	(a1),d3				# flush
62	inc	a0
63	cmp	NR_CPUS,a0
64	bne	loop_set_secondary_icr
65#endif /* CONFIG_SMP */
66
67	# save commandline pointer
68	mov	d0,a3
69
70	# preload the PGD pointer register
71	mov	swapper_pg_dir,d0
72	mov	d0,(PTBR)
73	clr	d0
74	movbu	d0,(PIDR)
75
76	# turn on the TLBs
77	mov	MMUCTR_IIV|MMUCTR_DIV,d0
78	mov	d0,(MMUCTR)
79#ifdef CONFIG_AM34_2
80	mov	MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
81#else
82	mov	MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
83#endif
84	mov	d0,(MMUCTR)
85
86	# turn on AM33v2 exception handling mode and set the trap table base
87	movhu	(CPUP),d0
88	or	CPUP_EXM_AM33V2,d0
89	movhu	d0,(CPUP)
90	mov	CONFIG_INTERRUPT_VECTOR_BASE,d0
91	mov	d0,(TBR)
92
93	# invalidate and enable both of the caches
94#ifdef CONFIG_SMP
95	mov	ECHCTR,a0
96	clr	d0
97	mov	d0,(a0)
98#endif
99	mov	CHCTR,a0
100	clr	d0
101	movhu	d0,(a0)					# turn off first
102	mov	CHCTR_ICINV|CHCTR_DCINV,d0
103	movhu	d0,(a0)
104	setlb
105	mov	(a0),d0
106	btst	CHCTR_ICBUSY|CHCTR_DCBUSY,d0		# wait till not busy
107	lne
108
109#ifdef CONFIG_MN10300_CACHE_ENABLED
110#ifdef CONFIG_MN10300_CACHE_WBACK
111#ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
112	mov	CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
113#else
114	mov	CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
115#endif /* NOWRALLOC */
116#else
117	mov	CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
118#endif /* WBACK */
119	movhu	d0,(a0)					# enable
120#endif /* ENABLED */
121
122	# turn on RTS on the debug serial port if applicable
123#ifdef CONFIG_MN10300_UNIT_ASB2305
124	bset	UART_MCR_RTS,(ASB2305_DEBUG_MCR)
125#endif
126
127	# clear the BSS area
128	mov	__bss_start,a0
129	mov	__bss_stop,a1
130	clr	d0
131bssclear:
132	cmp	a1,a0
133	bge	bssclear_end
134	mov	d0,(a0)
135	inc4	a0
136	bra	bssclear
137bssclear_end:
138
139	# retrieve the parameters (including command line) before we overwrite
140	# them
141	cmp	0xabadcafe,d1
142	bne	__no_parameters
143
144__copy_parameters:
145	mov	redboot_command_line,a0
146	mov	a0,a1
147	add	COMMAND_LINE_SIZE,a1
1481:
149	movbu	(a3),d0
150	inc	a3
151	movbu	d0,(a0)
152	inc	a0
153	cmp	a1,a0
154	blt	1b
155
156	mov	redboot_platform_name,a0
157	mov	a0,a1
158	add	COMMAND_LINE_SIZE,a1
159	mov	d2,a3
1601:
161	movbu	(a3),d0
162	inc	a3
163	movbu	d0,(a0)
164	inc	a0
165	cmp	a1,a0
166	blt	1b
167
168__no_parameters:
169
170	# set up the registers with recognisable rubbish in them
171	mov	init_thread_union+THREAD_SIZE-12,sp
172
173	mov	0xea01eaea,d0
174	mov	d0,(4,sp)		# EPSW save area
175	mov	0xea02eaea,d0
176	mov	d0,(8,sp)		# PC save area
177
178	mov	0xeb0060ed,d0
179	mov	d0,mdr
180	mov	0xeb0061ed,d0
181	mov	d0,mdrq
182	mov	0xeb0062ed,d0
183	mov	d0,mcrh
184	mov	0xeb0063ed,d0
185	mov	d0,mcrl
186	mov	0xeb0064ed,d0
187	mov	d0,mcvf
188	mov	0xed0065ed,a3
189	mov	a3,usp
190
191	mov	0xed00e0ed,e0
192	mov	0xed00e1ed,e1
193	mov	0xed00e2ed,e2
194	mov	0xed00e3ed,e3
195	mov	0xed00e4ed,e4
196	mov	0xed00e5ed,e5
197	mov	0xed00e6ed,e6
198	mov	0xed00e7ed,e7
199
200	mov	0xed00d0ed,d0
201	mov	0xed00d1ed,d1
202	mov	0xed00d2ed,d2
203	mov	0xed00d3ed,d3
204	mov	0xed00a0ed,a0
205	mov	0xed00a1ed,a1
206	mov	0xed00a2ed,a2
207	mov	0,a3
208
209	# set up the initial kernel stack
210	SAVE_ALL
211	mov	0xffffffff,d0
212	mov	d0,(REG_ORIG_D0,fp)
213
214	# put different recognisable rubbish in the regs
215	mov	0xfb0060ed,d0
216	mov	d0,mdr
217	mov	0xfb0061ed,d0
218	mov	d0,mdrq
219	mov	0xfb0062ed,d0
220	mov	d0,mcrh
221	mov	0xfb0063ed,d0
222	mov	d0,mcrl
223	mov	0xfb0064ed,d0
224	mov	d0,mcvf
225	mov	0xfd0065ed,a0
226	mov	a0,usp
227
228	mov	0xfd00e0ed,e0
229	mov	0xfd00e1ed,e1
230	mov	0xfd00e2ed,e2
231	mov	0xfd00e3ed,e3
232	mov	0xfd00e4ed,e4
233	mov	0xfd00e5ed,e5
234	mov	0xfd00e6ed,e6
235	mov	0xfd00e7ed,e7
236
237	mov	0xfd00d0ed,d0
238	mov	0xfd00d1ed,d1
239	mov	0xfd00d2ed,d2
240	mov	0xfd00d3ed,d3
241	mov	0xfd00a0ed,a0
242	mov	0xfd00a1ed,a1
243	mov	0xfd00a2ed,a2
244
245	# we may be holding current in E2
246#ifdef CONFIG_MN10300_CURRENT_IN_E2
247	mov	init_task,e2
248#endif
249
250	# initialise the processor and the unit
251	call	processor_init[],0
252	call	unit_init[],0
253
254#ifdef CONFIG_SMP
255	# mark the primary CPU in cpu_boot_map
256	mov	cpu_boot_map,a0
257	mov	0x1,d0
258	mov	d0,(a0)
259
260	# signal each secondary CPU to begin booting
261	mov	0x1,d2				# CPU ID
262
263loop_request_boot_secondary:
264	mov	d2,a0
265	# send SMP_BOOT_IPI to secondary CPU
266	asl	CROSS_ICR_CPU_SHIFT,a0
267	add	CROSS_GxICR(SMP_BOOT_IRQ,0),a0
268	movhu	(a0),d0
269	or	GxICR_REQUEST|GxICR_DETECT,d0
270	movhu	d0,(a0)
271	movhu	(a0),d0				# flush
272
273	# wait up to 100ms for AP's IPI to be received
274	clr	d3
275wait_on_secondary_boot:
276	mov	DELAY_TIME_BOOT_IPI,d0
277	call	__delay[],0
278	inc	d3
279	mov	cpu_boot_map,a0
280	mov	(a0),d0
281	lsr	d2,d0
282	btst	0x1,d0
283	bne	1f
284	cmp	TIME_OUT_COUNT_BOOT_IPI,d3
285	bne	wait_on_secondary_boot
2861:
287	inc	d2
288	cmp	NR_CPUS,d2
289	bne	loop_request_boot_secondary
290#endif /* CONFIG_SMP */
291
292#ifdef CONFIG_GDBSTUB
293	call	gdbstub_init[],0
294
295#ifdef CONFIG_GDBSTUB_IMMEDIATE
296	.globl	__gdbstub_pause
297__gdbstub_pause:
298	bra	__gdbstub_pause
299#endif
300#endif
301
302	jmp	start_kernel
303	.size	_start,.-_start
304
305###############################################################################
306#
307# Secondary CPU boot point
308#
309###############################################################################
310#ifdef CONFIG_SMP
311startup_secondary:
312	# preload the PGD pointer register
313	mov	swapper_pg_dir,d0
314	mov	d0,(PTBR)
315	clr	d0
316	movbu	d0,(PIDR)
317
318	# turn on the TLBs
319	mov	MMUCTR_IIV|MMUCTR_DIV,d0
320	mov	d0,(MMUCTR)
321#ifdef CONFIG_AM34_2
322	mov	MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
323#else
324	mov	MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
325#endif
326	mov	d0,(MMUCTR)
327
328	# turn on AM33v2 exception handling mode and set the trap table base
329	movhu	(CPUP),d0
330	or	CPUP_EXM_AM33V2,d0
331	movhu	d0,(CPUP)
332
333	# set the interrupt vector table
334	mov	CONFIG_INTERRUPT_VECTOR_BASE,d0
335	mov	d0,(TBR)
336
337	# invalidate and enable both of the caches
338	mov	ECHCTR,a0
339	clr	d0
340	mov	d0,(a0)
341	mov	CHCTR,a0
342	clr	d0
343	movhu	d0,(a0)					# turn off first
344	mov	CHCTR_ICINV|CHCTR_DCINV,d0
345	movhu	d0,(a0)
346	setlb
347	mov	(a0),d0
348	btst	CHCTR_ICBUSY|CHCTR_DCBUSY,d0		# wait till not busy (use CPU loop buffer)
349	lne
350
351#ifdef CONFIG_MN10300_CACHE_ENABLED
352#ifdef  CONFIG_MN10300_CACHE_WBACK
353#ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
354	mov	CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
355#else
356	mov	CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
357#endif  /* !NOWRALLOC */
358#else
359	mov	CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
360#endif  /* WBACK */
361	movhu	d0,(a0)					# enable
362#endif  /* ENABLED */
363
364	# Clear the boot IPI interrupt for this CPU
365	movhu	(GxICR(SMP_BOOT_IRQ)),d0
366	and	~GxICR_REQUEST,d0
367	movhu	d0,(GxICR(SMP_BOOT_IRQ))
368	movhu	(GxICR(SMP_BOOT_IRQ)),d0		# flush
369
370	/* get stack */
371	mov	CONFIG_INTERRUPT_VECTOR_BASE + CONFIG_BOOT_STACK_OFFSET,a0
372	mov	(CPUID),d0
373	and	CPUID_MASK,d0
374	mulu	CONFIG_BOOT_STACK_SIZE,d0
375	sub	d0,a0
376	mov	a0,sp
377
378	# init interrupt for AP
379	call	smp_prepare_cpu_init[],0
380
381	# mark this secondary CPU in cpu_boot_map
382	mov	(CPUID),d0
383	mov	0x1,d1
384	asl	d0,d1
385	mov	cpu_boot_map,a0
386	bset	d1,(a0)
387
388	or	EPSW_IE|EPSW_IM_1,epsw  # permit level 0 interrupts
389	nop
390	nop
391#ifdef  CONFIG_MN10300_CACHE_WBACK
392	# flush the local cache if it's in writeback mode
393	call	mn10300_local_dcache_flush_inv[],0
394	setlb
395	mov	(CHCTR),d0
396	btst	CHCTR_DCBUSY,d0		# wait till not busy (use CPU loop buffer)
397	lne
398#endif
399
400	# now sleep waiting for further instructions
401secondary_sleep:
402	mov	CPUM_SLEEP,d0
403	movhu	d0,(CPUM)
404	nop
405	nop
406	bra	secondary_sleep
407	.size	startup_secondary,.-startup_secondary
408#endif /* CONFIG_SMP */
409
410###############################################################################
411#
412#
413#
414###############################################################################
415ENTRY(__head_end)
416
417/*
418 * This is initialized to disallow all access to the low 2G region
419 * - the high 2G region is managed directly by the MMU
420 * - range 0x70000000-0x7C000000 are initialised for use by VMALLOC
421 */
422	.section .bss
423	.balign PAGE_SIZE
424ENTRY(swapper_pg_dir)
425        .space PTRS_PER_PGD*4
426
427/*
428 * The page tables are initialized to only 8MB here - the final page
429 * tables are set up later depending on memory size.
430 */
431
432	.balign PAGE_SIZE
433ENTRY(empty_zero_page)
434	.space PAGE_SIZE
435
436	.balign PAGE_SIZE
437ENTRY(empty_bad_page)
438	.space PAGE_SIZE
439
440	.balign PAGE_SIZE
441ENTRY(empty_bad_pte_table)
442	.space PAGE_SIZE
443
444	.balign PAGE_SIZE
445ENTRY(large_page_table)
446	.space PAGE_SIZE
447
448	.balign PAGE_SIZE
449ENTRY(kernel_vmalloc_ptes)
450	.space ((VMALLOC_END-VMALLOC_START)/PAGE_SIZE)*4
451