blob: dab7436d7bbe85e2997c18b43b5082e4eece4255 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/arch/m32r/kernel/head.S
3 *
4 * M32R startup code.
5 *
6 * Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata,
7 * Hitoshi Yamamoto
8 */
9
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include <linux/init.h>
11__INIT
12__INITDATA
13
14 .text
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <linux/linkage.h>
16#include <asm/segment.h>
17#include <asm/page.h>
18#include <asm/pgtable.h>
19#include <asm/assembler.h>
20#include <asm/m32r.h>
21#include <asm/mmu_context.h>
22
23/*
24 * References to members of the boot_cpu_data structure.
25 */
26 .text
27 .global start_kernel
28 .global __bss_start
29 .global _end
30ENTRY(stext)
31ENTRY(_stext)
32ENTRY(startup_32)
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 .text
138 .global eit_vector
139ENTRY(startup_AP)
140;; setup EVB
141 LDIMM (r4, eit_vector)
142 mvtc r4, cr5
143
144;; enable MMU
145 LDIMM (r2, init_tlb)
146 jl r2
147 seth r4, #high(MATM)
148 or3 r4, r4, #low(MATM)
149 ldi r5, #0x01
150 st r5, @r4 ; Set MATM Reg(T bit ON)
151 ld r6, @r4 ; MATM Check
152 LDIMM (r5, 1f)
153 jmp r5 ; enable MMU
154 nop
155 .fillinsn
1561:
157;; ISN check
158 ld r6, @r4 ; MATM Check
159 seth r4, #high(M32R_ICU_ISTS_ADDR)
160 or3 r4, r4, #low(M32R_ICU_ISTS_ADDR)
161 ld r5, @r4 ; Read ISTSi reg.
162 mv r6, r5
163 slli r5, #13 ; PIML check
164 srli r5, #13 ;
165 seth r4, #high(M32R_ICU_IMASK_ADDR)
166 or3 r4, r4, #low(M32R_ICU_IMASK_ADDR)
167 st r5, @r4 ; Write IMASKi reg.
168 slli r6, #4 ; ISN check
169 srli r6, #26 ;
170 seth r4, #high(M32R_IRQ_IPI5)
171 or3 r4, r4, #low(M32R_IRQ_IPI5)
172 bne r4, r6, 2f ; if (ISN != CPU_BOOT_IPI) goto sleep;
173
174;; check cpu_bootout_map and set cpu_bootin_map
175 LDIMM (r4, cpu_bootout_map)
176 ld r4, @r4
177 seth r5, #high(M32R_CPUID_PORTL)
178 or3 r5, r5, #low(M32R_CPUID_PORTL)
179 ld r5, @r5
180 ldi r6, #1
181 sll r6, r5
182 and r4, r6
183 beqz r4, 2f
184 LDIMM (r4, cpu_bootin_map)
185 ld r5, @r4
186 or r5, r6
187 st r6, @r4
188
189;; clear PSW
190 ldi r4, #0
191 mvtc r4, psw
192
193;; setup SPI
194 LDIMM (r4, stack_start)
195 ld r4, @r4
196 mvtc r4, spi
197
198;; setup BPC (start_secondary)
199 LDIMM (r4, start_secondary)
200 mvtc r4, bpc
201
202 rte ; goto startup_secondary
203 nop
204 nop
205
206 .fillinsn
2072:
208 ;; disable MMU
209 seth r4, #high(MATM)
210 or3 r4, r4, #low(MATM)
211 ldi r5, #0
212 st r5, @r4 ; Set MATM Reg(T bit OFF)
213 ld r6, @r4 ; MATM Check
214 LDIMM (r4, 3f)
215 seth r5, #high(__PAGE_OFFSET)
216 or3 r5, r5, #low(__PAGE_OFFSET)
217 not r5, r5
218 and r4, r5
219 jmp r4 ; disable MMU
220 nop
221 .fillinsn
2223:
223 ;; SLEEP and wait IPI
224 LDIMM (r4, AP_loop)
225 seth r5, #high(__PAGE_OFFSET)
226 or3 r5, r5, #low(__PAGE_OFFSET)
227 not r5, r5
228 and r4, r5
229 jmp r4
230 nop
231 nop
232#endif /* CONFIG_SMP */
233
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 .spi
273 ALIGN
274 .global spi_stack_top
275 .zero 1024
276spi_stack_top:
277
278 .section .spu
279 ALIGN
280 .global spu_stack_top
281 .zero 1024
282spu_stack_top:
283
284 .end