Blame view

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