• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 *  linux/arch/m32r/kernel/head.S
4 *
5 *  M32R startup code.
6 *
7 *  Copyright (c) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
8 *                            Hitoshi Yamamoto
9 */
10
11#include <linux/init.h>
12__INIT
13__INITDATA
14
15	.text
16#include <linux/linkage.h>
17#include <asm/segment.h>
18#include <asm/page.h>
19#include <asm/pgtable.h>
20#include <asm/assembler.h>
21#include <asm/m32r.h>
22#include <asm/mmu_context.h>
23
24/*
25 * References to members of the boot_cpu_data structure.
26 */
27__HEAD
28	.global	start_kernel
29	.global __bss_start
30	.global _end
31ENTRY(stext)
32ENTRY(_stext)
33	/* Setup up the stack pointer */
34	LDIMM	(r0, spi_stack_top)
35	LDIMM	(r1, spu_stack_top)
36	mvtc	r0, spi
37	mvtc	r1, spu
38
39	/* Initilalize PSW */
40	ldi	r0, #0x0000		/* use SPI, disable EI */
41	mvtc	r0, psw
42
43	/* Set up the stack pointer */
44	LDIMM	(r0, stack_start)
45	ld	r0, @r0
46	mvtc	r0, spi
47
48/*
49 * Clear BSS first so that there are no surprises...
50 */
51#ifdef CONFIG_ISA_DUAL_ISSUE
52
53	LDIMM	(r2, __bss_start)
54	LDIMM	(r3, _end)
55	sub	r3, r2		; BSS size in bytes
56	; R4 = BSS size in longwords (rounded down)
57	mv	r4, r3		    ||	ldi	r1, #0
58	srli	r4, #4		    ||	addi	r2, #-4
59	beqz	r4, .Lendloop1
60.Lloop1:
61#ifndef CONFIG_CHIP_M32310
62	; Touch memory for the no-write-allocating cache.
63	ld	r0, @(4,r2)
64#endif
65	st	r1, @+r2	    ||	addi	r4, #-1
66	st	r1, @+r2
67	st	r1, @+r2
68	st	r1, @+r2	    ||	cmpeq	r1, r4	; R4 = 0?
69	bnc	.Lloop1
70.Lendloop1:
71	and3	r4, r3, #15
72	addi	r2, #4
73	beqz	r4, .Lendloop2
74.Lloop2:
75	stb	r1, @r2		    ||	addi	r4, #-1
76	addi	r2, #1
77	bnez	r4, .Lloop2
78.Lendloop2:
79
80#else /* not CONFIG_ISA_DUAL_ISSUE */
81
82	LDIMM	(r2, __bss_start)
83	LDIMM	(r3, _end)
84	sub	r3, r2		; BSS size in bytes
85	mv	r4, r3
86	srli	r4, #2		; R4 = BSS size in longwords (rounded down)
87	ldi	r1, #0		; clear R1 for longwords store
88	addi	r2, #-4		; account for pre-inc store
89	beqz	r4, .Lendloop1	; any more to go?
90.Lloop1:
91	st	r1, @+r2	; yep, zero out another longword
92	addi	r4, #-1		; decrement count
93	bnez	r4, .Lloop1	; go do some more
94.Lendloop1:
95	and3	r4, r3, #3	; get no. of remaining BSS bytes to clear
96	addi	r2, #4		; account for pre-inc store
97	beqz	r4, .Lendloop2	; any more to go?
98.Lloop2:
99	stb	r1, @r2		; yep, zero out another byte
100	addi	r2, #1		; bump address
101	addi	r4, #-1		; decrement count
102	bnez	r4, .Lloop2	; go do some more
103.Lendloop2:
104
105#endif /* not CONFIG_ISA_DUAL_ISSUE */
106
107#if 0  /* M32R_FIXME */
108/*
109 * Copy data segment from ROM to RAM.
110 */
111	.global ROM_D, TOP_DATA, END_DATA
112
113	LDIMM	(r1, ROM_D)
114	LDIMM	(r2, TOP_DATA)
115	LDIMM	(r3, END_DATA)
116	addi	r2, #-4
117	addi	r3, #-4
118loop1:
119	ld	r0, @r1+
120	st	r0, @+r2
121	cmp	r2, r3
122	bc	loop1
123#endif /* 0 */
124
125/* Jump to kernel */
126	LDIMM	(r2, start_kernel)
127	jl	r2
128	.fillinsn
1291:
130	bra	1b		; main should never return here, but
131				; just in case, we know what happens.
132
133#ifdef CONFIG_SMP
134/*
135 * AP startup routine
136 */
137	.global	eit_vector
138ENTRY(startup_AP)
139;; setup EVB
140	LDIMM  (r4, eit_vector)
141	mvtc   r4, cr5
142
143;; enable MMU
144	LDIMM	(r2, init_tlb)
145	jl	r2
146	seth  r4, #high(MATM)
147	or3   r4, r4, #low(MATM)
148	ldi   r5, #0x01
149	st    r5, @r4            ; Set MATM Reg(T bit ON)
150	ld    r6, @r4            ; MATM Check
151	LDIMM (r5, 1f)
152	jmp   r5                 ; enable MMU
153	nop
154	.fillinsn
1551:
156;; ISN check
157	ld    r6, @r4            ; MATM Check
158	seth  r4, #high(M32R_ICU_ISTS_ADDR)
159	or3   r4, r4, #low(M32R_ICU_ISTS_ADDR)
160	ld    r5, @r4		; Read ISTSi reg.
161	mv    r6, r5
162	slli  r5, #13  ; PIML check
163	srli  r5, #13  ;
164	seth  r4, #high(M32R_ICU_IMASK_ADDR)
165	or3   r4, r4, #low(M32R_ICU_IMASK_ADDR)
166	st    r5, @r4		; Write IMASKi reg.
167	slli  r6, #4   ; ISN check
168	srli  r6, #26  ;
169	seth  r4, #high(M32R_IRQ_IPI5)
170	or3   r4, r4, #low(M32R_IRQ_IPI5)
171	bne   r4, r6, 2f  ; if (ISN != CPU_BOOT_IPI) goto sleep;
172
173;; check cpu_bootout_map and set cpu_bootin_map
174	LDIMM (r4, cpu_bootout_map)
175	ld    r4, @r4
176	seth  r5, #high(M32R_CPUID_PORTL)
177	or3   r5, r5, #low(M32R_CPUID_PORTL)
178	ld    r5, @r5
179	ldi   r6, #1
180	sll   r6, r5
181	and   r4, r6
182	beqz  r4, 2f
183	LDIMM (r4, cpu_bootin_map)
184	ld    r5, @r4
185	or    r5, r6
186	st    r6, @r4
187
188;; clear PSW
189	ldi   r4, #0
190	mvtc  r4, psw
191
192;; setup SPI
193	LDIMM (r4, stack_start)
194	ld    r4, @r4
195	mvtc  r4, spi
196
197;; setup BPC (start_secondary)
198	LDIMM (r4, start_secondary)
199	mvtc  r4, bpc
200
201	rte  ; goto startup_secondary
202	nop
203	nop
204
205	.fillinsn
2062:
207	;; disable MMU
208	seth  r4, #high(MATM)
209	or3   r4, r4, #low(MATM)
210	ldi   r5, #0
211    	st    r5, @r4            ; Set MATM Reg(T bit OFF)
212    	ld    r6, @r4            ; MATM Check
213	LDIMM (r4, 3f)
214	seth  r5, #high(__PAGE_OFFSET)
215	or3   r5, r5, #low(__PAGE_OFFSET)
216	not   r5, r5
217	and   r4, r5
218	jmp   r4                 ; disable MMU
219	nop
220	.fillinsn
2213:
222	;; SLEEP and wait IPI
223	LDIMM (r4, AP_loop)
224	seth  r5, #high(__PAGE_OFFSET)
225	or3   r5, r5, #low(__PAGE_OFFSET)
226	not   r5, r5
227	and   r4, r5
228	jmp   r4
229	nop
230	nop
231#endif  /* CONFIG_SMP */
232
233	.text
234ENTRY(stack_start)
235	.long	init_thread_union+8192
236	.long	__KERNEL_DS
237
238/*
239 * This is initialized to create a identity-mapping at 0-4M (for bootup
240 * purposes) and another mapping of the 0-4M area at virtual address
241 * PAGE_OFFSET.
242 */
243	.text
244
245#define  MOUNT_ROOT_RDONLY    1
246#define  RAMDISK_FLAGS        0		; 1024KB
247#define  ORIG_ROOT_DEV        0x0100	; /dev/ram0 (major:01, minor:00)
248#define  LOADER_TYPE          1		; (??? - non-zero value seems
249					; to be needed to boot from initrd)
250
251#define  COMMAND_LINE ""
252
253	.section	.empty_zero_page, "aw"
254ENTRY(empty_zero_page)
255	.long	MOUNT_ROOT_RDONLY		/* offset: +0x00 */
256	.long	RAMDISK_FLAGS
257	.long	ORIG_ROOT_DEV
258	.long	LOADER_TYPE
259	.long	0	/* INITRD_START */	/* +0x10 */
260	.long	0	/* INITRD_SIZE */
261	.long	0	/* CPU_CLOCK */
262	.long	0	/* BUS_CLOCK */
263	.long	0	/* TIMER_DIVIDE */	/* +0x20 */
264	.balign	256,0
265	.asciz	COMMAND_LINE
266  	.byte	0
267	.balign	4096,0,4096
268
269/*------------------------------------------------------------------------
270 * Stack area
271 */
272	.section .init.data, "aw"
273	ALIGN
274	.global spi_stack_top
275	.zero	1024
276spi_stack_top:
277
278	.section .init.data, "aw"
279	ALIGN
280	.global spu_stack_top
281	.zero	1024
282spu_stack_top:
283
284	.end
285