Merge with 2.3.99-pre1.
[linux-2.6/linux-mips.git] / arch / arm / kernel / head-armv.S
blob27a280b8bd03c7ee59c5c0de0a614f0e5d2216b0
1 /*
2  * linux/arch/arm/kernel/head-armv.S
3  *
4  * Copyright (C) 1994-1999 Russell King
5  *
6  * 32-bit kernel startup code for all architectures
7  */
8 #include <linux/config.h>
9 #include <linux/linkage.h>
11 #include <asm/assembler.h>
12 #include <asm/hardware.h>
13 #include <asm/dec21285.h>
15 #if (TEXTADDR & 0xffff) != 0x8000
16 #error TEXTADDR must start at 0xXXXX8000
17 #endif
19 #define SWAPPER_PGDIR_OFFSET    0x4000
21                 .globl  SYMBOL_NAME(swapper_pg_dir)
22                 .equ    SYMBOL_NAME(swapper_pg_dir),    TEXTADDR - 0x8000 + SWAPPER_PGDIR_OFFSET
24                 .section ".text.init",#alloc,#execinstr
25                 .type   stext, #function
26 ENTRY(stext)
27 ENTRY(_stext)
29 #ifdef CONFIG_ARCH_NETWINDER
31  * Compatability cruft for old NetWinder NeTTroms.  This
32  * code is currently scheduled for destruction in 2.5.xx
33  */
34                 .rept   8
35                 mov     r0, r0
36                 .endr
38                 adr     r2, 1f
39                 ldmdb   r2, {r7, r8}
40                 and     r3, r2, #0xc000
41                 teq     r3, #0x8000
42                 beq     __entry
43                 bic     r3, r2, #0xc000
44                 orr     r3, r3, #0x8000
45                 mov     r0, r3
46                 mov     r4, #64
47                 sub     r5, r8, r7
48                 b       1f
50                 .word   _stext
51                 .word   __bss_start
54                 .rept   4
55                 ldmia   r2!, {r6, r7, r8, r9}
56                 stmia   r3!, {r6, r7, r8, r9}
57                 .endr
58                 subs    r4, r4, #64
59                 bcs     1b
60                 movs    r4, r5
61                 mov     r5, #0
62                 movne   pc, r0
64                 mov     r0, #0
65                 mov     r1, #5
66 #endif
69  * Entry point.  Entry *must* be called with r0 == 0, with the MMU off.
70  *  r1 contains the unique architecture number.  See
71  * linux/arch/arm/kernel/setup.c machine_desc[] array for the complete
72  * list.  If you require a new number, please follow the instructions
73  * given in Documentation/arm/README.
74  */
75 __entry:        teq     r0, #0
76                 movne   r0, #'i'
77                 bne     __error
78                 bl      __lookup_processor_type
79                 teq     r10, #0                         @ invalid processor?
80                 moveq   r0, #'p'
81                 beq     __error
82                 bl      __lookup_architecture_type
83                 teq     r7, #0                          @ invalid architecture?
84                 moveq   r0, #'a'
85                 beq     __error
86                 bl      __create_page_tables
87                 adr     lr, __ret
88                 add     pc, r10, #12                    @ flush caches (returns ctrl reg)
90 __switch_data:  .long   __mmap_switched
91                 .long   SYMBOL_NAME(__bss_start)
92                 .long   SYMBOL_NAME(_end)
93                 .long   SYMBOL_NAME(processor_id)
94                 .long   SYMBOL_NAME(__machine_arch_type)
95                 .long   SYMBOL_NAME(cr_alignment)
96                 .long   SYMBOL_NAME(init_task_union)+8192
98 __ret:          ldr     lr, __switch_data
99                 mcr     p15, 0, r0, c1, c0
100                 mov     r0, r0
101                 mov     r0, r0
102                 mov     r0, r0
103                 mov     pc, lr
105                 /*
106                  * This code follows on after the page
107                  * table switch and jump above.
108                  *
109                  * r0  = processor control register
110                  * r1  = machine ID
111                  * r9  = processor ID
112                  */
113                 .align  5
114 __mmap_switched:
115                 adr     r3, __switch_data + 4
116                 ldmia   r3, {r4, r5, r6, r7, r8, sp}    @ Setup stack
118                 mov     fp, #0                          @ Clear BSS
119 1:              cmp     r4, r5
120                 strcc   fp, [r4],#4
121                 bcc     1b
123                 str     r9, [r6]                        @ Save processor ID
124                 str     r1, [r7]                        @ Save machine type
125 #ifdef CONFIG_ALIGNMENT_TRAP
126                 orr     r0, r0, #2                      @ ...........A.
127 #endif
128                 bic     r2, r0, #2                      @ Clear 'A' bit
129                 stmia   r8, {r0, r2}                    @ Save control register values
130                 b       SYMBOL_NAME(start_kernel)
135  * Setup the initial page tables.  We only setup the barest
136  * amount which are required to get the kernel running, which
137  * generally means mapping in the kernel code.
139  * We only map in 4MB of RAM, which should be sufficient in
140  * all cases.
142  * r5 = physical address of start of RAM
143  * r6 = physical IO address
144  * r7 = byte offset into page tables for IO
145  * r8 = page table flags
146  */
147 __create_page_tables:
148                 add     r4, r5, #SWAPPER_PGDIR_OFFSET
149                 mov     r0, r4
150                 mov     r3, #0
151                 add     r2, r0, #0x4000                 @ Clear page table
152 1:              str     r3, [r0], #4
153                 str     r3, [r0], #4
154                 str     r3, [r0], #4
155                 str     r3, [r0], #4
156                 teq     r0, r2
157                 bne     1b
158                 /*
159                  * Create identity mapping for first MB of kernel.
160                  * map in four sections (4MB) for kernel.
161                  * these are marked cacheable and bufferable.
162                  *
163                  * The identity mapping will be removed by  paging_init()
164                  */
165                 mov     r3, #0x0c
166                 orr     r3, r3, r8
167                 add     r3, r3, r5
168                 add     r0, r4, r5, lsr #18
169                 str     r3, [r0]
170                 add     r0, r4, #(TEXTADDR - 0x8000) >> 18
171                 str     r3, [r0], #4
172                 add     r3, r3, #1 << 20
173                 str     r3, [r0], #4
174                 add     r3, r3, #1 << 20
175                 str     r3, [r0], #4
176                 add     r3, r3, #1 << 20
177                 str     r3, [r0], #4
178 #ifdef CONFIG_DEBUG_LL
179                 /*
180                  * Map in IO space for serial debugging.
181                  * This allows debug messages to be output
182                  * via a serial before paging_init.
183                  */
184                 add     r0, r4, r7
185                 rsb     r3, r7, #0x4000 @ PTRS_PER_PGD*sizeof(long)
186                 cmp     r3, #0x0800
187                 addge   r2, r0, #0x0800
188                 addlt   r2, r0, r3
189                 orr     r3, r6, r8
190 1:              str     r3, [r0], #4
191                 add     r3, r3, #1 << 20
192                 teq     r0, r2
193                 bne     1b
194 #ifdef CONFIG_ARCH_NETWINDER
195                 teq     r1, #5
196                 bne     1f
197                 add     r0, r4, #0x3fc0
198                 mov     r3, #0x7c000000
199                 orr     r3, r3, r8
200                 str     r3, [r0], #4
201                 add     r3, r3, #1 << 20
202                 str     r3, [r0], #4
204 #endif
205 #endif
206 #ifdef CONFIG_ARCH_RPC
207                 /*
208                  * Map in screen at 0x02000000 & SCREEN2_BASE
209                  * Similar reasons here - for debug.  This is
210                  * only for Acorn RiscPC architectures.
211                  */
212                 teq     r5, #0
213                 addne   r0, r4, #0x80                   @ 02000000
214                 movne   r3, #0x02000000
215                 orrne   r3, r3, r8
216                 strne   r3, [r0]
217                 addne   r0, r4, #0x3600                 @ d8000000
218                 strne   r3, [r0]
219 #endif
220                 mov     pc, lr
225  * Exception handling.  Something went wrong and we can't
226  * proceed.  We ought to tell the user, but since we
227  * don't have any guarantee that we're even running on
228  * the right architecture, we do virtually nothing.
229  * r0 = ascii error character
231  * Generally, only serious errors cause this.
232  */
233 __error:
234 #ifdef CONFIG_ARCH_RPC
236  * Turn the screen red on a error - RiscPC only.
237  */
238                 mov     r0, #0x02000000
239                 mov     r3, #0x11
240                 orr     r3, r3, r3, lsl #8
241                 orr     r3, r3, r3, lsl #16
242                 str     r3, [r0], #4
243                 str     r3, [r0], #4
244                 str     r3, [r0], #4
245                 str     r3, [r0], #4
246 #endif
247 1:              mov     r0, r0
248                 b       1b
253  * Read processor ID register (CP#15, CR0), and determine
254  * processor type.
256  * Returns:
257  *      r5, r6, r7 corrupted
258  *      r8  = page table flags
259  *      r9  = processor ID
260  *      r10 = pointer to processor structure
261  */
262 __lookup_processor_type:
263                 adr     r5, 2f
264                 ldmia   r5, {r7, r9, r10}
265                 sub     r5, r5, r9
266                 add     r7, r7, r5
267                 add     r10, r10, r5
268                 mrc     p15, 0, r9, c0, c0              @ get processor id
269 1:              ldmia   r10, {r5, r6, r8}               @ value, mask, mmuflags
270                 eor     r5, r5, r9
271                 tst     r5, r6
272                 moveq   pc, lr
273                 add     r10, r10, #36                   @ sizeof(proc_info_list)
274                 cmp     r10, r7
275                 blt     1b
276                 mov     r10, #0
277                 mov     pc, lr
279 2:              .long   __proc_info_end
280                 .long   2b
281                 .long   __proc_info_begin
284  * Lookup machine architecture
285  * r1 = machine architecture number
286  * Returns:
287  *  r4 = unused word
288  *  r5 = physical start address of RAM
289  *  r6 = physical address of IO
290  *  r7 = byte offset into page tables for IO
291  */
292 __lookup_architecture_type:
293                 cmp     r1, #(__arch_types_end - __arch_types_start) / 16
294                 bge     1f
295                 adr     r4, __arch_types_start
296                 add     r4, r4, r1, lsl #4
297                 ldmia   r4, {r4, r5, r6, r7}
298                 mov     r7, r7, lsr #18
299                 mov     pc, lr
300 1:              mov     r7, #0
301                 mov     pc, lr
304  * Machine parameters.  Each machine requires 4 words, which are:
306  * word0: unused
307  * word1: physical start address of RAM
308  * word2: physical start address of IO
309  * word3: virtual start address of IO
311  * The IO mappings entered here are used to set up mappings
312  * required for debugging information to be shown to the user.
313  * paging_init() does the real page table initialisation.
314  */
315                 .type   __arch_types_start, #object
316                 @ 0x00 - DEC EBSA110
317 __arch_types_start:
318                 .long   0
319                 .long   0
320                 .long   0xe0000000
321                 .long   0xe0000000
323                 @ 0x01 - Acorn RiscPC
324                 .long   0
325                 .long   0x10000000
326                 .long   0x03000000
327                 .long   0xe0000000
329                 @ 0x02 - Unused
330                 .long   0
331                 .long   0
332                 .long   0xe0000000
333                 .long   0xe0000000
335                 @ 0x03 - NexusPCI
336                 .long   0
337                 .long   0x40000000
338                 .long   0x10000000
339                 .long   0xe0000000
341                 @ 0x04 - DEC EBSA285
342                 .long   0
343                 .long   0
344                 .long   DC21285_ARMCSR_BASE
345                 .long   0xfe000000
347                 @ 0x05 - Rebel.com NetWinder
348                 .long   0
349                 .long   0
350                 .long   DC21285_ARMCSR_BASE
351                 .long   0xfe000000
353                 @ 0x06 - CATS
354                 .long   0
355                 .long   0
356                 .long   DC21285_ARMCSR_BASE
357                 .long   0xfe000000
359                 @ 0x07 - tbox
360                 .long   0
361                 .long   0x80000000
362                 .long   0x00400000                      @ Uart
363                 .long   0xe0000000
365                 @ 0x08 - DEC EBSA285 as co-processor
366                 .long   0
367                 .long   0
368                 .long   DC21285_ARMCSR_BASE             @ Physical I/O base address
369                 .long   0x7cf00000                      @ Virtual I/O base address
371                 @ 0x09 - CL-PS7110
372                 .long   0
373                 .long   0
374                 .long   0
375                 .long   0
377                 @ 0x0a - Acorn Archimedes
378                 .long   0
379                 .long   0
380                 .long   0
381                 .long   0
383                 @ 0x0b - Acorn A5000
384                 .long   0
385                 .long   0
386                 .long   0
387                 .long   0
389                 @ 0x0c - Etoile
390                 .long   0
391                 .long   0
392                 .long   0
393                 .long   0
395                 @ 0x0d - LaCie_NAS
396                 .long   0
397                 .long   0
398                 .long   0
399                 .long   0
401                 @ 0x0e - CL-PS7500
402                 .long   0
403                 .long   0x10000000
404                 .long   0x03000000
405                 .long   0xe0000000
407                 @ 0x0f - Digital Shark (DNARD)
408                 .long   0
409                 .long   0x08000000
410                 .long   0x40000000
411                 .long   0xe0000000
413                 @ 0x10 - SA1100
414                 .long   0
415                 .long   0xc0000000
416                 .long   0x80000000
417                 .long   0xf8000000
419                 /*
420                  * Don't add anything here unless you have an
421                  * architecture number allocated - see
422                  * Documentation/arm/README
423                  */
424 __arch_types_end: