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