基于S3C4510B的BSP入口函数romInit.s详解
|
(一) romInit.s
/********************** romInit.s 的ROM初始化模块 ***************/
.data
.globl _copyright_wind_river
.long _copyright_wind_river
/****************************************************************************************/
描述:
(1) 该模块包含bootrom和vxworks_rom(从rom中启动的vxworks映象)的入口,入口函数
是romInit(),该函数是在系统上电时第一个被执行的函数,它进行最小的初始化工作,为C函
数的运行准备条件,该函数最后调用all/bootInit.c文件中的romStart()函数,并传递启动
类型参数BOOT_COLD(冷启动)给romStart();
(2)ronInit()屏蔽处理器中断和中断控制器,设置初始的堆栈指针到STACK_ADRS(该地址在
all/configAll.h中定义),其他的硬件初始化工作(如串口的初始化)在sysLib.c中的
sysHwInit()中完成;
(3)sysLib.c中的函数sysToMonitor()只是把pc指针跳转到romInit标号后面进行系统的热启动
(跳转地址为ROM_WARM_ADRS),并把启动类型传递到romStart();
******************************************************************************************/
#define _ASMLANGUAGE
#include "vxWorks.h"
#include "sysLib.h"
#include "arch/arm/arm.h"
#include "arch/arm/mmuArmLib.h"
#include "config.h"
#include "regs.h"
/* internals */
.globl _romInit /* 只是申明_romInit为全局标号 */
.globl _sdata /* 申明_sdata全局标号 */
/* externals */
.globl _romStart /* 申明外部函数romStart */
_sdata: /* _sdata的真正定义在此处 */
.asciz "start of data"
.balign 4
.text
.balign 4
_ARM_FUNCTION(_romInit) /* _romInit的真正定义在此处 */
cold:
MOV r0, #BOOT_COLD /* 保存启动类型BOOT_COLD到r0中 */
warm: /* sysToMonitor()函数跳转到此处进行热启动 */
B start
/*下面的该字符串不要随便更改,在sysToMonitor()处进行了检查 */
.ascii "Copyright 1984-1998 Wind River Systems, Inc."
.balign 4
start:
MRS r1, cpsr
BIC r1, r1, #MASK_MODE
ORR r1, r1, #MODE_SVC32 | I_BIT | F_BIT
MSR cpsr, r1 /*这几个语句禁止中断,设置为管理模式*/
MOV r13, r0 /* 保存启动类型到r13中,后面要使用r0寄存器 */
LDR r2, L$_SndsIntmsk /* 0x4008为4510B的INTMASK中断屏蔽寄存器地址 */
MVN r1, #0 /* &FFFFFFFF */
STR r1, [r2] /* 屏蔽所有的中断源(4510B共计支持21个中断源) */
CMP r0, #BOOT_COLD /* 如果不是冷启动,则不重新进行内存的配置,跳过下面的代码*/
BNE HiPosn
MOV r0, #DRAM_TYPE /* 在config.h中配置为0x01,即SDRAM */
CMP r0, #0x01 /* SDRAM = 0x01, EDO DRAM = 0x00 */
BNE EDO_RAM /* 如果不是SDRAM则跳过下面的语句 */
SYNC_DRAM:
LDR r0, L$_SndsSyscfg /*0x3ff0000为4510B的系统管理配置寄存器:SYSCFG */
LDR r1, L$_SysCfgSdram
STR r1, [r0]
/********************对此处SYSCFG配置值的说明*****************************************
L$_SysCfgSdram的值为1000,0111,1111,1111,1111,1111,1001,0000,
CE:0 即屏蔽cache,WE:0,即屏蔽写缓冲,CM:01:即cache模式为8K cache;
内部SRAM基地址为11,1111,1110,即0x3FE,0000
特殊寄存器基地址为:11,1111,1111,即:3FF0000,
产品号PD_ID为:00001,即S3C4510X,
SDRAM模式为1:4个DRAM组均为SDRAM接口
*************************************************************************************/
LDR r1, L$_SystemInitDataSDRAM
LDR r2, L$_SystemInitDataSDRAM + 0x04
LDR r3, L$_SystemInitDataSDRAM + 0x08
LDR r4, L$_SystemInitDataSDRAM + 0x0c
LDR r5, L$_SystemInitDataSDRAM + 0x10
LDR r6, L$_SystemInitDataSDRAM + 0x14
LDR r7, L$_SystemInitDataSDRAM + 0x18
LDR r8, L$_SystemInitDataSDRAM + 0x1c
LDR r9, L$_SystemInitDataSDRAM + 0x20
LDR r10,L$_SystemInitDataSDRAM + 0x24
LDR r11,L$_SystemInitDataSDRAM + 0x28
LDR r12,L$_SystemInitDataSDRAM + 0x2c
LDR r0, L$_SndsExtdbwth /* Extdbwth Offset : 0x3010 */
STMIA r0, {r1-r12} /*r1->[r0],r2->[r0+4],r3->[r0+8],.... */
/************ 对此处配置的说明,具体的配置值在snds100.h中定义 ****************************
数据总线宽度寄存器EXTDBWTH(0x3010):ROM0和ROM1为半字(16位)宽度,其余ROM和DRAM的都是32位宽度!
ROM/SRAM/FLASH组0控制寄存器 ROMCON0(0X3014):ROM0的起始地址为0,结束地址为0x80000;
ROM/SRAM/FLASH组1控制寄存器 ROMCON1(0X3018):0x60,普通ROM,页访问周期5个周期,可编程访问周期7个周期,首尾地址都为0
ROM/SRAM/FLASH组2控制寄存器 ROMCON2(0X301C):0x60,普通ROM,页访问周期5个周期,可编程访问周期7个周期,首尾地址都为0
ROM/SRAM/FLASH组3控制寄存器 ROMCON3(0X3020):0x60,普通ROM,页访问周期5个周期,可编程访问周期7个周期,首尾地址都为0
ROM/SRAM/FLASH组4控制寄存器 ROMCON4(0X3024):0x60,普通ROM,页访问周期5个周期,可编程访问周期7个周期,首尾地址都为0
ROM/SRAM/FLASH组5控制寄存器 ROMCON5(0X3028):0x60,普通ROM,页访问周期5个周期,可编程访问周期7个周期,首尾地址都为0
DRAM组0控制寄存器 DRAMCON0(0X302C):基地址为0x1000000,结束地址为:0x1400000,即实际内存大小为4M
DRAM组0控制寄存器 DRAMCON1(0X3030):0x00,无效
DRAM组0控制寄存器 DRAMCON2(0X3034):0x00,无效
DRAM组0控制寄存器 DRAMCON3(0X3038):0x00,无效
外部IO组基地址控制寄存器REFEXTCON(0X303C):外部IO基地址为0x3600000
***************************************************************************************/
MOV r0, #RESET_ROM_START /* ROM的起始地址:0x0,在snds100.h中定义 */
MOV r1, #ROM_SIZE /* 0x0080000,在config.h中定义,512K*/
MOV r2, #RESET_DRAM_START /* SDRAM起始地址:0x1000000,在snds100.h中定义 */
ROM2SDRAM_COPY_LOOP:
LDR r3, [r0], #4 /*[r0]->r3,r0+4->r0 */
STR r3, [r2], #4 /*[r2]<-r3,r2+4->r2 */
SUBS r1, r1, #4 /* Down Count */
BNE ROM2SDRAM_COPY_LOOP /* 把代码从ROM中的0地址处拷贝到SDRAM中起始地址处,拷贝512K长度*/
/*注意:代码运行到此处,在ROM中和在SDRAM中各存在一份代码,但执行的还是ROM中的代码*/
LDR r1, L$_SystemInitDataSDRAM_S
LDR r2, L$_SystemInitDataSDRAM_S + 0x04
LDR r3, L$_SystemInitDataSDRAM_S + 0x08
LDR r4, L$_SystemInitDataSDRAM_S + 0x0c
LDR r5, L$_SystemInitDataSDRAM_S + 0x10
LDR r6, L$_SystemInitDataSDRAM_S + 0x14
LDR r7, L$_SystemInitDataSDRAM_S + 0x18
LDR r8, L$_SystemInitDataSDRAM_S + 0x1c
LDR r9, L$_SystemInitDataSDRAM_S + 0x20
LDR r10,L$_SystemInitDataSDRAM_S + 0x24
LDR r11,L$_SystemInitDataSDRAM_S + 0x28
LDR r12,L$_SystemInitDataSDRAM_S + 0x2c
LDR r0, L$_SndsExtdbwth /* ROMCntr Offset : 0x3010 */
STMIA r0, {r1-r12}
/*此处重新映射系统的ROM和SDRAM的地址,把ROM的起始地址映射到0x1000000~0x1800000,即16M开始的512K空间 SDRAM1映射到0~0x400000,即4M的地址空间,其余的不作改变 */
LDR PC, L$_HiPosn
/*到此处时,由于系统的地址进行了重新的映射,所以需要重新进行定位,其实就是到HiPosn进行执行*/
/*下面的代码进行EDORAM的初始化配置,过程与SDRAM相同,不在说明*/
EDO_RAM:
LDR r0, L$_SndsSyscfg
LDR r1, L$_SysCfg
STR r1, [r0]
LDR r1, L$_SystemInitData
LDR r2, L$_SystemInitData + 0x04
LDR r3, L$_SystemInitData + 0x08
LDR r4, L$_SystemInitData + 0x0c
LDR r5, L$_SystemInitData + 0x10
LDR r6, L$_SystemInitData + 0x14
LDR r7, L$_SystemInitData + 0x18
LDR r8, L$_SystemInitData + 0x1c
LDR r9, L$_SystemInitData + 0x20
LDR r10,L$_SystemInitData + 0x24
LDR r11,L$_SystemInitData + 0x28
LDR r12,L$_SystemInitData + 0x2c
LDR r0, L$_SndsExtdbwth /* ROMCntr Offset : 0x3010 */
STMIA r0, {r1-r12}
MOV r0, #RESET_ROM_START /* Get pointer to ROM data */
MOV r1, #ROM_SIZE /* and RAM copy */
MOV r2, #RESET_DRAM_START /* Copy DRAM area base */
ROM2DRAM_COPY_LOOP:
LDR r3, [r0], #4
STR r3, [r2], #4
SUBS r1, r1, #4 /* Down Count */
BNE ROM2DRAM_COPY_LOOP
LDR r1, L$_SystemInitData_S
LDR r2, L$_SystemInitData_S + 0x04
LDR r3, L$_SystemInitData_S + 0x08
LDR r4, L$_SystemInitData_S + 0x0c
LDR r5, L$_SystemInitData_S + 0x10
LDR r6, L$_SystemInitData_S + 0x14
LDR r7, L$_SystemInitData_S + 0x18
LDR r8, L$_SystemInitData_S + 0x1c
LDR r9, L$_SystemInitData_S + 0x20
LDR r10,L$_SystemInitData_S + 0x24
LDR r11,L$_SystemInitData_S + 0x28
LDR r12,L$_SystemInitData_S + 0x2c
LDR r0, L$_SndsExtdbwth
STMIA r0, {r1-r12}
LDR PC, L$_HiPosn
/* 上面的代码完成了EDO_RAM的配置、代码的拷贝、地址的重映射工作 */
HiPosn:
MOV r0, r13 /* 把启动类型重新保存到R0中 */
LDR sp, L$_STACK_ADDR /* 初始化堆栈指针 */
MOV fp, #0 /* 把C语言的FRAME置0 */
/*下面的代码跳转到romStart()函数 */
#if (CPU == ARM7TDMI_T)
LDR r12, L$_rStrtInRom
ORR r12, r12, #1
BX r12
#else
LDR pc, L$_rStrtInRom /* 跳转到romStart()中执行 */
#endif /* (CPU == ARM7TDMI_T) */
.balign 4
L$_HiPosn:
.long ROM_TEXT_ADRS + HiPosn - _romInit
/* 此时地址进行了重新的映射,所有需要进行重新定位,注意ROM_TEXT_ADRS的值需要与程序中的实际情况相一致 */
L$_rStrtInRom:
.long ROM_TEXT_ADRS + _romStart - _romInit
/* 得到romStart重新映射后的地址 */
L$_STACK_ADDR:
.long STACK_ADRS
L$_SndsIntmsk:
.long SNDS_INTMASK
L$_IopModReg:
.long SNDS_IOPMOD
L$_IopConReg:
.long SNDS_IOPCON
L$_IopDat:
.long SNDS_IOPDATA
L$_SndsRomcon0:
.long SNDS_ROMCON0
L$_SndsExtdbwth:
.long SNDS_EXTDBWTH
L$_SndsSyscfg:
.long SNDS_SYSCFG
L$_SysCfg:
.long SYSCONFIG_VAL
L$_SysCfgSdram:
.long SYSCONFIG_VAL_SDRAM
L$_SystemInitData:
.long rEXTDBWTH /* DRAM1(Half), ROM5(Byte), ROM1(Half), else 32bit */
.long rROMCON0 /* 0x0000000 ~ 0x40000, ROM0,256K,2cycle */
.long rROMCON1
.long rROMCON2
.long rROMCON3
.long rROMCON4
.long rROMCON5
.long rDRAMCON0 /* 0x1000000 ~ 0x13FFFFF, DRAM0 4M, */
.long rDRAMCON1
.long rDRAMCON2
.long rDRAMCON3
.long rREFEXTCON /* External I/O, Refresh */
L$_SystemInitData_S:
.long rEXTDBWTH /* DRAM1(Half), ROM5(Byte), ROM1(Half), else 32bit */
.long rROMCON0_S /* 0x1000000 ~ 0x1040000, ROM0,256K,2cycle */
.long rROMCON1
.long rROMCON2
.long rROMCON3
.long rROMCON4
.long rROMCON5
.long rDRAMCON0_S /* 0x0000000 ~ 0x03FFFFF, DRAM0 */
.long rDRAMCON1
.long rDRAMCON2
.long rDRAMCON3
.long rREFEXTCON /* External I/O, Refresh */
/*======================================================
* SDRAM System Initialize Data (KS32C50100 only)
*======================================================
*/
L$_SystemInitDataSDRAM:
.long rEXTDBWTH /* DRAM1(Half), ROM5(Byte), ROM1(Half), else 32bit */
.long rROMCON0 /* 0x0000000 ~ 0x40000, ROM0,256K,2cycle */
.long rROMCON1
.long rROMCON2
.long rROMCON3
.long rROMCON4
.long rROMCON5
.long rSDRAMCON0 /* 0x1000000 ~ 0x13FFFFF, DRAM0 4M, */
.long rSDRAMCON1
.long rSDRAMCON2
.long rSDRAMCON3
.long rSREFEXTCON /* External I/O, Refresh */
L$_SystemInitDataSDRAM_S:
.long rEXTDBWTH /* DRAM1(Half), ROM5(Byte), ROM1(Half), else 32bit */
.long rROMCON0_S /* 0x1000000 ~ 0x1040000, ROM0,256K,2cycle */
.long rROMCON1
.long rROMCON2
.long rROMCON3
.long rROMCON4
.long rROMCON5
.long rSDRAMCON0_S /* 0x0000000 ~ 0x03FFFFF, DRAM0 4M, */
.long rSDRAMCON1
.long rSDRAMCON2
.long rSDRAMCON3
.long rSREFEXTCON /* External I/O, Refresh */
L$_pSystemInitData:
.long L$_SystemInitData
L$_pSystemInitData_S:
.long L$_SystemInitData_S
L$_pSystemInitDataSDRAM:
.long L$_SystemInitDataSDRAM
L$_pSystemInitDataSDRAM_S:
.long L$_SystemInitDataSDRAM_S