1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * arch/sh5/kernel/head.S
7 *
8 * Copyright (C) 2000, 2001  Paolo Alberelli
9 *
10 *
11 * benedict.gaster@superh.com:	 2nd May 2002
12 *    Moved definition of empty_zero_page to its own section allowing
13 *    it to be placed at an absolute address known at load time.
14 *
15 * lethal@linux-sh.org:          9th May 2003
16 *    Kill off GLOBAL_NAME() usage.
17 */
18
19#include <linux/config.h>
20
21#include <asm/page.h>
22#include <asm/mmu_context.h>
23#include <asm/cache.h>
24#include <asm/tlb.h>
25#include <asm/processor.h>
26#include <asm/registers.h>
27
28/*
29 * MMU defines: TLB boundaries.
30 */
31
32#define MMUIR_FIRST	ITLB_FIXED
33#define MMUIR_END	ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP
34#define MMUIR_STEP	TLB_STEP
35
36#define MMUDR_FIRST	DTLB_FIXED
37#define MMUDR_END	DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP
38#define MMUDR_STEP	TLB_STEP
39
40/* Safety check : CONFIG_CACHED_MEMORY_OFFSET has to be a multiple of 512Mb */
41#if (CONFIG_CACHED_MEMORY_OFFSET & ((1UL<<29)-1))
42#error "CONFIG_CACHED_MEMORY_OFFSET must be a multiple of 512Mb"
43#endif
44
45/*
46 * MMU defines: Fixed TLBs.
47 */
48/* Deal safely with the case where the base of RAM is not 512Mb aligned */
49
50#define ALIGN_512M_MASK (0xffffffffe0000000)
51#define ALIGNED_EFFECTIVE ((CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START) & ALIGN_512M_MASK)
52#define ALIGNED_PHYSICAL (CONFIG_MEMORY_START & ALIGN_512M_MASK)
53
54#define MMUIR_TEXT_H	(0x0000000000000003 | ALIGNED_EFFECTIVE)
55			/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
56
57#define MMUIR_TEXT_L	(0x000000000000009a | ALIGNED_PHYSICAL)
58			/* 512 Mb, Cacheable, Write-back, execute, Not User, Ph. Add. */
59
60#define MMUDR_CACHED_H	0x0000000000000003 | ALIGNED_EFFECTIVE
61			/* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */
62#define MMUDR_CACHED_L	0x000000000000015a | ALIGNED_PHYSICAL
63			/* 512 Mb, Cacheable, Write-back, read/write, Not User, Ph. Add. */
64
65#ifdef CONFIG_ICACHE_DISABLED
66#define	ICCR0_INIT_VAL	ICCR0_OFF			/* ICACHE off */
67#else
68#define	ICCR0_INIT_VAL	ICCR0_ON | ICCR0_ICI		/* ICE + ICI */
69#endif
70#define	ICCR1_INIT_VAL	ICCR1_NOLOCK			/* No locking */
71
72#if defined (CONFIG_DCACHE_DISABLED)
73#define	OCCR0_INIT_VAL	OCCR0_OFF			   /* D-cache: off  */
74#elif defined (CONFIG_DCACHE_WRITE_THROUGH)
75#define	OCCR0_INIT_VAL	OCCR0_ON | OCCR0_OCI | OCCR0_WT	   /* D-cache: on,   */
76							   /* WT, invalidate */
77#elif defined (CONFIG_DCACHE_WRITE_BACK)
78#define	OCCR0_INIT_VAL	OCCR0_ON | OCCR0_OCI | OCCR0_WB	   /* D-cache: on,   */
79							   /* WB, invalidate */
80#else
81#error preprocessor flag CONFIG_DCACHE_... not recognized!
82#endif
83
84#define	OCCR1_INIT_VAL	OCCR1_NOLOCK			   /* No locking     */
85
86	.section	.empty_zero_page, "aw"
87	.global empty_zero_page
88
89empty_zero_page:
90	.long	1		/* MOUNT_ROOT_RDONLY */
91	.long	0		/* RAMDISK_FLAGS */
92	.long	0x0200		/* ORIG_ROOT_DEV */
93	.long	1		/* LOADER_TYPE */
94	.long	0x00360000	/* INITRD_START */
95	.long	0x000a0000	/* INITRD_SIZE */
96	.long	0
97
98	.text
99	.balign 4096,0,4096
100
101	.section	.data, "aw"
102	.balign	PAGE_SIZE
103
104	.section	.data, "aw"
105	.balign	PAGE_SIZE
106
107	.global swapper_pg_dir
108swapper_pg_dir:
109	.space PAGE_SIZE, 0
110
111	.global empty_bad_page
112empty_bad_page:
113	.space PAGE_SIZE, 0
114
115	.global empty_bad_pte_table
116empty_bad_pte_table:
117	.space PAGE_SIZE, 0
118
119variables:
120	.global	fpu_in_use
121fpu_in_use:	.quad	0
122
123
124	.section	.text, "ax"
125	.balign L1_CACHE_BYTES
126/*
127 * Condition at the entry of __stext:
128 * . Reset state:
129 *   . SR.FD    = 1		(FPU disabled)
130 *   . SR.BL    = 1		(Exceptions disabled)
131 *   . SR.MD    = 1		(Privileged Mode)
132 *   . SR.MMU   = 0		(MMU Disabled)
133 *   . SR.CD    = 0		(CTC User Visible)
134 *   . SR.IMASK = Undefined	(Interrupt Mask)
135 *
136 * Operations supposed to be performed by __stext:
137 * . prevent speculative fetch onto device memory while MMU is off
138 * . reflect as much as possible SH5 ABI (r15, r26, r27, r18)
139 * . first, save CPU state and set it to something harmless
140 * . any CPU detection and/or endianness settings (?)
141 * . initialize EMI/LMI (but not TMU/RTC/INTC/SCIF): TBD
142 * . set initial TLB entries for cached and uncached regions
143 *   (no fine granularity paging)
144 * . set initial cache state
145 * . enable MMU and caches
146 * . set CPU to a consistent state
147 *   . registers (including stack pointer and current/KCR0)
148 *   . NOT expecting to set Exception handling nor VBR/RESVEC/DCR
149 *     at this stage. This is all to later Linux initialization steps.
150 *   . initialize FPU
151 * . clear BSS
152 * . jump into start_kernel()
153 * . be prepared to hopeless start_kernel() returns.
154 *
155 */
156	.global _stext
157_stext:
158	/*
159	 * Prevent speculative fetch on device memory due to
160	 * uninitialized target registers.
161	 */
162	ptabs/u	ZERO, t0
163	ptabs/u	ZERO, t1
164	ptabs/u	ZERO, t2
165	ptabs/u	ZERO, t3
166	ptabs/u	ZERO, t4
167	ptabs/u	ZERO, t5
168	ptabs/u	ZERO, t6
169	ptabs/u	ZERO, t7
170	synci
171
172	/*
173	 * Set variable/constant pointers according to SH5 ABI.
174	 */
175	_loada	constants, GCDT
176
177	_loada	variables, GVDT
178
179	/*
180	 * Read/Set CPU state. After this block:
181	 * r29 = Initial SR
182	 */
183	getcon	SR, r29
184	movi	SR_HARMLESS, r20
185	putcon	r20, SR
186
187	/*
188	 * Initialize EMI/LMI. To Be Done.
189	 */
190
191	/*
192	 * CPU detection and/or endianness settings (?). To Be Done.
193	 * Pure PIC code here, please ! Just save state into r30.
194         * After this block:
195	 * r30 = CPU type/Platform Endianness
196	 */
197
198	/*
199	 * Set initial TLB entries for cached and uncached regions.
200	 * Note: PTA/BLINK is PIC code, PTABS/BLINK isn't !
201	 */
202	/* Clear ITLBs */
203	_ptar	clear_ITLB, t1
204	movi	MMUIR_FIRST, r21
205	movi	MMUIR_END, r22
206clear_ITLB:
207	putcfg	r21, 0, ZERO		/* Clear MMUIR[n].PTEH.V */
208	addi	r21, MMUIR_STEP, r21
209        bne	r21, r22, t1
210
211	/* Clear DTLBs */
212	_ptar	clear_DTLB, t1
213	movi	MMUDR_FIRST, r21
214	movi	MMUDR_END, r22
215clear_DTLB:
216	putcfg	r21, 0, ZERO		/* Clear MMUDR[n].PTEH.V */
217	addi	r21, MMUDR_STEP, r21
218        bne	r21, r22, t1
219
220	/* Map one big (512Mb) page for ITLB */
221	movi	MMUIR_FIRST, r21
222	movi	MMUIR_TEXT_L, r22	/* PTEL first */
223	add.l	r22, r63, r22		/* Sign extend */
224	putcfg	r21, 1, r22		/* Set MMUIR[0].PTEL */
225	movi	MMUIR_TEXT_H, r22	/* PTEH last */
226	add.l	r22, r63, r22		/* Sign extend */
227	putcfg	r21, 0, r22		/* Set MMUIR[0].PTEH */
228
229	/* Map one big CACHED (512Mb) page for DTLB */
230	movi	MMUDR_FIRST, r21
231	movi	MMUDR_CACHED_L, r22	/* PTEL first */
232	add.l	r22, r63, r22		/* Sign extend */
233	putcfg	r21, 1, r22		/* Set MMUDR[0].PTEL */
234	movi	MMUDR_CACHED_H, r22	/* PTEH last */
235	add.l	r22, r63, r22		/* Sign extend */
236	putcfg	r21, 0, r22		/* Set MMUDR[0].PTEH */
237
238	/*
239	 * Set cache behaviours.
240	 */
241	/* ICache */
242	movi	ICCR_BASE, r21
243	movi	ICCR0_INIT_VAL, r22
244	movi	ICCR1_INIT_VAL, r23
245	putcfg	r21, ICCR_REG0, r22
246	putcfg	r21, ICCR_REG1, r23
247
248	/* OCache */
249	movi	OCCR_BASE, r21
250	movi	OCCR0_INIT_VAL, r22
251	movi	OCCR1_INIT_VAL, r23
252	putcfg	r21, OCCR_REG0, r22
253	putcfg	r21, OCCR_REG1, r23
254
255
256	/*
257	 * Enable Caches and MMU. Do the first non-PIC jump.
258         * Now head.S global variables, constants and externs
259	 * can be used.
260	 */
261	getcon	SR, r21
262	movi	SR_ENABLE_MMU, r22
263	or	r21, r22, r21
264	putcon	r21, SSR
265	_loada	hyperspace, r22
266	ori	r22, 1, r22	    /* Make it SHmedia, not required but..*/
267	putcon	r22, SPC
268	synco
269	rte			    /* And now go into the hyperspace ... */
270hyperspace:			    /* ... that's the next instruction !  */
271
272	/*
273	 * Set CPU to a consistent state.
274	 * r31 = FPU support flag
275	 * t0/t7 in use. Others give a chance to loop somewhere safe
276	 */
277	_loada	start_kernel, r32
278	ori	r32, 1, r32
279
280	ptabs	r32, t0		    /* r32 = _start_kernel address        */
281	_ptaru	hopeless, t1
282	_ptaru	hopeless, t2
283	_ptaru	hopeless, t3
284	_ptaru	hopeless, t4
285	_ptaru	hopeless, t5
286	_ptaru	hopeless, t6
287	_ptar	hopeless, t7
288	gettr	t1, r28			/* r28 = hopeless address */
289
290	/* Set initial stack pointer */
291	_loada	init_task_union, SP
292	putcon	SP, KCR0		/* Set current to init_task */
293	movi	THREAD_SIZE, r22	/* Point to the end */
294	add	SP, r22, SP
295
296	/*
297	 * Initialize FPU.
298	 * Keep FPU flag in r31. After this block:
299	 * r31 = FPU flag
300	 */
301	addi	GVDT, fpu_in_use - variables, r31	/* Temporary */
302
303#ifndef CONFIG_NOFPU_SUPPORT
304	getcon	SR, r21
305	movi	SR_ENABLE_FPU, r22
306	and	r21, r22, r22
307	putcon	r22, SR			/* Try to enable */
308	getcon	SR, r22
309	xor	r21, r22, r21
310	shlri	r21, 15, r21		/* Supposedly 0/1 */
311	st.q	r31, 0 , r21		/* Set fpu_in_use */
312#else
313	movi	0, r21
314	st.q	r31, 0 , r21		/* Set fpu_in_use */
315#endif
316	or	r21, ZERO, r31		/* Set FPU flag at last */
317
318	/*
319	 * Clear bss
320	 */
321	_ptar	clear_quad, t1
322	_loada	__bss_start, r22
323	_loada	_end, r23
324clear_quad:
325	st.q	r22, 0, ZERO
326	addi	r22, 8, r22
327	bne	r22, r23, t1		/* Both quad aligned, see vmlinux.lds.S */
328	_ptaru	hopeless, t1
329
330	/* Say bye to head.S but be prepared to wrongly get back ... */
331	blink	t0, LINK
332
333	/* If we ever get back here through LINK/t1-t7 */
334	_ptaru	hopeless, t7
335
336hopeless:
337	/*
338	 * Something's badly wrong here. Loop endlessly,
339         * there's nothing more we can do about it.
340	 *
341	 * Note on hopeless: it can be jumped into invariably
342	 * before or after jumping into hyperspace. The only
343	 * requirement is to be PIC called (PTA) before and
344	 * any way (PTA/PTABS) after. According to Virtual
345	 * to Physical mapping a simulator/emulator can easily
346	 * tell where we came here from just looking at hopeless
347	 * (PC) address.
348	 *
349	 * For debugging purposes:
350	 * (r28) hopeless/loop address
351	 * (r29) Original SR
352	 * (r30) CPU type/Platform endianness
353	 * (r31) FPU Support
354	 * (r32) _start_kernel address
355	 */
356	blink	t7, ZERO
357
358
359	.balign L1_CACHE_BYTES
360constants:
361dummyc:	.quad 0
362
363