Path: blob/master/arch/m68k/platform/coldfire/head.S
10819 views
/*****************************************************************************/12/*3* head.S -- common startup code for ColdFire CPUs.4*5* (C) Copyright 1999-2010, Greg Ungerer <[email protected]>.6*/78/*****************************************************************************/910#include <linux/linkage.h>11#include <linux/init.h>12#include <asm/asm-offsets.h>13#include <asm/coldfire.h>14#include <asm/mcfsim.h>15#include <asm/thread_info.h>1617/*****************************************************************************/1819/*20* If we don't have a fixed memory size, then lets build in code21* to auto detect the DRAM size. Obviously this is the preferred22* method, and should work for most boards. It won't work for those23* that do not have their RAM starting at address 0, and it only24* works on SDRAM (not boards fitted with SRAM).25*/26#if CONFIG_RAMSIZE != 027.macro GET_MEM_SIZE28movel #CONFIG_RAMSIZE,%d0 /* hard coded memory size */29.endm3031#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \32defined(CONFIG_M5249) || defined(CONFIG_M527x) || \33defined(CONFIG_M528x) || defined(CONFIG_M5307) || \34defined(CONFIG_M5407)35/*36* Not all these devices have exactly the same DRAM controller,37* but the DCMR register is virtually identical - give or take38* a couple of bits. The only exception is the 5272 devices, their39* DRAM controller is quite different.40*/41.macro GET_MEM_SIZE42movel MCFSIM_DMR0,%d0 /* get mask for 1st bank */43btst #0,%d0 /* check if region enabled */44beq 1f45andl #0xfffc0000,%d046beq 1f47addl #0x00040000,%d0 /* convert mask to size */481:49movel MCFSIM_DMR1,%d1 /* get mask for 2nd bank */50btst #0,%d1 /* check if region enabled */51beq 2f52andl #0xfffc0000,%d153beq 2f54addl #0x00040000,%d155addl %d1,%d0 /* total mem size in d0 */562:57.endm5859#elif defined(CONFIG_M5272)60.macro GET_MEM_SIZE61movel MCF_MBAR+MCFSIM_CSOR7,%d0 /* get SDRAM address mask */62andil #0xfffff000,%d0 /* mask out chip select options */63negl %d0 /* negate bits */64.endm6566#elif defined(CONFIG_M520x)67.macro GET_MEM_SIZE68clrl %d069movel MCFSIM_SDCS0, %d2 /* Get SDRAM chip select 0 config */70andl #0x1f, %d2 /* Get only the chip select size */71beq 3f /* Check if it is enabled */72addql #1, %d2 /* Form exponent */73moveql #1, %d074lsll %d2, %d0 /* 2 ^ exponent */753:76movel MCFSIM_SDCS1, %d2 /* Get SDRAM chip select 1 config */77andl #0x1f, %d2 /* Get only the chip select size */78beq 4f /* Check if it is enabled */79addql #1, %d2 /* Form exponent */80moveql #1, %d181lsll %d2, %d1 /* 2 ^ exponent */82addl %d1, %d0 /* Total size of SDRAM in d0 */834:84.endm8586#else87#error "ERROR: I don't know how to probe your boards memory size?"88#endif8990/*****************************************************************************/9192/*93* Boards and platforms can do specific early hardware setup if94* they need to. Most don't need this, define away if not required.95*/96#ifndef PLATFORM_SETUP97#define PLATFORM_SETUP98#endif99100/*****************************************************************************/101102.global _start103.global _rambase104.global _ramvec105.global _ramstart106.global _ramend107#if defined(CONFIG_UBOOT)108.global _init_sp109#endif110111/*****************************************************************************/112113.data114115/*116* During startup we store away the RAM setup. These are not in the117* bss, since their values are determined and written before the bss118* has been cleared.119*/120_rambase:121.long 0122_ramvec:123.long 0124_ramstart:125.long 0126_ramend:127.long 0128#if defined(CONFIG_UBOOT)129_init_sp:130.long 0131#endif132133/*****************************************************************************/134135__HEAD136137/*138* This is the codes first entry point. This is where it all139* begins...140*/141142_start:143nop /* filler */144movew #0x2700, %sr /* no interrupts */145#if defined(CONFIG_UBOOT)146movel %sp,_init_sp /* save initial stack pointer */147#endif148149/*150* Do any platform or board specific setup now. Most boards151* don't need anything. Those exceptions are define this in152* their board specific includes.153*/154PLATFORM_SETUP155156/*157* Create basic memory configuration. Set VBR accordingly,158* and size memory.159*/160movel #CONFIG_VECTORBASE,%a7161movec %a7,%VBR /* set vectors addr */162movel %a7,_ramvec163164movel #CONFIG_RAMBASE,%a7 /* mark the base of RAM */165movel %a7,_rambase166167GET_MEM_SIZE /* macro code determines size */168addl %a7,%d0169movel %d0,_ramend /* set end ram addr */170171/*172* Now that we know what the memory is, lets enable cache173* and get things moving. This is Coldfire CPU specific. Not174* all version cores have identical cache register setup. But175* it is very similar. Define the exact settings in the headers176* then the code here is the same for all.177*/178movel #CACHE_INIT,%d0 /* invalidate whole cache */179movec %d0,%CACR180nop181movel #ACR0_MODE,%d0 /* set RAM region for caching */182movec %d0,%ACR0183movel #ACR1_MODE,%d0 /* anything else to cache? */184movec %d0,%ACR1185#ifdef ACR2_MODE186movel #ACR2_MODE,%d0187movec %d0,%ACR2188movel #ACR3_MODE,%d0189movec %d0,%ACR3190#endif191movel #CACHE_MODE,%d0 /* enable cache */192movec %d0,%CACR193nop194195#ifdef CONFIG_ROMFS_FS196/*197* Move ROM filesystem above bss :-)198*/199lea _sbss,%a0 /* get start of bss */200lea _ebss,%a1 /* set up destination */201movel %a0,%a2 /* copy of bss start */202203movel 8(%a0),%d0 /* get size of ROMFS */204addql #8,%d0 /* allow for rounding */205andl #0xfffffffc, %d0 /* whole words */206207addl %d0,%a0 /* copy from end */208addl %d0,%a1 /* copy from end */209movel %a1,_ramstart /* set start of ram */210211_copy_romfs:212movel -(%a0),%d0 /* copy dword */213movel %d0,-(%a1)214cmpl %a0,%a2 /* check if at end */215bne _copy_romfs216217#else /* CONFIG_ROMFS_FS */218lea _ebss,%a1219movel %a1,_ramstart220#endif /* CONFIG_ROMFS_FS */221222223/*224* Zero out the bss region.225*/226lea _sbss,%a0 /* get start of bss */227lea _ebss,%a1 /* get end of bss */228clrl %d0 /* set value */229_clear_bss:230movel %d0,(%a0)+ /* clear each word */231cmpl %a0,%a1 /* check if at end */232bne _clear_bss233234/*235* Load the current task pointer and stack.236*/237lea init_thread_union,%a0238lea THREAD_SIZE(%a0),%sp239240/*241* Assember start up done, start code proper.242*/243jsr start_kernel /* start Linux kernel */244245_exit:246jmp _exit /* should never get here */247248/*****************************************************************************/249250251