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)