项目中使用的是EMIF CS1上面的一个Flash,其中地址A20~A23使用GPIO方式控制,不过因为这段程序只有38KB,所以这几个地址均为0,A24的话是因为板卡上面有两个Flash,通过CPLD进行片选使能,我的BOOT程序放到了Flash0上面,也就是A24应该为0。这块Flash为16位宽。因此我在boot_loop的时候,都是按16位宽从Flash中读数,然后又以16位宽的方式写到了RAM中去。
BOOT部分占用IRAM前1024字节,因此在Flash和IRAM中,我都是从各自0x400的地址搬移数据,然后跳转到c_int地址去运行。
因为只用到了CE1,以后可能会使用下CE0上面的CPLD在引导时做些状态标记,所以EMIF初始化部分只进行了CE0和CE1的初始化工作。代码实现如下:
;
; ======== boot_c671x.s62 ========
;
.title "Flash bootup utility"
.option D,T
.length 130
.width 140
; global EMIF symbols defined for the c671x family
.include boot_c671x.h62
.sect ".boot_load"
.global _boot
.ref _c_int00
;Flash Boot配置信息相关定义
FLASH_BOOT_COPY_STARTADDR .equ 0x90000400
FLASH_BOOT_BINSIZE .equ 0x000FFC00
RAM_BOOT_COPY_STARTADDR .equ 0x00000400
CPLD_CFG_LED_ADDR .equ 0x80180020
CPLD_CFG_LED_LIGTHON .equ 0x00000000
CPLD_CFG_LED_LIGTHOFF .equ 0x000000ff
_boot:
;************************************************************************
;* CONFIGURE EMIF
;************************************************************************
;****************************************************************
; *EMIF_GCTL = EMIF_GCTL_V;
;****************************************************************
mvkl EMIF_GCTL,A4 ;将EMIF全局控制寄存器基地址低16位写入A4寄存器低16位,
;因mvkl带符号位扩展,因此该语句必须先于mvkh
|| mvkl EMIF_GCTL_V,B4 ;将EMIF全局控制寄存器配置参数低16位写入B4寄存器低16位
mvkh EMIF_GCTL,A4 ;将EMIF全局控制寄存器基地址高16位写入A4寄存器高16位
|| mvkh EMIF_GCTL_V,B4 ;将EMIF全局控制寄存器配置参数高16位写入B4寄存器高16位
;两条指令并行执行
stw B4,*A4 ;将B4值写入A4指向地址存储空间
;****************************************************************
; *EMIF_CE0 = EMIF_CE0_V
;****************************************************************
mvkl EMIF_CE0,A4 ;将EMIF CE0寄存器地址低16位写入A4寄存器低16位
|| mvkl EMIF_CE0_V,B4 ;将EMIF CE0寄存器配置参数低16位写入B4寄存器低16位
;两条指令并行执行
mvkh EMIF_CE0,A4 ;将EMIF CE0寄存器地址高16位写入A4寄存器高16位
|| mvkh EMIF_CE0_V,B4 ;将EMIF CE0寄存器配置参数高16位写入A4寄存器高16位
;两条指令并行执行
stw B4,*A4 ;将B4值写入A4指向地址存储空间
;****************************************************************
; *EMIF_CE1 = EMIF_CE1_V (setup for 16-bit async flash)
;****************************************************************
mvkl EMIF_CE1,A4 ;参上
|| mvkl EMIF_CE1_V,B4
mvkh EMIF_CE1,A4
|| mvkh EMIF_CE1_V,B4
stw B4,*A4
;**********************************************************************
; 通过配置GPIO引脚完成:Flash A20~A23为低电平, A24 Flash片选为低电平
;**********************************************************************
; GPIO Enable Register (GPEN) config
mvkl GPEN,A4 ;
|| mvkl GPEN_V,B4 ;
mvkh GPEN,A4 ;
|| mvkh GPEN_V,B4 ;
stw B4,*A4
; GPIO Direction Register (GPDIR)
mvkl GPDIR,A4 ;
|| mvkl GPDIR_V,B4 ;
mvkh GPDIR,A4 ;
|| mvkh GPDIR_V,B4 ;
stw B4,*A4
; GPIO Direction Register (GPDIR)
mvkl GPVAL,A4 ;
|| mvkl GPVAL_V,B4 ;
mvkh GPVAL,A4 ;
|| mvkh GPVAL_V,B4 ;
stw B4,*A4
;**********************************************************************
;Flash程序读取、写入地址、入口地址赋值...
;**********************************************************************
mvkl FLASH_BOOT_COPY_STARTADDR,A4 ;BOOT文件Flash基地址
|| mvkl RAM_BOOT_COPY_STARTADDR,B5 ;RAM拷贝地址
mvkh FLASH_BOOT_COPY_STARTADDR,A4
|| mvkh RAM_BOOT_COPY_STARTADDR,B5
mvkl FLASH_BOOT_BINSIZE,B0 ;BOOT程序拷贝长度
mvkh FLASH_BOOT_BINSIZE,B0
mvkl .S2 _c_int00,B7 ;BOOT程序入口地址
mvkh .S2 _c_int00,B7
boot_loop: ;BOOT程序搬移操作
ldh *A4++,A7 ;从A4地址所在区域读取1字节数据到 A7寄存器
sub B0,2,B0 ;decrement counter
nop 3
sth A7,*B5++ ;将A7寄存值保存到地址中
nop 4
[B0] b boot_loop ; setup branch if not done
[!B0] b .S2 B7 ;执行结束,转至入口地址开始执行
nop 5