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