summaryrefslogtreecommitdiff
path: root/arch/m32r/kernel/head.S
blob: 3e83173995cd81992766212a33a5efee63931038 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
215
216
217
218
219
220
221
222
223
224
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
/*
 *  linux/arch/m32r/kernel/head.S
 *
 *  M32R startup code.
 *
 *  Copyright (c) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
 *                            Hitoshi Yamamoto
 */

/* $Id$ */

#include <linux/init.h>
__INIT
__INITDATA

	.text
#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/assembler.h>
#include <asm/m32r.h>
#include <asm/mmu_context.h>

/*
 * References to members of the boot_cpu_data structure.
 */
	.text
	.global	start_kernel
	.global __bss_start
	.global _end
ENTRY(stext)
ENTRY(_stext)
ENTRY(startup_32)
	/* Setup up the stack pointer */
	LDIMM	(r0, spi_stack_top)
	LDIMM	(r1, spu_stack_top)
	mvtc	r0, spi
	mvtc	r1, spu

	/* Initilalize PSW */
	ldi	r0, #0x0000		/* use SPI, disable EI */
	mvtc	r0, psw

	/* Set up the stack pointer */
	LDIMM	(r0, stack_start)
	ld	r0, @r0
	mvtc	r0, spi

/*
 * Clear BSS first so that there are no surprises...
 */
#ifdef CONFIG_ISA_DUAL_ISSUE

	LDIMM	(r2, __bss_start)
	LDIMM	(r3, _end)
	sub	r3, r2		; BSS size in bytes
	; R4 = BSS size in longwords (rounded down)
	mv	r4, r3		    ||	ldi	r1, #0
	srli	r4, #4		    ||	addi	r2, #-4
	beqz	r4, .Lendloop1
.Lloop1:
#ifndef CONFIG_CHIP_M32310
	; Touch memory for the no-write-allocating cache.
	ld	r0, @(4,r2)
#endif
	st	r1, @+r2	    ||	addi	r4, #-1
	st	r1, @+r2
	st	r1, @+r2
	st	r1, @+r2	    ||	cmpeq	r1, r4	; R4 = 0?
	bnc	.Lloop1
.Lendloop1:
	and3	r4, r3, #15
	addi	r2, #4
	beqz	r4, .Lendloop2
.Lloop2:
	stb	r1, @r2		    ||	addi	r4, #-1
	addi	r2, #1
	bnez	r4, .Lloop2
.Lendloop2:

#else /* not CONFIG_ISA_DUAL_ISSUE */

	LDIMM	(r2, __bss_start)
	LDIMM	(r3, _end)
	sub	r3, r2		; BSS size in bytes
	mv	r4, r3
	srli	r4, #2		; R4 = BSS size in longwords (rounded down)
	ldi	r1, #0		; clear R1 for longwords store
	addi	r2, #-4		; account for pre-inc store
	beqz	r4, .Lendloop1	; any more to go?
.Lloop1:
	st	r1, @+r2	; yep, zero out another longword
	addi	r4, #-1		; decrement count
	bnez	r4, .Lloop1	; go do some more
.Lendloop1:
	and3	r4, r3, #3	; get no. of remaining BSS bytes to clear
	addi	r2, #4		; account for pre-inc store
	beqz	r4, .Lendloop2	; any more to go?
.Lloop2:
	stb	r1, @r2		; yep, zero out another byte
	addi	r2, #1		; bump address
	addi	r4, #-1		; decrement count
	bnez	r4, .Lloop2	; go do some more
.Lendloop2:

#endif /* not CONFIG_ISA_DUAL_ISSUE */

#if 0  /* M32R_FIXME */
/*
 * Copy data segment from ROM to RAM.
 */
	.global ROM_D, TOP_DATA, END_DATA

	LDIMM	(r1, ROM_D)
	LDIMM	(r2, TOP_DATA)
	LDIMM	(r3, END_DATA)
	addi	r2, #-4
	addi	r3, #-4
loop1:
	ld	r0, @r1+
	st	r0, @+r2
	cmp	r2, r3
	bc	loop1
#endif /* 0 */

/* Jump to kernel */
	LDIMM	(r2, start_kernel)
	jl	r2
	.fillinsn
1:
	bra	1b		; main should never return here, but
				; just in case, we know what happens.

#ifdef CONFIG_SMP
/*
 * AP startup routine
 */
	.text
	.global	eit_vector
ENTRY(startup_AP)
;; setup EVB
	LDIMM  (r4, eit_vector)
	mvtc   r4, cr5

