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 */ 11 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 */ 28 29 __HEAD 30 31############################################################################### 32# 33# bootloader entry point 34# 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 46 47 # 48 # We're dealing with the primary CPU (BP) here, then. 49 # Keep BP's D0,D1,D2 register for boot check. 50 # 51 52 # Set up the Boot IPI for each secondary CPU 53 mov 0x1,a0 54loop_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 */ 66 67 # save commandline pointer 68 mov d0,a3 69 70 # preload the PGD pointer register 71 mov swapper_pg_dir,d0 72 mov d0,(PTBR) 73 clr d0 74 movbu d0,(PIDR) 75 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) 85 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) 92 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 108 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 */ 121 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 126 127 # clear the BSS area 128 mov __bss_start,a0 129 mov __bss_stop,a1 130 clr d0 131bssclear: 132 cmp a1,a0 133 bge bssclear_end 134 mov d0,(a0) 135 inc4 a0 136 bra bssclear 137bssclear_end: 138 139 # retrieve the parameters (including command line) before we overwrite 140 # them 141 cmp 0xabadcafe,d1 142 bne __no_parameters 143 144__copy_parameters: 145 mov redboot_command_line,a0 146 mov a0,a1 147 add COMMAND_LINE_SIZE,a1 1481: 149 movbu (a3),d0 150 inc a3 151 movbu d0,(a0) 152 inc a0 153 cmp a1,a0 154 blt 1b 155 156 mov redboot_platform_name,a0 157 mov a0,a1 158 add COMMAND_LINE_SIZE,a1 159 mov d2,a3 1601: 161 movbu (a3),d0 162 inc a3 163 movbu d0,(a0) 164 inc a0 165 cmp a1,a0 166 blt 1b 167 168__no_parameters: 169 170 # set up the registers with recognisable rubbish in them 171 mov init_thread_union+THREAD_SIZE-12,sp 172 173 mov 0xea01eaea,d0 174 mov d0,(4,sp) # EPSW save area 175 mov 0xea02eaea,d0 176 mov d0,(8,sp) # PC save area 177 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 190 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 199 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 208 209 # set up the initial kernel stack 210 SAVE_ALL 211 mov 0xffffffff,d0 212 mov d0,(REG_ORIG_D0,fp) 213 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 227 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 236 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 244 245 # we may be holding current in E2 246#ifdef CONFIG_MN10300_CURRENT_IN_E2 247 mov init_task,e2 248#endif 249 250 # initialise the processor and the unit 251 call processor_init[],0 252 call unit_init[],0 253 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) 259 260 # signal each secondary CPU to begin booting 261 mov 0x1,d2 # CPU ID 262 263loop_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 272 273 # wait up to 100ms for AP's IPI to be received 274 clr d3 275wait_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 2861: 287 inc d2 288 cmp NR_CPUS,d2 289 bne loop_request_boot_secondary 290#endif /* CONFIG_SMP */ 291 292#ifdef CONFIG_GDBSTUB 293 call gdbstub_init[],0 294 295#ifdef CONFIG_GDBSTUB_IMMEDIATE 296 .globl __gdbstub_pause 297__gdbstub_pause: 298 bra __gdbstub_pause 299#endif 300#endif 301 302 jmp start_kernel 303 .size _start,.-_start 304 305############################################################################### 306# 307# Secondary CPU boot point 308# 309############################################################################### 310#ifdef CONFIG_SMP 311startup_secondary: 312 # preload the PGD pointer register 313 mov swapper_pg_dir,d0 314 mov d0,(PTBR) 315 clr d0 316 movbu d0,(PIDR) 317 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) 327 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) 332 333 # set the interrupt vector table 334 mov CONFIG_INTERRUPT_VECTOR_BASE,d0 335 mov d0,(TBR) 336 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 350 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 */ 363 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 369 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 377 378 # init interrupt for AP 379 call smp_prepare_cpu_init[],0 380 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) 387 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 399 400 # now sleep waiting for further instructions 401secondary_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 */ 409 410############################################################################### 411# 412# 413# 414############################################################################### 415ENTRY(__head_end) 416 417/* 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 424ENTRY(swapper_pg_dir) 425 .space PTRS_PER_PGD*4 426 427/* 428 * The page tables are initialized to only 8MB here - the final page 429 * tables are set up later depending on memory size. 430 */ 431 432 .balign PAGE_SIZE 433ENTRY(empty_zero_page) 434 .space PAGE_SIZE 435 436 .balign PAGE_SIZE 437ENTRY(empty_bad_page) 438 .space PAGE_SIZE 439 440 .balign PAGE_SIZE 441ENTRY(empty_bad_pte_table) 442 .space PAGE_SIZE 443 444 .balign PAGE_SIZE 445ENTRY(large_page_table) 446 .space PAGE_SIZE 447 448 .balign PAGE_SIZE 449ENTRY(kernel_vmalloc_ptes) 450 .space ((VMALLOC_END-VMALLOC_START)/PAGE_SIZE)*4 451