www.pudn.com > at91rm9200bsp.rar > romInitasm.s


/* romInit.s - ARM Integrator ROM initialization module */


/*
modification history
--------------------
2004/10/23 this file is modified form VxWorks demo bsp integrator920t
*/

/*
DESCRIPTION
This module contains the entry code for VxWorks images that start
running from ROM, such as 'bootrom' and 'vxWorks_rom'.  The entry
point, romInit(), is the first code executed on power-up.  It performs
the minimal setup needed to call the generic C routine romStart() with
parameter BOOT_COLD.

romInit() masks interrupts in the processor and the interrupt
controller and sets the initial stack pointer (to STACK_ADRS which is
defined in configAll.h).  Other hardware and device initialisation is
performed later in the sysHwInit routine in sysLib.c.

The routine sysToMonitor() jumps to a location after the beginning of
romInit, (defined by ROM_WARM_ADRS) to perform a "warm boot".  This
entry point allows a parameter to be passed to romStart().

The routines in this module don't use the "C" frame pointer %r11@ ! or
establish a stack frame.

*/

#define	_ASMLANGUAGE
#include "vxWorks.h"
#include "sysLib.h"
#include "asm.h"
#include "regs.h"	
#include "config.h"
#include "arch/arm/mmuArmLib.h"

        .data
        .globl   VAR(copyright_wind_river)
        .long    VAR(copyright_wind_river)

/* internals */

	.globl	FUNC(romInit)		/* start of system code */
	
	.globl	VAR(sdata)		/* start of data */
        .globl  _sdata
	.globl	VAR(integratorMemSize)	/* actual memory size */


/* externals */

	.extern	FUNC(romStart)	/* system initialization routine */
	.extern FUNC(StartHwInit) 
	.extern FUNC( romCInitRtn )

_sdata:
VAR_LABEL(sdata)
	.asciz	"start of data"
	.balign	4


	.text
	.balign 4

/*******************************************************************************
*
* romInit - entry point for VxWorks in ROM
*

* romInit
*     (
*     int startType	/@ only used by 2nd entry point @/
*     )

* INTERNAL
* sysToMonitor examines the ROM for the first instruction and the string
* "Copy" in the third word so if this changes, sysToMonitor must be updated.
*/

_ARM_FUNCTION(romInit)
_romInit:
cold:
	MOV	r0, #BOOT_COLD	/* fall through to warm boot entry */
warm:
	B	start

	/* copyright notice appears at beginning of ROM (in TEXT segment) */

	.ascii   "Copyright 1999-2004 ARM Limited"
	.ascii   "\nCopyright 1999-2004 JSEPTRI, Inc."
	.balign 4

start:
	/*
	 * There have been reports of problems with certain boards and
	 * certain power supplies not coming up after a power-on reset,
	 * and adding a delay at the start of romInit appears to help
	 * with this.
	 */

	TEQS	r0, #BOOT_COLD
	MOVEQ	r1, #AT91RM9200_DELAY_VALUE
	MOVNE	r1, #1

delay_loop:
	SUBS	r1, r1, #1
	BNE	delay_loop

#if defined(CPU_920T)

	/*
	 * Set processor and MMU to known state as follows (we may have not
	 * been entered from a reset). We must do this before setting the CPU
	 * mode as we must set PROG32/DATA32.
	 *
	 * MMU Control Register layout.
	 *
	 * bit
	 *  0 M 0 MMU disabled
	 *  1 A 0 Address alignment fault disabled, initially
	 *  2 C 0 Data cache disabled
	 *  3 W 0 Write Buffer disabled
	 *  4 P 1 PROG32
	 *  5 D 1 DATA32
	 *  6 L 1 Should Be One (Late abort on earlier CPUs)
	 *  7 B ? Endianness (1 => big)
	 *  8 S 0 System bit to zero } Modifies MMU protections, not really
	 *  9 R 1 ROM bit to one     } relevant until MMU switched on later.
	 * 10 F 0 Should Be Zero
	 * 11 Z 0 Should Be Zero (Branch prediction control on 810)
	 * 12 I 0 Instruction cache control
	 */

	/* Setup MMU Control Register */

	MOV	r1, #MMU_INIT_VALUE		/* Defined in mmuArmLib.h */

#if defined(AT91RM9200_EARLY_I_CACHE_ENABLE)
	ORR	r1, r1, #MMUCR_I_ENABLE		/* conditionally enable Icache*/