;; enable MMU
	LDIMM	(r2, init_tlb)
	jl	r2
	seth  r4, #high(MATM)
	or3   r4, r4, #low(MATM)
	ldi   r5, #0x01
	st    r5, @r4            ; Set MATM Reg(T bit ON)
	ld    r6, @r4            ; MATM Check
	LDIMM (r5, 1f)
	jmp   r5                 ; enable MMU
	nop
	.fillinsn
1:
;; ISN check
	ld    r6, @r4            ; MATM Check
	seth  r4, #high(M32R_ICU_ISTS_ADDR)
	or3   r4, r4, #low(M32R_ICU_ISTS_ADDR)
	ld    r5, @r4		; Read ISTSi reg.
	mv    r6, r5
	slli  r5, #13  ; PIML check
	srli  r5, #13  ;
	seth  r4, #high(M32R_ICU_IMASK_ADDR)
	or3   r4, r4, #low(M32R_ICU_IMASK_ADDR)
	st    r5, @r4		; Write IMASKi reg.
	slli  r6, #4   ; ISN check
	srli  r6, #26  ;
	seth  r4, #high(M32R_IRQ_IPI5)
	or3   r4, r4, #low(M32R_IRQ_IPI5)
	bne   r4, r6, 2f  ; if (ISN != CPU_BOOT_IPI) goto sleep;

;; check cpu_bootout_map and set cpu_bootin_map
	LDIMM (r4, cpu_bootout_map)
	ld    r4, @r4
	seth  r5, #high(M32R_CPUID_PORTL)
	or3   r5, r5, #low(M32R_CPUID_PORTL)
	ld    r5, @r5
	ldi   r6, #1
	sll   r6, r5
	and   r4, r6
	beqz  r4, 2f
	LDIMM (r4, cpu_bootin_map)
	ld    r5, @r4
	or    r5, r6
	st    r6, @r4

;; clear PSW
	ldi   r4, #0
	mvtc  r4, psw

;; setup SPI
	LDIMM (r4, stack_start)
	ld    r4, @r4
	mvtc  r4, spi

;; setup BPC (start_secondary)
	LDIMM (r4, start_secondary)
	mvtc  r4, bpc

	rte  ; goto startup_secondary
	nop
	nop

	.fillinsn
2:
	;; disable MMU
	seth  r4, #high(MATM)
	or3   r4, r4, #low(MATM)
	ldi   r5, #0
    	st    r5, @r4            ; Set MATM Reg(T bit OFF)
    	ld    r6, @r4            ; MATM Check
	LDIMM (r4, 3f)
	seth  r5, #high(__PAGE_OFFSET)
	or3   r5, r5, #low(__PAGE_OFFSET)
	not   r5, r5
	and   r4, r5
	jmp   r4                 ; disable MMU
	nop
	.fillinsn
3:
	;; SLEEP and wait IPI
	LDIMM (r4, AP_loop)
	seth  r5, #high(__PAGE_OFFSET)
	or3   r5, r5, #low(__PAGE_OFFSET)
	not   r5, r5
	and   r4, r5
	jmp   r4
	nop
	nop
#endif  /* CONFIG_SMP */

ENTRY(stack_start)
	.long	init_thread_union+8192
	.long	__KERNEL_DS

/*
 * This is initialized to create a identity-mapping at 0-4M (for bootup
 * purposes) and another mapping of the 0-4M area at virtual address
 * PAGE_OFFSET.
 */
	.text

#define  MOUNT_ROOT_RDONLY    1
#define  RAMDISK_FLAGS        0		; 1024KB
#define  ORIG_ROOT_DEV        0x0100	; /dev/ram0 (major:01, minor:00)
#define  LOADER_TYPE          1		; (??? - non-zero value seems
					; to be needed to boot from initrd)

#define  COMMAND_LINE ""

	.section	.empty_zero_page, "aw"
ENTRY(empty_zero_page)
	.long	MOUNT_ROOT_RDONLY		/* offset: +0x00 */
	.long	RAMDISK_FLAGS
	.long	ORIG_ROOT_DEV
	.long	LOADER_TYPE
	.long	0	/* INITRD_START */	/* +0x10 */
	.long	0	/* INITRD_SIZE */
	.long	0	/* CPU_CLOCK */
	.long	0	/* BUS_CLOCK */
	.long	0	/* TIMER_DIVIDE */	/* +0x20 */
	.balign	256,0
	.asciz	COMMAND_LINE
  	.byte	0
	.balign	4096,0,4096

/*------------------------------------------------------------------------
 * Stack area
 */
	.section .spi
	ALIGN
	.global spi_stack_top
	.zero	1024
spi_stack_top:

	.section .spu
	ALIGN
	.global spu_stack_top
	.zero	1024
spu_stack_top:

	.end