这个文件主要是设置系统时钟,初始化flash,以及SDRAM。。。
..\u-boot-1.3.1\cpu\arm920t\at91rm9200\lowlevel_init.S
#include
#include
//CONFIG_SKIP_LOWLEVEL_INIT定义见..\u-boot-1.3.1\include\configs\at91rm9200dk.h
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
/*
* some parameters for the board
*
* This is based on rm9200dk.cfg for the BDI2000 from ABATRON which in
* turn is based on the boot.bin code from ATMEL
*
*/
//flash相关寄存器
/* flash */
#define MC_PUIA 0xFFFFFF10
#define MC_PUP 0xFFFFFF50
#define MC_PUER 0xFFFFFF54
#define MC_ASR 0xFFFFFF04
#define MC_AASR 0xFFFFFF08
#define EBI_CFGR 0xFFFFFF64
#define SMC2_CSR 0xFFFFFF70
//系统时钟相关寄存器
/* clocks */
#define PLLAR 0xFFFFFC28
#define PLLBR 0xFFFFFC2C
#define MCKR 0xFFFFFC30
#define AT91C_BASE_CKGR 0xFFFFFC20
#define CKGR_MOR 0
//sdram相关寄存器
/* sdram */
#define PIOC_ASR 0xFFFFF870
#define PIOC_BSR 0xFFFFF874
#define PIOC_PDR 0xFFFFF804
#define EBI_CSA 0xFFFFFF60
#define SDRC_CR 0xFFFFFF98
#define SDRC_MR 0xFFFFFF90
#define SDRC_TR 0xFFFFFF94
_MTEXT_BASE:
#undef START_FROM_MEM//从flash,还是从sdram启动,这里定义从sdram启动
#ifdef START_FROM_MEM
.word TEXT_BASE-PHYS_FLASH_1
#else
.word TEXT_BASE//TEXT_BASE在..\u-boot-1.3.1\board\at91rm9200dk\config.mk
#endif
.globl lowlevel_init
lowlevel_init:
/* Get the CKGR Base Address */
ldr r1, =AT91C_BASE_CKGR //初始化系统时钟
/* Main oscillator Enable register */
#ifdef CFG_USE_MAIN_OSCILLATOR
ldr r0, =0x0000FF01 /* Enable main oscillator, OSCOUNT = 0xFF */
#else
ldr r0, =0x0000FF00 /* Disable main oscillator, OSCOUNT = 0xFF */
#endif
str r0, [r1, #CKGR_MOR]
/* Add loop to compensate Main Oscillator startup time */
ldr r0, =0x00000010//这个地方相当与一段延时,保证系统时钟设置正常
LoopOsc:
subs r0, r0, #1
bhi LoopOsc
/* memory control configuration *///初始化flash
/* this isn't very elegant, but what the heck */
ldr r0, =SMRDATA //将标号SMRDATA所标识的地址写入r0
ldr r1, _MTEXT_BASE //将标号_MTEXT_BASE处的数据写入r1
sub r0, r0, r1 //得到相对起始地址 我总觉得这个地方有些问题,可很多人认为没有问题。。。。有待深究,是不是我多了呢?
add r2, r0, #80 //得到相对结束地址
0:
/* the address */
//不仔细的看,你还真发现不了这个地方的妙处,哈哈,想法挺好。。。。
//需要配合下面的表一起看,估计你就能明白了。
ldr r1, [r0], #4 //R1←[R0],R0←R0+4
/* the value */
ldr r3, [r0], #4
str r3, [r1]
cmp r2, r0
bne 0b
/* delay - this is all done by guess */
ldr r0, =0x00010000
1:
subs r0, r0, #1
bhi 1b
ldr r0, =SMRDATA1//初始化sdram
ldr r1, _MTEXT_BASE
sub r0, r0, r1
add r2, r0, #176
2:
/* the address */
ldr r1, [r0], #4
/* the value */
ldr r3, [r0], #4
str r3, [r1]
cmp r2, r0
bne 2b
/* switch from FastBus to Asynchronous clock mode */
//结合datasheet看,有详细的描述
mrc p15, 0, r0, c1, c0, 0 //将读出的数据放到r0中
orr r0, r0, #0xC0000000 @ set bit 31 (iA) and 30 (nF)
//主要是设置C1,异步模式;C0是只读的
mcr p15, 0, r0, c1, c0, 0
/* everything is fine now */
mov pc, lr
.ltorg
SMRDATA:
.word MC_PUIA
.word MC_PUIA_VAL//..\u-boot-1.3.1\include\configs\at91rm9200dk.h有定义
.word MC_PUP
.word MC_PUP_VAL
.word MC_PUER
.word MC_PUER_VAL
.word MC_ASR
.word MC_ASR_VAL
.word MC_AASR
.word MC_AASR_VAL
.word EBI_CFGR
.word EBI_CFGR_VAL
.word SMC2_CSR
.word SMC2_CSR_VAL
.word PLLAR
.word PLLAR_VAL
.word PLLBR
.word PLLBR_VAL
.word MCKR
.word MCKR_VAL
/* SMRDATA is 80 bytes long */
/* here there's a delay of 100 */
SMRDATA1:
.word PIOC_ASR
.word PIOC_ASR_VAL
.word PIOC_BSR
.word PIOC_BSR_VAL
.word PIOC_PDR
.word PIOC_PDR_VAL
.word EBI_CSA
.word EBI_CSA_VAL
.word SDRC_CR
.word SDRC_CR_VAL
.word SDRC_MR
.word SDRC_MR_VAL
.word SDRAM
.word SDRAM_VAL
.word SDRC_MR
.word SDRC_MR_VAL1
.word SDRAM
.word SDRAM_VAL
.word SDRAM
.word SDRAM_VAL
.word SDRAM
.word SDRAM_VAL
.word SDRAM
.word SDRAM_VAL
.word SDRAM
.word SDRAM_VAL
.word SDRAM
.word SDRAM_VAL
.word SDRAM
.word SDRAM_VAL
.word SDRAM
.word SDRAM_VAL
.word SDRC_MR
.word SDRC_MR_VAL2
.word SDRAM1
.word SDRAM_VAL
.word SDRC_TR
.word SDRC_TR_VAL
.word SDRAM
.word SDRAM_VAL
.word SDRC_MR
.word SDRC_MR_VAL3
.word SDRAM
.word SDRAM_VAL
/* SMRDATA1 is 176 bytes long */
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */