- Linus: drop support for old-style Makefiles entirely. Big.
[davej-history.git] / arch / arm / kernel / head-armv.S
blob5e529e7026cded2440ab51b862da0fa1440cd8af
1 /*
2  *  linux/arch/arm/kernel/head-armv.S
3  *
4  *  Copyright (C) 1994-1999 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  *  32-bit kernel startup code for all architectures
11  */
12 #include <linux/config.h>
13 #include <linux/linkage.h>
15 #include <asm/assembler.h>
16 #include <asm/mach-types.h>
17 #include <asm/mach/arch.h>
19 #define K(a,b,c)        ((a) << 24 | (b) << 12 | (c))
22  * We place the page tables 16K below TEXTADDR.  Therefore, we must make sure
23  * that TEXTADDR is correctly set.  Currently, we expect the least significant
24  * "short" to be 0x8000, but we could probably relax this restriction to
25  * TEXTADDR > PAGE_OFFSET + 0x4000
26  *
27  * Note that swapper_pg_dir is the virtual address of the page tables, and
28  * pgtbl gives us a position-independent reference to these tables.  We can
29  * do this because stext == TEXT_ADDR
30  */
31 #if (TEXTADDR & 0xffff) != 0x8000
32 #error TEXTADDR must start at 0xXXXX8000
33 #endif
35                 .globl  SYMBOL_NAME(swapper_pg_dir)
36                 .equ    SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000
38                 .macro  pgtbl, reg
39                 adr     \reg, stext
40                 sub     \reg, \reg, #0x4000
41                 .endm
43                 .section ".text.init",#alloc,#execinstr
44                 .type   stext, #function
45 ENTRY(stext)
47  * Entry point.  The general rules are:
48  *  should be called with r0 == 0
49  *  r1 contains the unique architecture number
50  *  with MMU is off, I-cache may be on or off, D-cache should be off.
51  * See linux/arch/arm/kernel/arch.c and linux/include/asm-arm/system.h
52  * for the complete list of numbers for r1.  If you require a new number,
53  * please follow the instructions given towards the end of
54  * linux/Documentation/arm/README.
55  */
56                 mov     r12, r0
58  * NOTE!  Any code which is placed here should be done for one of
59  * the following reasons:
60  *
61  *  1. Compatability with old production boot firmware (ie, users
62  *     actually have and are booting the kernel with the old firmware)
63  *     and therefore will be eventually removed.
64  *  2. Cover the case when there is no boot firmware.  This is not
65  *     ideal, but in this case, it should ONLY set r0 and r1 to the
66  *     appropriate value.
67  */
68 #if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_INTEGRATOR)
70  * Compatability cruft for old NetWinder NeTTroms.  This
71  * code is currently scheduled for destruction in 2.5.xx
72  */
73                 .rept   8
74                 mov     r0, r0
75                 .endr
77                 adr     r2, 1f
78                 ldmdb   r2, {r7, r8}
79                 and     r3, r2, #0xc000
80                 teq     r3, #0x8000
81                 beq     __entry
82                 bic     r3, r2, #0xc000
83                 orr     r3, r3, #0x8000
84                 mov     r0, r3
85                 mov     r4, #64
86                 sub     r5, r8, r7
87                 b       1f
89                 .word   _stext
90                 .word   __bss_start
93                 .rept   4
94                 ldmia   r2!, {r6, r7, r8, r9}
95                 stmia   r3!, {r6, r7, r8, r9}
96                 .endr
97                 subs    r4, r4, #64
98                 bcs     1b
99                 movs    r4, r5
100                 mov     r5, #0
101                 movne   pc, r0
103                 mov     r1, #MACH_TYPE_NETWINDER        @ (will go in 2.5)
104                 mov     r12, #2 << 24                   @ scheduled for removal in 2.5.xx
105                 orr     r12, r12, #5 << 12
106 __entry:
107 #endif
108 #if defined(CONFIG_ARCH_L7200)
110  * FIXME - No bootloader, so manually set 'r1' with our architecture number.
111  */
112                 mov     r1, #MACH_TYPE_L7200
113 #elif defined(CONFIG_ARCH_INTEGRATOR)
114                 mov     r1, #MACH_TYPE_INTEGRATOR
115 #endif
117                 mov     r0, #F_BIT | I_BIT | MODE_SVC   @ make sure svc mode
118                 msr     cpsr_c, r0                      @ and all irqs diabled
119                 bl      __lookup_processor_type
120                 teq     r10, #0                         @ invalid processor?
121                 moveq   r0, #'p'                        @ yes, error 'p'
122                 beq     __error
123                 bl      __lookup_architecture_type
124                 teq     r7, #0                          @ invalid architecture?
125                 moveq   r0, #'a'                        @ yes, error 'a'
126                 beq     __error
127                 bl      __create_page_tables
128                 adr     lr, __ret                       @ return address
129                 add     pc, r10, #12                    @ initialise processor
130                                                         @ (return control reg)
132 __switch_data:  .long   __mmap_switched
133                 .long   SYMBOL_NAME(compat)
134                 .long   SYMBOL_NAME(__bss_start)
135                 .long   SYMBOL_NAME(_end)
136                 .long   SYMBOL_NAME(processor_id)
137                 .long   SYMBOL_NAME(__machine_arch_type)
138                 .long   SYMBOL_NAME(cr_alignment)
139                 .long   SYMBOL_NAME(init_task_union)+8192
141 __ret:          ldr     lr, __switch_data
142                 mcr     p15, 0, r0, c1, c0
143                 mov     r0, r0
144                 mov     r0, r0
145                 mov     r0, r0
146                 mov     pc, lr
148                 /*
149                  * This code follows on after the page
150                  * table switch and jump above.
151                  *
152                  * r0  = processor control register
153                  * r1  = machine ID
154                  * r9  = processor ID
155                  */
156                 .align  5
157 __mmap_switched:
158                 adr     r3, __switch_data + 4
159                 ldmia   r3, {r2, r4, r5, r6, r7, r8, sp}@ r2 = compat
160                                                         @ sp = stack pointer
161                 str     r12, [r2]
163                 mov     fp, #0                          @ Clear BSS (and zero fp)
164 1:              cmp     r4, r5
165                 strcc   fp, [r4],#4
166                 bcc     1b
168                 str     r9, [r6]                        @ Save processor ID
169                 str     r1, [r7]                        @ Save machine type
170 #ifdef CONFIG_ALIGNMENT_TRAP
171                 orr     r0, r0, #2                      @ ...........A.
172 #endif
173                 bic     r2, r0, #2                      @ Clear 'A' bit
174                 stmia   r8, {r0, r2}                    @ Save control register values
175                 b       SYMBOL_NAME(start_kernel)
180  * Setup the initial page tables.  We only setup the barest
181  * amount which are required to get the kernel running, which
182  * generally means mapping in the kernel code.
184  * We only map in 4MB of RAM, which should be sufficient in
185  * all cases.
187  * r5 = physical address of start of RAM
188  * r6 = physical IO address
189  * r7 = byte offset into page tables for IO
190  * r8 = page table flags
191  */
192 __create_page_tables:
193                 pgtbl   r4
194                 mov     r0, r4
195                 mov     r3, #0
196                 add     r2, r0, #0x4000                 @ 16k of page table
197 1:              str     r3, [r0], #4                    @ Clear page table
198                 str     r3, [r0], #4
199                 str     r3, [r0], #4
200                 str     r3, [r0], #4
201                 teq     r0, r2
202                 bne     1b
203                 /*
204                  * Create identity mapping for first MB of kernel.
205                  * This is marked cacheable and bufferable.
206                  *
207                  * The identity mapping will be removed by  paging_init()
208                  */
209                 add     r3, r8, r5                      @ mmuflags + start of RAM
210                 add     r0, r4, r5, lsr #18
211                 str     r3, [r0]                        @ identity mapping
212                 /*
213                  * Now setup the pagetables for our kernel direct
214                  * mapped region.  We round TEXTADDR down to the
215                  * nearest megabyte boundary.
216                  */
217                 add     r0, r4, #(TEXTADDR & 0xfff00000) >> 18 @ start of kernel
218                 str     r3, [r0], #4                    @ PAGE_OFFSET + 0MB
219                 add     r3, r3, #1 << 20
220                 str     r3, [r0], #4                    @ PAGE_OFFSET + 1MB
221                 add     r3, r3, #1 << 20
222                 str     r3, [r0], #4                    @ PAGE_OFFSET + 2MB
223                 add     r3, r3, #1 << 20
224                 str     r3, [r0], #4                    @ PAGE_OFFSET + 3MB
226                 bic     r8, r8, #0x0c                   @ turn off cacheable
227                                                         @ and bufferable bits
228 #ifdef CONFIG_DEBUG_LL
229                 /*
230                  * Map in IO space for serial debugging.
231                  * This allows debug messages to be output
232                  * via a serial before paging_init.
233                  */
234                 add     r0, r4, r7
235                 rsb     r3, r7, #0x4000 @ PTRS_PER_PGD*sizeof(long)
236                 cmp     r3, #0x0800
237                 addge   r2, r0, #0x0800
238                 addlt   r2, r0, r3
239                 orr     r3, r6, r8
240 1:              str     r3, [r0], #4
241                 add     r3, r3, #1 << 20
242                 teq     r0, r2
243                 bne     1b
244 #ifdef CONFIG_ARCH_NETWINDER
245                 /*
246                  * If we're using the NetWinder, we need to map in
247                  * the 16550-type serial port for the debug messages
248                  */
249                 teq     r1, #5
250                 bne     1f
251                 add     r0, r4, #0x3fc0
252                 mov     r3, #0x7c000000
253                 orr     r3, r3, r8
254                 str     r3, [r0], #4
255                 add     r3, r3, #1 << 20
256                 str     r3, [r0], #4
258 #endif
259 #endif
260 #ifdef CONFIG_ARCH_RPC
261                 /*
262                  * Map in screen at 0x02000000 & SCREEN2_BASE
263                  * Similar reasons here - for debug.  This is
264                  * only for Acorn RiscPC architectures.
265                  */
266                 teq     r5, #0
267                 addne   r0, r4, #0x80                   @ 02000000
268                 movne   r3, #0x02000000
269                 orrne   r3, r3, r8
270                 strne   r3, [r0]
271                 addne   r0, r4, #0x3600                 @ d8000000
272                 strne   r3, [r0]
273 #endif
274                 mov     pc, lr
279  * Exception handling.  Something went wrong and we can't
280  * proceed.  We ought to tell the user, but since we
281  * don't have any guarantee that we're even running on
282  * the right architecture, we do virtually nothing.
283  * r0 = ascii error character:
284  *      a = invalid architecture
285  *      p = invalid processor
286  *      i = invalid calling convention
288  * Generally, only serious errors cause this.
289  */
290 __error:
291 #ifdef CONFIG_DEBUG_LL
292                 mov     r8, r0                          @ preserve r0
293                 adr     r0, err_str
294                 bl      printascii
295                 mov     r0, r8
296                 bl      printch
297 #endif
298 #ifdef CONFIG_ARCH_RPC
300  * Turn the screen red on a error - RiscPC only.
301  */
302                 mov     r0, #0x02000000
303                 mov     r3, #0x11
304                 orr     r3, r3, r3, lsl #8
305                 orr     r3, r3, r3, lsl #16
306                 str     r3, [r0], #4
307                 str     r3, [r0], #4
308                 str     r3, [r0], #4
309                 str     r3, [r0], #4
310 #endif
311 1:              mov     r0, r0
312                 b       1b
314 #ifdef CONFIG_DEBUG_LL
315 err_str:        .asciz  "\nError: "
316                 .align
317 #endif
320  * Read processor ID register (CP#15, CR0), and look up in the linker-built
321  * supported processor list.  Note that we can't use the absolute addresses
322  * for the __proc_info lists since we aren't running with the MMU on
323  * (and therefore, we are not in the correct address space).  We have to
324  * calculate the offset.
326  * Returns:
327  *      r5, r6, r7 corrupted
328  *      r8  = page table flags
329  *      r9  = processor ID
330  *      r10 = pointer to processor structure
331  */
332 __lookup_processor_type:
333                 adr     r5, 2f
334                 ldmia   r5, {r7, r9, r10}
335                 sub     r5, r5, r10                     @ convert addresses
336                 add     r7, r7, r5                      @ to our address space
337                 add     r10, r9, r5
338                 mrc     p15, 0, r9, c0, c0              @ get processor id
339 1:              ldmia   r10, {r5, r6, r8}               @ value, mask, mmuflags
340                 and     r6, r6, r9                      @ mask wanted bits
341                 teq     r5, r6
342                 moveq   pc, lr
343                 add     r10, r10, #36                   @ sizeof(proc_info_list)
344                 cmp     r10, r7
345                 blt     1b
346                 mov     r10, #0                         @ unknown processor
347                 mov     pc, lr
350  * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
351  * more information about the __proc_info and __arch_info structures.
352  */
353 2:              .long   __proc_info_end
354                 .long   __proc_info_begin
355                 .long   2b
356                 .long   __arch_info_begin
357                 .long   __arch_info_end
360  * Lookup machine architecture in the linker-build list of architectures.
361  * Note that we can't use the absolute addresses for the __arch_info
362  * lists since we aren't running with the MMU on (and therefore, we are
363  * not in the correct address space).  We have to calculate the offset.
365  *  r1 = machine architecture number
366  * Returns:
367  *  r2, r3, r4 corrupted
368  *  r5 = physical start address of RAM
369  *  r6 = physical address of IO
370  *  r7 = byte offset into page tables for IO
371  */
372 __lookup_architecture_type:
373                 adr     r4, 2b
374                 ldmia   r4, {r2, r3, r5, r6, r7}        @ throw away r2, r3
375                 sub     r5, r4, r5                      @ convert addresses
376                 add     r4, r6, r5                      @ to our address space
377                 add     r7, r7, r5
378 1:              ldr     r5, [r4]                        @ get machine type
379                 teq     r5, r1
380                 beq     2f
381                 add     r4, r4, #SIZEOF_MACHINE_DESC
382                 cmp     r4, r7
383                 blt     1b
384                 mov     r7, #0                          @ unknown architecture
385                 mov     pc, lr
386 2:              ldmib   r4, {r5, r6, r7}                @ found, get results
387                 mov     r7, r7, lsr #18                 @ pagetable byte offset
388                 mov     pc, lr