Merge branch 'master'
[linux-2.6] / arch / m32r / kernel / head.S
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