📄 rominit.s
字号:
sub r6, r6, r7 /* subtract romInit base address */
add r6, r6, r8 /* add in ROM_TEXT_ADRS address */
/*
* OP = 00 write, UM = 0 UPMA, MB = 000 OP为run命令时定义正确的有效CS引脚,
* MCLF = 0000 OP为run命令时定义重复的次数, MAD = 00000 对我们无用,
*/
lis r9, HIADJ (MCR_OP_WRITE | MCR_UM_UPMA | MCR_MB_CS0)
addi r9, r9, LO(MCR_OP_WRITE | MCR_UM_UPMA | MCR_MB_CS0)
/* MCR,MDR see 866um.pdf 15.4.5 15.4.6 */
UpmaWriteLoop:
/* write the UPM table in the UPM */
lwz r10, 0(r6) /* get data from table */
stw r10, MDR(0)(r4) /* store the data to MD register */
stw r9, MCR(0)(r4) /* issue command to MCR register */
addi r6, r6, 4 /* next entry in the table */
addi r9, r9, 1 /* next MAD address */
addi r5,r5,-1
cmpwi r5,0
bne UpmaWriteLoop
/* 2、program MPTPR see 866um.pdf 15.4.8 */
li r6, MPTPR_PTP_DIV64
sth r6, MPTPR(0)(r4)
/* 3、program MAMR/MBMR see 866um.pdf 15.4.4 */
/* get PTA, REFRESH_VALUE = 50M/64K = 781, PTA = REFRESH_VALUE/64 = 12 */
li r6, MPTPR_PTP_DIV64
lis r11, HIADJ ((REFRESH_VALUE / 64) << MAMR_PTA_SHIFT)
addi r11, r11, LO ((REFRESH_VALUE / 64) << MAMR_PTA_SHIFT)
/* initialize MxMR but don't enable refresh until after SDRAM initialization. */
lis r6, HIADJ( MAMR_PTAE | MAMR_AMA_TYPE_1 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A10 | \
MAMR_RLFA_1X | MAMR_WLFA_1X | MAMR_TLFA_4X)
addi r6, r6, LO( MAMR_PTAE | MAMR_AMA_TYPE_1 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A10 | \
MAMR_RLFA_1X | MAMR_WLFA_1X | MAMR_TLFA_4X)
or r6, r6, r11
stw r6, MAMR(0)(r4)
/* 4、setup BRx ORx. */
/* Map the bank 1 to the Board Status and Control Registers */
/* cs2配置为sdram,从cs1开始or的配置要先于br */
/* 配置cs2
* AM = 0xFE00 = 给出32M地址空间给cs1内存,
* ATM = 000。
* CSNT/SAM (Start address multiplex) = 1
* G5LA,G5LS = 00
* BI/ (Burst Inhibit) = 0 = This bank supports burst accesses.
*/
lis r5, HIADJ( (0xFE000000 & OR_AM_MSK )|OR_CSNT_SAM)
addi r5, r5, LO( (0xFE000000 & OR_AM_MSK )|OR_CSNT_SAM)
stw r5, OR2(0)(r4)
/*
* BA (Base Address) = 0x0000 cs2内存的基址,
* AT (Address Type) = 000b = no restrictions to bank
* PS (Port Size) = 00b = 32 bit port size
* PARE (Parity Enable) = 0 = parity checking disabled
* WP (Write Protect) = 0 = both read and write accesses are allowed
* MS (Machine Select) = 10 = user-programable machine A selected
* V (Valid Bit) = 1 = Valid bit set
*/
lis r5, HIADJ( (LOCAL_MEM_LOCAL_ADRS & BR_BA_MSK) | BR_MS_UPMA | BR_PS_32| BR_V )
addi r5, r5, LO( (LOCAL_MEM_LOCAL_ADRS & BR_BA_MSK) | BR_MS_UPMA | BR_PS_32 | BR_V )
stw r5, BR2(0)(r4)
/*
* Issue precharge command (PRCG) and wait the precharge time (t-rp).
* Run precharge pattern from UPMA location 5.
*/
/* CS2 */
lis r5, HIADJ(MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS2 | \
MCR_MCLF_1X | 0x5)
addi r5, r5, LO(MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS2 | \
MCR_MCLF_1X | 0x5)
stw r5, MCR(0)(r4)
/* run refresh pattern 8 times */
/* CS2 */
lis r5, HIADJ(MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS2 | \
MCR_MCLF_8X | 0x30)
addi r5, r5, LO(MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS2 | \
MCR_MCLF_8X | 0x30)
stw r5, MCR(0)(r4)
/*
* Configure the 32 bit address to be output on the address bus
* if AMX = 0xb11.
* See section 15.6.4.1 "Arm Words". The following values must
* be placed on the defined SDRAM address pins:
* A[9] = 0 burst write mode
* A[6:4] = 010 cas latency of two
* A[3] = 0 sequential mode
* A[2:0] = 010 burst length 4
*
* The address must be shifted left by 2 bits for 32 bit wide SDRAM...
* (0b0100010 << 2) = 0x88
*/
lis r5, HIADJ(LOCAL_MEM_LOCAL_ADRS | 0x88)
addi r5, r5, LO(LOCAL_MEM_LOCAL_ADRS | 0x88)
stw r5, MAR(0)(r4)
/*
* issue a mode register set (MRS) to initialize the SDRAM mode
* register. This programs the burst length, CAS latency and
* write mode. Run MRS pattern from UPMA location 6.
*/
/* CS2 */
lis r5, HIADJ(MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS2 | \
MCR_MCLF_1X | 0x6)
addi r5, r5, LO(MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS2 | \
MCR_MCLF_1X | 0x6)
stw r5, MCR(0)(r4)
/* cs1配置为flash,从cs1开始or的配置要先于br */
lis r5, HIADJ( (0xFFE00000 & OR_AM_MSK) | OR_CSNT_SAM | OR_BI | OR_SCY_6_CLK | OR_TRLX )
addi r5, r5, LO( (0xFFE00000 & OR_AM_MSK) | OR_CSNT_SAM | OR_BI | OR_SCY_6_CLK | OR_TRLX )
stw r5, OR1(0)(r4)
lis r5, HIADJ( (FLASH_BASE_ADDR & BR_BA_MSK) | BR_PS_16 | BR_V )
addi r5, r5, LO( (FLASH_BASE_ADDR & BR_BA_MSK) | BR_PS_16 | BR_V )
stw r5, BR1(0)(r4)
bl LedDBTest
mfspr r4, IMMR /* read it back, to be sure */
rlwinm r4, r4, 0, 0, 15 /* only high 16 bits count */
#if 1
/*初始化运行灯的IO口*/
lis r4, HIADJ( INTERNAL_MEM_MAP_ADDR )
addi r4, r4, LO( INTERNAL_MEM_MAP_ADDR )
mtspr IMMR, r4 /* initialize the IMMR register */
xor r6,r6,r6 /* 将PC的所有端口全部设为输出 */
lis r4, HIADJ( INTERNAL_MEM_MAP_ADDR )
addi r4, r4, LO( INTERNAL_MEM_MAP_ADDR )
sth r6, PCPAR(0)(r4)
sth r6, PCSO(0)(r4)
li r5, 0xffff
sth r5, PCDIR(0)(r4)
/* 如果上电缺省为灭灯的话,把灯打开 */
sth r6, PCDAT(0)(r4) /*turn on*/
/* 如果上电缺省为灯亮的话,把灯灭掉 */
/*stw r5, PBDAT(0)(r4)*/ /*turn off*/
/*测试部分内存,这部分内存在内存程序中,无法测试,为了提高效率,使用汇编语言,有错误点灯*/
/*先对0地址的测试一下,后面的测试有一点不方便*/
xor r7, r7, r7
lis r8, HIADJ( 0xA5A5A5A5 )
addi r8, r8, LO( 0xA5A5A5A5 )
stw r8,0(r7)
lwz r6,0(r7)
cmpw r6,r8
bne DEAD_LOOP
lis r7, HIADJ( romInit - 0x10000 )
addi r7, r7, LO( romInit - 0x10000 )
lis r8, HIADJ( romInit + 0x80000 )
addi r8, r8, LO( romInit + 0x80000 )
RAM_WHITELOOP:
stw r7,0(r7)
addi r7,r7,4
cmpw r8,r7
bne RAM_WHITELOOP
sth r5, PCDAT(0)(r4) /*turn off*/
lis r6, HIADJ( romInit - 0x10000 )
addi r6, r6, LO( romInit - 0x10000 )
lis r7, HIADJ( romInit - 0x10000 )
addi r7, r7, LO( romInit - 0x10000 )
lis r8, HIADJ( romInit + 0x80000 )
addi r8, r8, LO( romInit + 0x80000 )
RAM_READLOOP:
lwz r6,0(r6)
cmpw r6,r7
bne DEAD_LOOP
addi r7,r7,4
addi r6,r6,4
cmpw r8,r7
bne RAM_READLOOP
xor r6,r6,r6 /* 将PB的所有端口全部设为输出 */
sth r6, PCDAT(0)(r4) /*turn on*/
#endif
stackinit:
/* initialize the stack pointer */
lis sp, HIADJ(STACK_ADRS)
addi sp, sp, LO(STACK_ADRS)
/* initialize r2 and r13 according to EABI standard */
/* EABI : Embedded Application Binary Interface */
/* go to C entry point */
addi sp, sp, -FRAMEBASESZ /* get frame stack */
/*
* calculate C entry point: routine - entry point + ROM base
* routine = romStart
* entry point = romInit = R7
* ROM base = ROM_TEXT_ADRS = R8
* C entry point: romStart - R7 + R8
*/
lis r7, HIADJ( romInit )
addi r7, r7, LO( romInit )
lis r8, HIADJ( ROM_TEXT_ADRS )
addi r8, r8, LO( ROM_TEXT_ADRS )
lis r6, HIADJ(romStart)
addi r6, r6, LO(romStart) /* load R6 with C entry point */
sub r6, r6, r7 /* routine - entry point */
add r6, r6, r8 /* + ROM base */
mtlr r6 /* move C entry point to LR */
blr /* jump to the C entry point */
/*出错死循环*/
DEAD_LOOP:
xor r6,r6,r6 /* 将PB的所有端口全部设为输出 */
sth r6, PCDAT(0)(r4) /*turn on*/
bl DEAD_LOOP
LedDBTest:
lis r4, HIADJ( INTERNAL_MEM_MAP_ADDR )
addi r4, r4, LO( INTERNAL_MEM_MAP_ADDR )
mtspr IMMR, r4 /* initialize the IMMR register */
xor r6,r6,r6 /* 将PC的所有端口全部设为输出 */
sth r6, PCPAR(0)(r4)
sth r6, PCSO(0)(r4)
li r5, 0xFFFFFFFF
sth r5, PCDIR(0)(r4)
sth r6, PCDAT(0)(r4) /*turn on*/
stw r5, PCDAT(0)(r4) /*turn off*/
bclr 20,0 /* return to caller */
LedCtrl:
/* r3 为第一个参数:点灯的种类:LED_RUN,LED_ALARM
* r4 为第二个参数:开关灯:LED_ON,LED_OFF
* 汇编中并不判断入口参数的合法性,在C中做一层封装,来判断外面进来的参数
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -