缩写:
IOMUXC:input-output multiplexer controller输入/输出多路复用控制器
ALT:alternate functions交替功能
1.1 给系统上电
STARTUPTEXT
LEAF_ENTRY StartUp
; SYS_ON_OFF_CTL is connected to GPIO1_23(muxed on UART3_TXD as ALT3).
ldr r1, =(CSP_BASE_REG_PA_IOMUXC + 0x244)
ldr r0, =0x00000003
str r0, [r1]
CSP_BASE_REG_PA_IOMUXC定义了IO多路复用控制器起始地址,偏移0x244对应IOMUXC_SW_MUX_CTL_PAD_UART3_TXD寄存器,下面是此寄存器的描述:
图1
SION:配置为1强迫BGA此引脚的输入路径连接到UART3_TXD,而不管MUX_MODE模式的值;配置为0表示BGA此引脚的输入路径由MUX_MODE的值来决定。
MUX_MODE:BGA的UART3_TXD这个PAD可以根据MUX_MODE的值配置为不同的模式,比如,如果MUX_MODE=000,表示此PAD连接到CPU内部UART1的DSR;如果MUX_MODE=011,表示此PAD连接到GPU内部GPIO1_23。
; Assert SYS_ON_OFF_CTL (GPIO1_23) to keep poweractive after user releases
; PWR button. This is done as early as possible to prevent the board
; from powering down during boot.
ldr r1,=(CSP_BASE_REG_PA_GPIO1)
ldr r0, [r1,#0x4]
orr r0, r0,#(0x1 << 23)
str r0, [r1,#0x4] ; GDIR[23] = 1 =>GPIO1_23 is an output
先把GDIR寄存器的值取出来保存在r0寄存器中,然后设置GDIR[23]为1,也就是设置为输出功能,设置之后把修改后的值重新写入到GDIR寄存器中。
ldr r0, [r1,#0x0]
orr r0, r0,#(0x1 << 23) ; DR[23] = 1 =>GPIO1_23 is asserted
str r0, [r1,#0x0]
把DR[23]设置为1,表示GPIO1_23输出为高电平,目的在上面的注释说的很清楚,就是在用户松开PWR按键后尽快为整个系统供电。
GDIR:Data Direction Register,数据分享寄存器,设置对应的位为0表示对应的pin为输入,为1表示为输出。
DR:Data Register,数据寄存器,如果IOMUX为GPIO模式且为输出,写到此寄存器中的数据将驱动GPIO的pin;如果为输入,读取DR寄存器返回的是相应PAD的值(PSR data),也就是pin引脚的电平状态,而不是DR寄存器的值。
图2
1.2 取出ROM code保存在IRAM中的启动卡的地址模式并保存在r12寄存器中
; by default,assume this is TO2
; is this card to be addressed in sectormode or byte mode? Save flag in r12. DO NOT MODIFY r12 AGAIN!
ldr r1, =IRAM_CARD_ADDR_MODE_TO2
ldr r12,[r1]
IMX51有TO1、TO11和TO2几个版本,对于这几个版本,ROM code把启动卡的地址模式(sector mode或是byte mode)保存在IRAM地址不用的地址处,对于TO2版本来说就保存在IRAM_CARD_ADDR_MODE_TO2(0x1FFE1AB8)的地方。现在把地址模式的值取出来保存在r12寄存器中。
ldr r0, =ROM_ID
ldr r0, [r0]
; is this TO1.1?
cmp r0, #0x2 ; 0x2 is the value forTO1.1 (TO2 has 0x10 as the value)
ROM_ID =0x00000048,ROM ID保存在0x00000048地址单元处,取出其保存的值来和TO11版本比较,如果箱单,表示是TO11版本,然后继续执行紧挨着的下面代码。
; is this card to be addressed in sectormode or byte mode? Save flag in r12. DO NOT MODIFY r12 AGAIN!
ldreq r1, =IRAM_CARD_ADDR_MODE_TO11
ldreq r12,[r1]
把地址模式的值保存到r12寄存器中。
; is this TO1?
cmp r0, #0x1 ; 0x1 is the value for TO1.0
如果不是TO11版本,接着判断是否为TO1版本,如果是则
; is this card to be addressed in sectormode or byte mode? Save flag in r12. DO NOT MODIFY r12 AGAIN!
ldreq r1, =IRAM_CARD_ADDR_MODE_TO1
ldreq r12,[r1]
把地址模式的值保存到r12寄存器中。
1.3 把ARM处理器设置为管理模式,并且禁用普通IRQ和快速IRQ
;--------------------------------------------------------------------------
; MS RECOMMENDATION:
; Put the processor in supervisor mode
; Disable the interrupt request (IRQ) and fast interruptrequest (FIQ)
; inputs
;--------------------------------------------------------------------------
mrs r0,cpsr ; r0 =CPSR
mov r0,#ARM_CPSR_MODE_SVC ; entersupervisor mode
读取当前程序状态寄存器cpsr的值保存到r0寄存器中,接着设置处理器为管理模式(supervisor,svc)。
orr r0, r0,#ARM_CPSR_IRQDISABLE ; disablenormal IRQ
orr r0, r0,#ARM_CPSR_FIQDISABLE ; disablefast IRQ
orr r0, r0,#ARM_CPSR_PRECISE ; enableprecise data aborts
msr cpsr_xc,r0 ; update CPSR controlbits
禁用普通IRQ、快速IRQ、禁止不确定数据异常(ARM_CPSR_PRECISE = 1<<8)
mrc p15, 1,r0, c9, c0, 2 ; Read L2 auxcontrol reg
orr r0, r0,#(1 << 25) ; Disablewrite combining (HW workaround)
mcr p15, 1,r0, c9, c0, 2 ; Update L2 auxcontrol reg
这部分目前只知道是从协处理器p15中读取其寄存器的值保存到ARM处理器的r0寄存器中,然后禁用write combining之后重新写入P15的寄存器中。
1.4 禁用内存管理单元MMU、指令cache和数据cache。
;--------------------------------------------------------------------------
; MS RECOMMENDATION:
; Disable memory management unit (MMU) andboth the instruction and data
; caches
;--------------------------------------------------------------------------
mrc p15, 0, r0, c1, c0, 0 ; r0 = system control reg
bic r0, r0, #ARM_CTRL_ICACHE ; disable ICache
bic r0, r0, #ARM_CTRL_DCACHE ; disable DCache
bic r0, r0, #ARM_CTRL_MMU ; disable MMU
bic r0, r0, #ARM_CTRL_VECTORS ; set vector base to 0x00000000
orr r0, r0, #ARM_CTRL_FLOW ; program flow prediction enabled
mcr p15, 0,r0, c1, c0, 0 ; updatesystem control reg
1.5 配置ARM协处理器访问控制寄存器
; Configure ARM coprocessor access control register
;
ldr r0,=ARM_CACR_CONFIG ; r0 =CACR configuration
mcr p15, 0,r0, c1, c0, 2 ; update CACR
DCD 0xF57FF06F ; ISB
1.6 配置AHB、IP BUS接口(AIPS)寄存器
; ConfigureAHB<->IP-bus interface (AIPS) registers
;
ldr r1, =CSP_BASE_REG_PA_AIPS1
ldr r2, =CSP_BASE_REG_PA_AIPS2
; Except for AIPS regs, configure allperipherals as follows:
; unbuffered writes (MBW=0)
; disable supervisor protect (SP=0)
; disable write protect (WP=0)
; disable trusted protect (TP=0)
mov r0, #0
str r0, [r1, #AIPSREG_OPACR0_OFFSET]
str r0, [r1, #AIPSREG_OPACR1_OFFSET]
str r0, [r1, #AIPSREG_OPACR2_OFFSET]
str r0, [r1, #AIPSREG_OPACR3_OFFSET]
str r0, [r1, #AIPSREG_OPACR4_OFFSET]
str r0, [r2, #AIPSREG_OPACR0_OFFSET]
str r0, [r2, #AIPSREG_OPACR1_OFFSET]
str r0, [r2, #AIPSREG_OPACR2_OFFSET]
str r0, [r2, #AIPSREG_OPACR3_OFFSET]
str r0, [r2, #AIPSREG_OPACR4_OFFSET]
; Set all MPRx to be non-bufferable,trusted for R/W,
; not forced to user-mode.
ldr r0, =(0x77777777)
str r0, [r1, #AIPSREG_MPR0_OFFSET]
str r0, [r1, #AIPSREG_MPR1_OFFSET]
str r0, [r2, #AIPSREG_MPR0_OFFSET]
str r0, [r2,#AIPSREG_MPR1_OFFSET]
1.7 内存初始化
把DDR2的相关引脚配置为DDR2输入类型,如下图:
图3
通过把IOMUXC_SW_PAD_CTL_GRP_INMODE1[9]设置为1,把DRAM_D[31:0]等DDR2相关的引脚社会自为DDR2输入类型,IMX51功能真的很强大,就控制此寄存器的这位就能够控制这些引脚的输入类型。
; IOMUXC_SW_PAD_CTL_PAD_EIM_SDODT1 Pull-D, HIGH DS
ldr r0,=0x000020c5
ldr r1,=0x73fa850c
str r0, [r1]
; IOMUXC_SW_PAD_CTL_PAD_EIM_SDODT0 Pull-D, HIGH DS
ldr r0,=0x000020c5
ldr r1,=0x73fa8510
str r0, [r1]
EIM_SDODT0和EIM_SDODT1用于连接DDR2的ODT(On Die Termination)引脚,评估板用512MB(4*128),如果只用到256MB(2*128)可以根据原理图只控制其一。
; IOMUXC_SW_PAD_CTL_GRP_DDR_A0 MEDIUM DS
ldr r0,=0x00000002
ldr r1,=0x73fa883c
str r0, [r1]
; IOMUXC_SW_PAD_CTL_GRP_DDR_A1 MEDIUM DS
ldr r0,=0x00000002
ldr r1,=0x73fa8848
str r0, [r1]
; IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK MAX DS
ldr r0,=0x000000e7
ldr r1,=0x73fa84b8
str r0, [r1]
设置DRAM_A[14:0]和EIM_SDBA0[3:0]为中间的驱动强度(Medium Drive Strength),以及SDCLK的属性设置。
; IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 Pull/Keep Disable
ldr r0, =0x00000045
ldr r1,=0x73fa84bc
str r0, [r1]
; IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 Pull/Keep Disable
ldr r0,=0x00000045
ldr r1,=0x73fa84c0
str r0, [r1]
; IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 Pull/Keep Disable
ldr r0,=0x00000045
ldr r1,=0x73fa84c4
str r0, [r1]
; IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 Pull/Keep Disable
ldr r0,=0x00000045
ldr r1,=0x73fa84c8
str r0, [r1]
设置DRAM_SDQS[3:0]的控制属性,详见数据手册中IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0到3寄存器的说明
……………….
其他DDR2控制脚的控制,包括驱动强度;还有就是一些时序参数的设置,这部分就不一一列举出来了。
1.8 从SD/MMC卡中读取eboot,然后跳到到eboot的入口开始执行。