Back to home page

LXR

 
 

    


0001 /* Boot entry point for MN10300 kernel
0002  *
0003  * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
0004  * Written by David Howells (dhowells@redhat.com)
0005  *
0006  * This program is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU General Public Licence
0008  * as published by the Free Software Foundation; either version
0009  * 2 of the Licence, or (at your option) any later version.
0010  */
0011 
0012 #include <linux/init.h>
0013 #include <linux/threads.h>
0014 #include <linux/linkage.h>
0015 #include <linux/serial_reg.h>
0016 #include <asm/thread_info.h>
0017 #include <asm/page.h>
0018 #include <asm/pgtable.h>
0019 #include <asm/frame.inc>
0020 #include <asm/param.h>
0021 #include <unit/serial.h>
0022 #ifdef CONFIG_SMP
0023 #include <asm/smp.h>
0024 #include <asm/intctl-regs.h>
0025 #include <asm/cpu-regs.h>
0026 #include <proc/smp-regs.h>
0027 #endif /* CONFIG_SMP */
0028 
0029     __HEAD
0030 
0031 ###############################################################################
0032 #
0033 # bootloader entry point
0034 #
0035 ###############################################################################
0036     .globl  _start
0037     .type   _start,@function
0038 _start:
0039 #ifdef CONFIG_SMP
0040     #
0041     # If this is a secondary CPU (AP), then deal with that elsewhere
0042     #
0043     mov (CPUID),d3
0044     and CPUID_MASK,d3
0045     bne startup_secondary
0046 
0047     #
0048     # We're dealing with the primary CPU (BP) here, then.
0049     # Keep BP's D0,D1,D2 register for boot check.
0050     #
0051 
0052     # Set up the Boot IPI for each secondary CPU
0053     mov 0x1,a0
0054 loop_set_secondary_icr:
0055     mov a0,a1
0056     asl CROSS_ICR_CPU_SHIFT,a1
0057     add CROSS_GxICR(SMP_BOOT_IRQ,0),a1
0058     movhu   (a1),d3
0059     or  GxICR_ENABLE|GxICR_LEVEL_0,d3
0060     movhu   d3,(a1)
0061     movhu   (a1),d3             # flush
0062     inc a0
0063     cmp NR_CPUS,a0
0064     bne loop_set_secondary_icr
0065 #endif /* CONFIG_SMP */
0066 
0067     # save commandline pointer
0068     mov d0,a3
0069 
0070     # preload the PGD pointer register
0071     mov swapper_pg_dir,d0
0072     mov d0,(PTBR)
0073     clr d0
0074     movbu   d0,(PIDR)
0075 
0076     # turn on the TLBs
0077     mov MMUCTR_IIV|MMUCTR_DIV,d0
0078     mov d0,(MMUCTR)
0079 #ifdef CONFIG_AM34_2
0080     mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
0081 #else
0082     mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
0083 #endif
0084     mov d0,(MMUCTR)
0085 
0086     # turn on AM33v2 exception handling mode and set the trap table base
0087     movhu   (CPUP),d0
0088     or  CPUP_EXM_AM33V2,d0
0089     movhu   d0,(CPUP)
0090     mov CONFIG_INTERRUPT_VECTOR_BASE,d0
0091     mov d0,(TBR)
0092 
0093     # invalidate and enable both of the caches
0094 #ifdef CONFIG_SMP
0095     mov ECHCTR,a0
0096     clr d0
0097     mov d0,(a0)
0098 #endif
0099     mov CHCTR,a0
0100     clr d0
0101     movhu   d0,(a0)                 # turn off first
0102     mov CHCTR_ICINV|CHCTR_DCINV,d0
0103     movhu   d0,(a0)
0104     setlb
0105     mov (a0),d0
0106     btst    CHCTR_ICBUSY|CHCTR_DCBUSY,d0        # wait till not busy
0107     lne
0108 
0109 #ifdef CONFIG_MN10300_CACHE_ENABLED
0110 #ifdef CONFIG_MN10300_CACHE_WBACK
0111 #ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
0112     mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
0113 #else
0114     mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
0115 #endif /* NOWRALLOC */
0116 #else
0117     mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
0118 #endif /* WBACK */
0119     movhu   d0,(a0)                 # enable
0120 #endif /* ENABLED */
0121 
0122     # turn on RTS on the debug serial port if applicable
0123 #ifdef CONFIG_MN10300_UNIT_ASB2305
0124     bset    UART_MCR_RTS,(ASB2305_DEBUG_MCR)
0125 #endif
0126 
0127     # clear the BSS area
0128     mov __bss_start,a0
0129     mov __bss_stop,a1
0130     clr d0
0131 bssclear:
0132     cmp a1,a0
0133     bge bssclear_end
0134     mov d0,(a0)
0135     inc4    a0
0136     bra bssclear
0137 bssclear_end:
0138 
0139     # retrieve the parameters (including command line) before we overwrite
0140     # them
0141     cmp 0xabadcafe,d1
0142     bne __no_parameters
0143 
0144 __copy_parameters:
0145     mov redboot_command_line,a0
0146     mov a0,a1
0147     add COMMAND_LINE_SIZE,a1
0148 1:
0149     movbu   (a3),d0
0150     inc a3
0151     movbu   d0,(a0)
0152     inc a0
0153     cmp a1,a0
0154     blt 1b
0155 
0156     mov redboot_platform_name,a0
0157     mov a0,a1
0158     add COMMAND_LINE_SIZE,a1
0159     mov d2,a3
0160 1:
0161     movbu   (a3),d0
0162     inc a3
0163     movbu   d0,(a0)
0164     inc a0
0165     cmp a1,a0
0166     blt 1b
0167 
0168 __no_parameters:
0169 
0170     # set up the registers with recognisable rubbish in them
0171     mov init_thread_union+THREAD_SIZE-12,sp
0172 
0173     mov 0xea01eaea,d0
0174     mov d0,(4,sp)       # EPSW save area
0175     mov 0xea02eaea,d0
0176     mov d0,(8,sp)       # PC save area
0177 
0178     mov 0xeb0060ed,d0
0179     mov d0,mdr
0180     mov 0xeb0061ed,d0
0181     mov d0,mdrq
0182     mov 0xeb0062ed,d0
0183     mov d0,mcrh
0184     mov 0xeb0063ed,d0
0185     mov d0,mcrl
0186     mov 0xeb0064ed,d0
0187     mov d0,mcvf
0188     mov 0xed0065ed,a3
0189     mov a3,usp
0190 
0191     mov 0xed00e0ed,e0
0192     mov 0xed00e1ed,e1
0193     mov 0xed00e2ed,e2
0194     mov 0xed00e3ed,e3
0195     mov 0xed00e4ed,e4
0196     mov 0xed00e5ed,e5
0197     mov 0xed00e6ed,e6
0198     mov 0xed00e7ed,e7
0199 
0200     mov 0xed00d0ed,d0
0201     mov 0xed00d1ed,d1
0202     mov 0xed00d2ed,d2
0203     mov 0xed00d3ed,d3
0204     mov 0xed00a0ed,a0
0205     mov 0xed00a1ed,a1
0206     mov 0xed00a2ed,a2
0207     mov 0,a3
0208 
0209     # set up the initial kernel stack
0210     SAVE_ALL
0211     mov 0xffffffff,d0
0212     mov d0,(REG_ORIG_D0,fp)
0213 
0214     # put different recognisable rubbish in the regs
0215     mov 0xfb0060ed,d0
0216     mov d0,mdr
0217     mov 0xfb0061ed,d0
0218     mov d0,mdrq
0219     mov 0xfb0062ed,d0
0220     mov d0,mcrh
0221     mov 0xfb0063ed,d0
0222     mov d0,mcrl
0223     mov 0xfb0064ed,d0
0224     mov d0,mcvf
0225     mov 0xfd0065ed,a0
0226     mov a0,usp
0227 
0228     mov 0xfd00e0ed,e0
0229     mov 0xfd00e1ed,e1
0230     mov 0xfd00e2ed,e2
0231     mov 0xfd00e3ed,e3
0232     mov 0xfd00e4ed,e4
0233     mov 0xfd00e5ed,e5
0234     mov 0xfd00e6ed,e6
0235     mov 0xfd00e7ed,e7
0236 
0237     mov 0xfd00d0ed,d0
0238     mov 0xfd00d1ed,d1
0239     mov 0xfd00d2ed,d2
0240     mov 0xfd00d3ed,d3
0241     mov 0xfd00a0ed,a0
0242     mov 0xfd00a1ed,a1
0243     mov 0xfd00a2ed,a2
0244 
0245     # we may be holding current in E2
0246 #ifdef CONFIG_MN10300_CURRENT_IN_E2
0247     mov init_task,e2
0248 #endif
0249 
0250     # initialise the processor and the unit
0251     call    processor_init[],0
0252     call    unit_init[],0
0253 
0254 #ifdef CONFIG_SMP
0255     # mark the primary CPU in cpu_boot_map
0256     mov cpu_boot_map,a0
0257     mov 0x1,d0
0258     mov d0,(a0)
0259 
0260     # signal each secondary CPU to begin booting
0261     mov 0x1,d2              # CPU ID
0262 
0263 loop_request_boot_secondary:
0264     mov d2,a0
0265     # send SMP_BOOT_IPI to secondary CPU
0266     asl CROSS_ICR_CPU_SHIFT,a0
0267     add CROSS_GxICR(SMP_BOOT_IRQ,0),a0
0268     movhu   (a0),d0
0269     or  GxICR_REQUEST|GxICR_DETECT,d0
0270     movhu   d0,(a0)
0271     movhu   (a0),d0             # flush
0272 
0273     # wait up to 100ms for AP's IPI to be received
0274     clr d3
0275 wait_on_secondary_boot:
0276     mov DELAY_TIME_BOOT_IPI,d0
0277     call    __delay[],0
0278     inc d3
0279     mov cpu_boot_map,a0
0280     mov (a0),d0
0281     lsr d2,d0
0282     btst    0x1,d0
0283     bne 1f
0284     cmp TIME_OUT_COUNT_BOOT_IPI,d3
0285     bne wait_on_secondary_boot
0286 1:
0287     inc d2
0288     cmp NR_CPUS,d2
0289     bne loop_request_boot_secondary
0290 #endif /* CONFIG_SMP */
0291 
0292 #ifdef CONFIG_GDBSTUB
0293     call    gdbstub_init[],0
0294 
0295 #ifdef CONFIG_GDBSTUB_IMMEDIATE
0296     .globl  __gdbstub_pause
0297 __gdbstub_pause:
0298     bra __gdbstub_pause
0299 #endif
0300 #endif
0301 
0302     jmp start_kernel
0303     .size   _start,.-_start
0304 
0305 ###############################################################################
0306 #
0307 # Secondary CPU boot point
0308 #
0309 ###############################################################################
0310 #ifdef CONFIG_SMP
0311 startup_secondary:
0312     # preload the PGD pointer register
0313     mov swapper_pg_dir,d0
0314     mov d0,(PTBR)
0315     clr d0
0316     movbu   d0,(PIDR)
0317 
0318     # turn on the TLBs
0319     mov MMUCTR_IIV|MMUCTR_DIV,d0
0320     mov d0,(MMUCTR)
0321 #ifdef CONFIG_AM34_2
0322     mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
0323 #else
0324     mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
0325 #endif
0326     mov d0,(MMUCTR)
0327 
0328     # turn on AM33v2 exception handling mode and set the trap table base
0329     movhu   (CPUP),d0
0330     or  CPUP_EXM_AM33V2,d0
0331     movhu   d0,(CPUP)
0332 
0333     # set the interrupt vector table
0334     mov CONFIG_INTERRUPT_VECTOR_BASE,d0
0335     mov d0,(TBR)
0336 
0337     # invalidate and enable both of the caches
0338     mov ECHCTR,a0
0339     clr d0
0340     mov d0,(a0)
0341     mov CHCTR,a0
0342     clr d0
0343     movhu   d0,(a0)                 # turn off first
0344     mov CHCTR_ICINV|CHCTR_DCINV,d0
0345     movhu   d0,(a0)
0346     setlb
0347     mov (a0),d0
0348     btst    CHCTR_ICBUSY|CHCTR_DCBUSY,d0        # wait till not busy (use CPU loop buffer)
0349     lne
0350 
0351 #ifdef CONFIG_MN10300_CACHE_ENABLED
0352 #ifdef  CONFIG_MN10300_CACHE_WBACK
0353 #ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
0354     mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
0355 #else
0356     mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
0357 #endif  /* !NOWRALLOC */
0358 #else
0359     mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
0360 #endif  /* WBACK */
0361     movhu   d0,(a0)                 # enable
0362 #endif  /* ENABLED */
0363 
0364     # Clear the boot IPI interrupt for this CPU
0365     movhu   (GxICR(SMP_BOOT_IRQ)),d0
0366     and ~GxICR_REQUEST,d0
0367     movhu   d0,(GxICR(SMP_BOOT_IRQ))
0368     movhu   (GxICR(SMP_BOOT_IRQ)),d0        # flush
0369 
0370     /* get stack */
0371     mov CONFIG_INTERRUPT_VECTOR_BASE + CONFIG_BOOT_STACK_OFFSET,a0
0372     mov (CPUID),d0
0373     and CPUID_MASK,d0
0374     mulu    CONFIG_BOOT_STACK_SIZE,d0
0375     sub d0,a0
0376     mov a0,sp
0377 
0378     # init interrupt for AP
0379     call    smp_prepare_cpu_init[],0
0380 
0381     # mark this secondary CPU in cpu_boot_map
0382     mov (CPUID),d0
0383     mov 0x1,d1
0384     asl d0,d1
0385     mov cpu_boot_map,a0
0386     bset    d1,(a0)
0387 
0388     or  EPSW_IE|EPSW_IM_1,epsw  # permit level 0 interrupts
0389     nop
0390     nop
0391 #ifdef  CONFIG_MN10300_CACHE_WBACK
0392     # flush the local cache if it's in writeback mode
0393     call    mn10300_local_dcache_flush_inv[],0
0394     setlb
0395     mov (CHCTR),d0
0396     btst    CHCTR_DCBUSY,d0     # wait till not busy (use CPU loop buffer)
0397     lne
0398 #endif
0399 
0400     # now sleep waiting for further instructions
0401 secondary_sleep:
0402     mov CPUM_SLEEP,d0
0403     movhu   d0,(CPUM)
0404     nop
0405     nop
0406     bra secondary_sleep
0407     .size   startup_secondary,.-startup_secondary
0408 #endif /* CONFIG_SMP */
0409 
0410 ###############################################################################
0411 #
0412 #
0413 #
0414 ###############################################################################
0415 ENTRY(__head_end)
0416 
0417 /*
0418  * This is initialized to disallow all access to the low 2G region
0419  * - the high 2G region is managed directly by the MMU
0420  * - range 0x70000000-0x7C000000 are initialised for use by VMALLOC
0421  */
0422     .section .bss
0423     .balign PAGE_SIZE
0424 ENTRY(swapper_pg_dir)
0425         .space PTRS_PER_PGD*4
0426 
0427 /*
0428  * The page tables are initialized to only 8MB here - the final page
0429  * tables are set up later depending on memory size.
0430  */
0431 
0432     .balign PAGE_SIZE
0433 ENTRY(empty_zero_page)
0434     .space PAGE_SIZE
0435 
0436     .balign PAGE_SIZE
0437 ENTRY(empty_bad_page)
0438     .space PAGE_SIZE
0439 
0440     .balign PAGE_SIZE
0441 ENTRY(empty_bad_pte_table)
0442     .space PAGE_SIZE
0443 
0444     .balign PAGE_SIZE
0445 ENTRY(large_page_table)
0446     .space PAGE_SIZE
0447 
0448     .balign PAGE_SIZE
0449 ENTRY(kernel_vmalloc_ptes)
0450     .space ((VMALLOC_END-VMALLOC_START)/PAGE_SIZE)*4