1 /* Boot entry point for MN10300 kernel
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
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>
18 #include <asm/pgtable.h>
19 #include <asm/frame.inc>
20 #include <asm/param.h>
21 #include <unit/serial.h>
24 #include <asm/intctl-regs.h>
25 #include <asm/cpu-regs.h>
26 #include <proc/smp-regs.h>
27 #endif /* CONFIG_SMP */
31 ###############################################################################
33 # bootloader entry point
35 ###############################################################################
37 .type _start,@function
41 # If this is a secondary CPU (AP), then deal with that elsewhere
48 # We're dealing with the primary CPU (BP) here, then.
49 # Keep BP's D0,D1,D2 register for boot check.
52 # Set up the Boot IPI for each secondary CPU
54 loop_set_secondary_icr:
56 asl CROSS_ICR_CPU_SHIFT,a1
57 add CROSS_GxICR(SMP_BOOT_IRQ,0),a1
59 or GxICR_ENABLE|GxICR_LEVEL_0,d3
64 bne loop_set_secondary_icr
65 #endif /* CONFIG_SMP */
67 # save commandline pointer
70 # preload the PGD pointer register
77 mov MMUCTR_IIV|MMUCTR_DIV,d0
80 mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
82 mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
86 # turn on AM33v2 exception handling mode and set the trap table base
90 mov CONFIG_INTERRUPT_VECTOR_BASE,d0
93 # invalidate and enable both of the caches
101 movhu d0,(a0) # turn off first
102 mov CHCTR_ICINV|CHCTR_DCINV,d0
106 btst CHCTR_ICBUSY|CHCTR_DCBUSY,d0 # wait till not busy
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
114 mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
115 #endif /* NOWRALLOC */
117 mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
119 movhu d0,(a0) # enable
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)
139 # retrieve the parameters (including command line) before we overwrite
145 mov redboot_command_line,a0
147 add COMMAND_LINE_SIZE,a1
156 mov redboot_platform_name,a0
158 add COMMAND_LINE_SIZE,a1
170 # set up the registers with recognisable rubbish in them
171 mov init_thread_union+THREAD_SIZE-12,sp
174 mov d0,(4,sp) # EPSW save area
176 mov d0,(8,sp) # PC save area
209 # set up the initial kernel stack
212 mov d0,(REG_ORIG_D0,fp)
214 # put different recognisable rubbish in the regs
245 # we may be holding current in E2
246 #ifdef CONFIG_MN10300_CURRENT_IN_E2
250 # initialise the processor and the unit
251 call processor_init[],0
255 # mark the primary CPU in cpu_boot_map
260 # signal each secondary CPU to begin booting
263 loop_request_boot_secondary:
265 # send SMP_BOOT_IPI to secondary CPU
266 asl CROSS_ICR_CPU_SHIFT,a0
267 add CROSS_GxICR(SMP_BOOT_IRQ,0),a0
269 or GxICR_REQUEST|GxICR_DETECT,d0
271 movhu (a0),d0 # flush
273 # wait up to 100ms for AP's IPI to be received
275 wait_on_secondary_boot:
276 mov DELAY_TIME_BOOT_IPI,d0
284 cmp TIME_OUT_COUNT_BOOT_IPI,d3
285 bne wait_on_secondary_boot
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
303 .size _start,.-_start
305 ###############################################################################
307 # Secondary CPU boot point
309 ###############################################################################
312 # preload the PGD pointer register
313 mov swapper_pg_dir,d0
319 mov MMUCTR_IIV|MMUCTR_DIV,d0
322 mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
324 mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
328 # turn on AM33v2 exception handling mode and set the trap table base
330 or CPUP_EXM_AM33V2,d0
333 # set the interrupt vector table
334 mov CONFIG_INTERRUPT_VECTOR_BASE,d0
337 # invalidate and enable both of the caches
343 movhu d0,(a0) # turn off first
344 mov CHCTR_ICINV|CHCTR_DCINV,d0
348 btst CHCTR_ICBUSY|CHCTR_DCBUSY,d0 # wait till not busy (use CPU loop buffer)
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
356 mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
357 #endif /* !NOWRALLOC */
359 mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
361 movhu d0,(a0) # enable
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
371 mov CONFIG_INTERRUPT_VECTOR_BASE + CONFIG_BOOT_STACK_OFFSET,a0
374 mulu CONFIG_BOOT_STACK_SIZE,d0
378 # init interrupt for AP
379 call smp_prepare_cpu_init[],0
381 # mark this secondary CPU in cpu_boot_map
388 or EPSW_IE|EPSW_IM_1,epsw # permit level 0 interrupts
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
396 btst CHCTR_DCBUSY,d0 # wait till not busy (use CPU loop buffer)
400 # now sleep waiting for further instructions
407 .size startup_secondary,.-startup_secondary
408 #endif /* CONFIG_SMP */
410 ###############################################################################
414 ###############################################################################
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
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.
433 ENTRY(empty_zero_page)
437 ENTRY(empty_bad_page)
441 ENTRY(empty_bad_pte_table)
445 ENTRY(large_page_table)
449 ENTRY(kernel_vmalloc_ptes)
450 .space ((VMALLOC_END-VMALLOC_START)/PAGE_SIZE)*4