#endif

	MCR	CP_MMU, 0, r1, c1, c0, 0	/* Write to MMU CR */

	/*
	 * If MMU was on before this, then we'd better hope it was set
	 * up for flat translation or there will be problems. The next
	 * 2/3 instructions will be fetched "translated" (number depends
	 * on CPU).
	 *
	 * We would like to discard the contents of the Write-Buffer
	 * altogether, but there is no facility to do this. Failing that,
	 * we do not want any pending writes to happen at a later stage,
	 * so drain the Write-Buffer, i.e. force any pending writes to
	 * happen now.
	 */

	MOV	r1, #0				/* data SBZ */
	MCR	CP_MMU, 0, r1, c7, c10, 4	/* drain write-buffer */

	/* Flush (invalidate) both I and D caches */

	MCR	CP_MMU, 0, r1, c7, c7, 0	/* R1 = 0 from above, data SBZ*/


        /*
	 * Set Process ID Register to zero, this effectively disables
	 * the process ID remapping feature.
	 */

	MOV	r1, #0
	MCR	CP_MMU, 0, r1, c13, c0, 0
#endif /* defined(CPU_720T,740T,920T,940T,946ES) */

	/* disable interrupts in CPU and switch to SVC32 mode */

	MRS	r1, cpsr
	BIC	r1, r1, #MASK_MODE
	ORR	r1, r1, #MODE_SVC32 | I_BIT | F_BIT
	MSR	cpsr, r1

	/*
	 * CPU INTERRUPTS DISABLED
	 *
	 * disable individual interrupts in the interrupt controller
	 */

	LDR	r2, =AIC_BASE_ADDR			/* R2->interrupt controller */
	MVN	r1, #0				/* &FFFFFFFF */
	STR	r1, [r2, #AIC_IDCR_OFFSET]	/* disable all IRQ sources */
	

	/*
	 * Jump to the normal (higher) ROM Position. After a reset, the
	 * ROM is mapped into memory from* location zero upwards as well
	 * as in its normal position at This code could be executing in
	 * the lower position. We wish to be executing the code, still
	 * in ROM, but in its normal (higher) position before we remap
	 * the machine so that the ROM is no longer dual-mapped from zero
	 * upwards, but so that RAM appears from 0 upwards.
	 */

	LDR	pc, L$_HiPosn
HiPosn:
	

	/*
	 * We are now executing in the normal (higher, still in ROM)
	 * position in the memory map.  Remap memory to post-reset state,
	 * so that the ROM is not now dual-mapped to zero upwards, but
	 * RAM is mapped from zero, instead.
	 */

	MOV	r1, #1
	LDR	r2, =MC_BASE_ADDR
	STR	r1, [r2, #MC_RCR_OFFSET]
 
 
	LDR sp, =ARM920T_ROMINIT_C_STACK_TOP 
 
	MOV lr, pc 
	LDR pc, L$_romCInit_ADDR  
	 

	/*
	 * SSRAM is now mapped from 0 upwards.
	 *
	 * Setup asynchronous clocking (eg. core and memory clocks different)
	 */
	
	/* disable all interrup for pmc */
	LDR r1, =PMC_BASE_ADDR
	LDR r2, =PMC_CKGR_MOR_VALUE
	STR r2, [r1,#PMC_CKGR_MOR_OFFSET]	/* start the Main osc */

	/*wait main os stabliize */
	LDR r3, =DELAY_MAIN_FREQ 
branch1:
	LDR r2, [r1, #(PMC_SR_OFFSET)]
	TST r2, #PMC_SR_MOSCS
	BNE branch2
	SUBS r3, r3, #1
	BGT  branch1
branch2:	

	/* main osc should stab now, continue startup PLLA */
	MVN r2, #0	/*0xfffffff disable all interrupt*/
	STR r2, [r1, #(PMC_IDR_OFFSET)]
	
	LDR r2, =PMC_PLLA_VALUE
	STR r2, [r1, #(PMC_CKGR_PLLAR_OFFSET)]
	
	LDR r3, =DELAY_MAIN_FREQ 
	LDR r4, =PMC_SR_LOCKA
	
branch3:
	LDR r2, [r1, #(PMC_SR_OFFSET)]
	TST r2, r4
	BNE branch4
	SUBS r3, r3, #1
	BGT branch3
	
branch4: 
	/* in order to ascess flash correctly, it seems need to fir setup SMC, and MC first
	1. setup EBI
	2. setup chip select 0(SMC)
	*/
	LDR r2, =EBI_CSA_VALUE
	LDR r1, =EBI_BASE_ADDR
	STR r2, [r1, #EBI_CSA_OFFSET]
	
	LDR r1, =SMC_BASE_ADDR
	LDR R2, =SMC_CSR0_VALUE
	STR r2, [r1, #SMC_CSR0_OFFSET]
	
	
	/* master clock setup, now the flash ascess time already setup
		write a dirty value to MCKR, the new MCKR value must not same as before
	  so make a dummy write to it first
	*/
	
	LDR r1, =PMC_BASE_ADDR
	LDR r2, =0x203
	STR r2, [r1, #(PMC_MCKR_OFFSET)]
	
	LDR r3, =DELAY_MAIN_FREQ  
		
branch5:	/*wait new state to be stability */
	LDR r2, [r1, #(PMC_SR_OFFSET)]
	TST r2, #PMC_SR_MCKRDY
	BNE branch6
	SUBS r3, r3, #1
	BGT branch5

branch6:		
		
	/*write real used set value to MCKR*/

	LDR r2, =PMC_MCKR_VALUE	/*select PLLA as master clock */
	STR r2, [r1, #(PMC_MCKR_OFFSET)]
	
	LDR r3, =DELAY_MAIN_FREQ  
		
branch7:	/*wait new state to be stability again*/
	LDR r2, [r1, #(PMC_SR_OFFSET)]
	TST r2, #PMC_SR_MCKRDY
	BNE branch8
	SUBS r3, r3, #1
	BGT branch7
	
branch8:	/* here we finished setup the process frequency and 
	MASTER clock frequency, and now we should run at 180MHz
	ok, now we need to setup SDRAM
	 */
 
 
	 
	 
	/* Configure PIOC as peripheral (D16/D31) */
	LDR r1, =PIOC_BASE_ADDR
	LDR r2, =PIOC_ENABLE_D16
	STR r2, [r1, #PIO_ASR_OFFSET]
	STR r2, [r1, #PIO_PDR_OFFSET]
	
	/*Init SDRAM, DBW is 32 bit always*/
	LDR r2, =SDRAMC_CR_VALUE
	LDR r1, =SDRAMC_BASE_ADDR
	STR r2, [r1, #SDRAMC_CR_OFFSET]
	
	MOV r2, #SDRAMC_MR_PRECHG
	STR r2, [r1, #SDRAMC_MR_OFFSET]
	
	LDR r3, =LOCAL_MEM_LOCAL_ADRS
	MOV r4, #0
	STR r4,[r3]
	 
		
	LDR r2, =SDRAMC_MR_REFLASH
	STR r2, [r1, #SDRAMC_MR_OFFSET]
	
	STR r4,[r3]
	STR r4,[r3]
	STR r4,[r3]
	STR r4,[r3]
	STR r4,[r3]
	STR r4,[r3]
	STR r4,[r3]
	STR r4,[r3]
		
	LDR r2, =SDRAMC_MR_LDMODE
	STR r2, [r1, #SDRAMC_MR_OFFSET]
	
	LDR r2, =SDRAMC_TR_VALUE
	STR r2, [r1, #SDRAMC_TR_OFFSET]
	
	MOV r2, #SDRAMC_MR_NORMAL
	STR r2, [r1, #SDRAMC_MR_OFFSET]
	
	
	/* we should finished the SDRAM init, what will we do next? */
	
	/*
	 * End of DRAM initialisation.
	 *
	 * Initialize the stack pointer to just before where the
	 * uncompress code, copied from ROM to RAM, will run.
	 */

	LDR	sp, L$_STACK_ADDR
	MOV	fp, #0			/* zero frame pointer */

	/* jump to C entry point in ROM: routine - entry point + ROM base */

#if	(ARM_THUMB)
	LDR	r12, L$_rStrtInRom
	ORR	r12, r12, #1		/* force Thumb state */
	BX	r12
#else
	LDR	pc, L$_rStrtInRom
#endif	/* (ARM_THUMB) */

/******************************************************************************/

/*
 * PC-relative-addressable pointers - LDR Rn,=sym is broken
 * note "_" after "$" to stop preprocessor performing substitution
 */

	.balign	4
	

L$_HiPosn:
	.long	ROM_TEXT_ADRS + HiPosn - FUNC(romInit)

L$_rStrtInRom:
	.long	ROM_TEXT_ADRS + FUNC(romStart) - FUNC(romInit)

L$_STACK_ADDR:
	.long	STACK_ADRS 
 
L$_romCInit_ADDR: 
	.long  ROM_TEXT_ADRS + FUNC(romCInitRtn) - FUNC(romInit)