Merge branch 'quilt/device-mapper'
[linux-2.6/next.git] / arch / mn10300 / kernel / head.S
blob73e00fc78072d69623b5baf2e06f45ac4aa29a0b
1 /* Boot entry point for MN10300 kernel
2  *
3  * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public Licence
8  * as published by the Free Software Foundation; either version
9  * 2 of the Licence, or (at your option) any later version.
10  */
12 #include <linux/init.h>
13 #include <linux/threads.h>
14 #include <linux/linkage.h>
15 #include <linux/serial_reg.h>
16 #include <asm/thread_info.h>
17 #include <asm/page.h>
18 #include <asm/pgtable.h>
19 #include <asm/frame.inc>
20 #include <asm/param.h>
21 #include <unit/serial.h>
22 #ifdef CONFIG_SMP
23 #include <asm/smp.h>
24 #include <asm/intctl-regs.h>
25 #include <asm/cpu-regs.h>
26 #include <proc/smp-regs.h>
27 #endif /* CONFIG_SMP */
29         __HEAD
31 ###############################################################################
33 # bootloader entry point
35 ###############################################################################
36         .globl  _start
37         .type   _start,@function
38 _start:
39 #ifdef CONFIG_SMP
40         #
41         # If this is a secondary CPU (AP), then deal with that elsewhere
42         #
43         mov     (CPUID),d3
44         and     CPUID_MASK,d3
45         bne     startup_secondary
47         #
48         # We're dealing with the primary CPU (BP) here, then.
49         # Keep BP's D0,D1,D2 register for boot check.
50         #
52         # Set up the Boot IPI for each secondary CPU
53         mov     0x1,a0
54 loop_set_secondary_icr:
55         mov     a0,a1
56         asl     CROSS_ICR_CPU_SHIFT,a1
57         add     CROSS_GxICR(SMP_BOOT_IRQ,0),a1
58         movhu   (a1),d3
59         or      GxICR_ENABLE|GxICR_LEVEL_0,d3
60         movhu   d3,(a1)
61         movhu   (a1),d3                         # flush
62         inc     a0
63         cmp     NR_CPUS,a0
64         bne     loop_set_secondary_icr
65 #endif /* CONFIG_SMP */
67         # save commandline pointer
68         mov     d0,a3
70         # preload the PGD pointer register
71         mov     swapper_pg_dir,d0
72         mov     d0,(PTBR)
73         clr     d0
74         movbu   d0,(PIDR)
76         # turn on the TLBs
77         mov     MMUCTR_IIV|MMUCTR_DIV,d0
78         mov     d0,(MMUCTR)
79 #ifdef CONFIG_AM34_2
80         mov     MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
81 #else
82         mov     MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
83 #endif
84         mov     d0,(MMUCTR)
86         # turn on AM33v2 exception handling mode and set the trap table base
87         movhu   (CPUP),d0
88         or      CPUP_EXM_AM33V2,d0
89         movhu   d0,(CPUP)
90         mov     CONFIG_INTERRUPT_VECTOR_BASE,d0
91         mov     d0,(TBR)
93         # invalidate and enable both of the caches
94 #ifdef CONFIG_SMP
95         mov     ECHCTR,a0
96         clr     d0
97         mov     d0,(a0)
98 #endif
99         mov     CHCTR,a0
100         clr     d0
101         movhu   d0,(a0)                                 # turn off first
102         mov     CHCTR_ICINV|CHCTR_DCINV,d0
103         movhu   d0,(a0)
104         setlb
105         mov     (a0),d0
106         btst    CHCTR_ICBUSY|CHCTR_DCBUSY,d0            # wait till not busy
107         lne
109 #ifdef CONFIG_MN10300_CACHE_ENABLED
110 #ifdef CONFIG_MN10300_CACHE_WBACK
111 #ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
112         mov     CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
113 #else
114         mov     CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
115 #endif /* NOWRALLOC */
116 #else
117         mov     CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
118 #endif /* WBACK */
119         movhu   d0,(a0)                                 # enable
120 #endif /* ENABLED */
122         # turn on RTS on the debug serial port if applicable
123 #ifdef CONFIG_MN10300_UNIT_ASB2305
124         bset    UART_MCR_RTS,(ASB2305_DEBUG_MCR)
125 #endif
127         # clear the BSS area
128         mov     __bss_start,a0
129         mov     __bss_stop,a1
130         clr     d0
131 bssclear:
132         cmp     a1,a0
133         bge     bssclear_end
134         mov     d0,(a0)
135         inc4    a0
136         bra     bssclear
137 bssclear_end:
139         # retrieve the parameters (including command line) before we overwrite
140         # them
141         cmp     0xabadcafe,d1
142         bne     __no_parameters
144 __copy_parameters:
145         mov     redboot_command_line,a0
146         mov     a0,a1
147         add     COMMAND_LINE_SIZE,a1
149         movbu   (a3),d0
150         inc     a3
151         movbu   d0,(a0)
152         inc     a0
153         cmp     a1,a0
154         blt     1b
156         mov     redboot_platform_name,a0
157         mov     a0,a1
158         add     COMMAND_LINE_SIZE,a1
159         mov     d2,a3
161         movbu   (a3),d0
162         inc     a3
163         movbu   d0,(a0)
164         inc     a0
165         cmp     a1,a0
166         blt     1b
168 __no_parameters:
170         # set up the registers with recognisable rubbish in them
171         mov     init_thread_union+THREAD_SIZE-12,sp
173         mov     0xea01eaea,d0
174         mov     d0,(4,sp)               # EPSW save area
175         mov     0xea02eaea,d0
176         mov     d0,(8,sp)               # PC save area
178         mov     0xeb0060ed,d0
179         mov     d0,mdr
180         mov     0xeb0061ed,d0
181         mov     d0,mdrq
182         mov     0xeb0062ed,d0
183         mov     d0,mcrh
184         mov     0xeb0063ed,d0
185         mov     d0,mcrl
186         mov     0xeb0064ed,d0
187         mov     d0,mcvf
188         mov     0xed0065ed,a3
189         mov     a3,usp
191         mov     0xed00e0ed,e0
192         mov     0xed00e1ed,e1
193         mov     0xed00e2ed,e2
194         mov     0xed00e3ed,e3
195         mov     0xed00e4ed,e4
196         mov     0xed00e5ed,e5
197         mov     0xed00e6ed,e6
198         mov     0xed00e7ed,e7
200         mov     0xed00d0ed,d0
201         mov     0xed00d1ed,d1
202         mov     0xed00d2ed,d2
203         mov     0xed00d3ed,d3
204         mov     0xed00a0ed,a0
205         mov     0xed00a1ed,a1
206         mov     0xed00a2ed,a2
207         mov     0,a3
209         # set up the initial kernel stack
210         SAVE_ALL
211         mov     0xffffffff,d0
212         mov     d0,(REG_ORIG_D0,fp)
214         # put different recognisable rubbish in the regs
215         mov     0xfb0060ed,d0
216         mov     d0,mdr
217         mov     0xfb0061ed,d0
218         mov     d0,mdrq
219         mov     0xfb0062ed,d0
220         mov     d0,mcrh
221         mov     0xfb0063ed,d0
222         mov     d0,mcrl
223         mov     0xfb0064ed,d0
224         mov     d0,mcvf
225         mov     0xfd0065ed,a0
226         mov     a0,usp
228         mov     0xfd00e0ed,e0
229         mov     0xfd00e1ed,e1
230         mov     0xfd00e2ed,e2
231         mov     0xfd00e3ed,e3
232         mov     0xfd00e4ed,e4
233         mov     0xfd00e5ed,e5
234         mov     0xfd00e6ed,e6
235         mov     0xfd00e7ed,e7
237         mov     0xfd00d0ed,d0
238         mov     0xfd00d1ed,d1
239         mov     0xfd00d2ed,d2
240         mov     0xfd00d3ed,d3
241         mov     0xfd00a0ed,a0
242         mov     0xfd00a1ed,a1
243         mov     0xfd00a2ed,a2
245         # we may be holding current in E2
246 #ifdef CONFIG_MN10300_CURRENT_IN_E2
247         mov     init_task,e2
248 #endif
250         # initialise the processor and the unit
251         call    processor_init[],0
252         call    unit_init[],0
254 #ifdef CONFIG_SMP
255         # mark the primary CPU in cpu_boot_map
256         mov     cpu_boot_map,a0
257         mov     0x1,d0
258         mov     d0,(a0)
260         # signal each secondary CPU to begin booting
261         mov     0x1,d2                          # CPU ID
263 loop_request_boot_secondary:
264         mov     d2,a0
265         # send SMP_BOOT_IPI to secondary CPU
266         asl     CROSS_ICR_CPU_SHIFT,a0
267         add     CROSS_GxICR(SMP_BOOT_IRQ,0),a0
268         movhu   (a0),d0
269         or      GxICR_REQUEST|GxICR_DETECT,d0
270         movhu   d0,(a0)
271         movhu   (a0),d0                         # flush
273         # wait up to 100ms for AP's IPI to be received
274         clr     d3
275 wait_on_secondary_boot:
276         mov     DELAY_TIME_BOOT_IPI,d0
277         call    __delay[],0
278         inc     d3
279         mov     cpu_boot_map,a0
280         mov     (a0),d0
281         lsr     d2,d0
282         btst    0x1,d0
283         bne     1f
284         cmp     TIME_OUT_COUNT_BOOT_IPI,d3
285         bne     wait_on_secondary_boot
287         inc     d2
288         cmp     NR_CPUS,d2
289         bne     loop_request_boot_secondary
290 #endif /* CONFIG_SMP */
292 #ifdef CONFIG_GDBSTUB
293         call    gdbstub_init[],0
295 #ifdef CONFIG_GDBSTUB_IMMEDIATE
296         .globl  __gdbstub_pause
297 __gdbstub_pause:
298         bra     __gdbstub_pause
299 #endif
300 #endif
302         jmp     start_kernel
303         .size   _start,.-_start
305 ###############################################################################
307 # Secondary CPU boot point
309 ###############################################################################
310 #ifdef CONFIG_SMP
311 startup_secondary:
312         # preload the PGD pointer register
313         mov     swapper_pg_dir,d0
314         mov     d0,(PTBR)
315         clr     d0
316         movbu   d0,(PIDR)
318         # turn on the TLBs
319         mov     MMUCTR_IIV|MMUCTR_DIV,d0
320         mov     d0,(MMUCTR)
321 #ifdef CONFIG_AM34_2
322         mov     MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
323 #else
324         mov     MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
325 #endif
326         mov     d0,(MMUCTR)
328         # turn on AM33v2 exception handling mode and set the trap table base
329         movhu   (CPUP),d0
330         or      CPUP_EXM_AM33V2,d0
331         movhu   d0,(CPUP)
333         # set the interrupt vector table
334         mov     CONFIG_INTERRUPT_VECTOR_BASE,d0
335         mov     d0,(TBR)
337         # invalidate and enable both of the caches
338         mov     ECHCTR,a0
339         clr     d0
340         mov     d0,(a0)
341         mov     CHCTR,a0
342         clr     d0
343         movhu   d0,(a0)                                 # turn off first
344         mov     CHCTR_ICINV|CHCTR_DCINV,d0
345         movhu   d0,(a0)
346         setlb
347         mov     (a0),d0
348         btst    CHCTR_ICBUSY|CHCTR_DCBUSY,d0            # wait till not busy (use CPU loop buffer)
349         lne
351 #ifdef CONFIG_MN10300_CACHE_ENABLED
352 #ifdef  CONFIG_MN10300_CACHE_WBACK
353 #ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
354         mov     CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
355 #else
356         mov     CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
357 #endif  /* !NOWRALLOC */
358 #else
359         mov     CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
360 #endif  /* WBACK */
361         movhu   d0,(a0)                                 # enable
362 #endif  /* ENABLED */
364         # Clear the boot IPI interrupt for this CPU
365         movhu   (GxICR(SMP_BOOT_IRQ)),d0
366         and     ~GxICR_REQUEST,d0
367         movhu   d0,(GxICR(SMP_BOOT_IRQ))
368         movhu   (GxICR(SMP_BOOT_IRQ)),d0                # flush
370         /* get stack */
371         mov     CONFIG_INTERRUPT_VECTOR_BASE + CONFIG_BOOT_STACK_OFFSET,a0
372         mov     (CPUID),d0
373         and     CPUID_MASK,d0
374         mulu    CONFIG_BOOT_STACK_SIZE,d0
375         sub     d0,a0
376         mov     a0,sp
378         # init interrupt for AP
379         call    smp_prepare_cpu_init[],0
381         # mark this secondary CPU in cpu_boot_map
382         mov     (CPUID),d0
383         mov     0x1,d1
384         asl     d0,d1
385         mov     cpu_boot_map,a0
386         bset    d1,(a0)
388         or      EPSW_IE|EPSW_IM_1,epsw  # permit level 0 interrupts
389         nop
390         nop
391 #ifdef  CONFIG_MN10300_CACHE_WBACK
392         # flush the local cache if it's in writeback mode
393         call    mn10300_local_dcache_flush_inv[],0
394         setlb
395         mov     (CHCTR),d0
396         btst    CHCTR_DCBUSY,d0         # wait till not busy (use CPU loop buffer)
397         lne
398 #endif
400         # now sleep waiting for further instructions
401 secondary_sleep:
402         mov     CPUM_SLEEP,d0
403         movhu   d0,(CPUM)
404         nop
405         nop
406         bra     secondary_sleep
407         .size   startup_secondary,.-startup_secondary
408 #endif /* CONFIG_SMP */
410 ###############################################################################
414 ###############################################################################
415 ENTRY(__head_end)
418  * This is initialized to disallow all access to the low 2G region
419  * - the high 2G region is managed directly by the MMU
420  * - range 0x70000000-0x7C000000 are initialised for use by VMALLOC
421  */
422         .section .bss
423         .balign PAGE_SIZE
424 ENTRY(swapper_pg_dir)
425         .space PTRS_PER_PGD*4
428  * The page tables are initialized to only 8MB here - the final page
429  * tables are set up later depending on memory size.
430  */
432         .balign PAGE_SIZE
433 ENTRY(empty_zero_page)
434         .space PAGE_SIZE
436         .balign PAGE_SIZE
437 ENTRY(empty_bad_page)
438         .space PAGE_SIZE
440         .balign PAGE_SIZE
441 ENTRY(empty_bad_pte_table)
442         .space PAGE_SIZE
444         .balign PAGE_SIZE
445 ENTRY(large_page_table)
446         .space PAGE_SIZE
448         .balign PAGE_SIZE
449 ENTRY(kernel_vmalloc_ptes)
450         .space ((VMALLOC_END-VMALLOC_START)/PAGE_SIZE)*4