Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
[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 #include <linux/init.h>
11 __INIT
12 __INITDATA
13
14         .text
15 #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
30 ENTRY(stext)
31 ENTRY(_stext)
32 ENTRY(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
118 loop1:
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
129 1:
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
139 ENTRY(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
156 1:
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
207 2:
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
222 3:
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
234 ENTRY(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"
254 ENTRY(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
276 spi_stack_top:
277
278         .section .spu
279         ALIGN
280         .global spu_stack_top
281         .zero   1024
282 spu_stack_top:
283
284         .end