diff options
author | Robin Gong <B38343@freescale.com> | 2011-12-07 09:50:09 +0800 |
---|---|---|
committer | Robin Gong <B38343@freescale.com> | 2011-12-07 10:09:30 +0800 |
commit | 9af08a287afce5949ceb56774c1b405fb523d735 (patch) | |
tree | 45d46a8cfb3b30b0dd6e9d93f3c4471f1dbb7719 /board | |
parent | c9384fca46bf0fcf8f14f76e218e010f2d17263c (diff) | |
download | u-boot-imx-9af08a287afce5949ceb56774c1b405fb523d735.zip u-boot-imx-9af08a287afce5949ceb56774c1b405fb523d735.tar.gz u-boot-imx-9af08a287afce5949ceb56774c1b405fb523d735.tar.bz2 |
ENGR00169654 mx53_pcba: enable DDR auto-calibration
Enabled the functioon of DDR auto-calibration in flash_header.S
of HW PCBA.
Signed-off-by: Robin Gong <B38343@freescale.com>
Diffstat (limited to 'board')
-rw-r--r-- | board/freescale/mx53_pcba/flash_header.S | 798 |
1 files changed, 620 insertions, 178 deletions
diff --git a/board/freescale/mx53_pcba/flash_header.S b/board/freescale/mx53_pcba/flash_header.S index da12348..38ece08 100644 --- a/board/freescale/mx53_pcba/flash_header.S +++ b/board/freescale/mx53_pcba/flash_header.S @@ -20,208 +20,650 @@ #include <config.h> #include <asm/arch/mx53.h> -#define REG_LD_AND_STR_INIT(base) \ - ldr r0, =base; - -#define REG_LD_AND_STR_OP(i, offset, val) \ - ldr r1, =val; \ - ldr r2, =offset; \ - str r1, [r0, r2]; - -#define REG_LD_AND_STR_END(base) - - #ifdef CONFIG_FLASH_HEADER #ifndef CONFIG_FLASH_HEADER_OFFSET # error "Must define the offset of flash header" #endif + .section ".text.flasheader", "x" b _start .org CONFIG_FLASH_HEADER_OFFSET -ivt_header: .long 0x402000D1/* Tag=0xD1, Len=0x0020, Ver=0x40 */ -app_code_jump_v: .long (0xF8006000 + (plugin_start - TEXT_BASE)) -reserv1: .long 0x0 -dcd_ptr: .long 0x0 -boot_data_ptr: .long (0xF8006000 + (boot_data - TEXT_BASE)) -self_ptr: .long (0xF8006000 + (ivt_header - TEXT_BASE)) -app_code_csf: .long 0x0 -reserv2: .long 0x0 -boot_data: .long 0xF8006000 -image_len: .long (3 * 1024) -plugin: .long 0x1 +ivt_header: .long 0x402000D1 /* Tag=0xD1, Len=0x0020, Ver=0x40 */ +app_code_jump_v: .long (0xF8006000 + (plugin_start - TEXT_BASE)) +reserv1: .long 0x0 +dcd_ptr: .long 0x0 +boot_data_ptr: .long (0xF8006000 + (boot_data - TEXT_BASE)) +self_ptr: .long (0xF8006000 + (ivt_header - TEXT_BASE)) +app_code_csf: .long 0x0 +reserv2: .long 0x0 +boot_data: .long 0xF8006000 +image_len: .long 4*1024 +plugin: .long 0x1 /* Second IVT to give entry point into the bootloader copied to DDR */ -ivt2_header: .long 0x402000D1/*Tag=0xD1, Len=0x0020, Ver=0x40 */ -app2_code_jump_v: .long _start /* Entry point for the bootloader */ -reserv3: .long 0x0 -dcd2_ptr: .long 0x0 -boot_data2_ptr: .long boot_data2 -self_ptr2: .long ivt2_header -app_code_csf2: .long 0x0 -reserv4: .long 0x0 -boot_data2: .long TEXT_BASE -image_len2: .long _end_of_copy - TEXT_BASE + CONFIG_FLASH_HEADER_OFFSET -plugin2: .long 0x0 +ivt2_header: .long 0x402000D1 /*Tag=0xD1, Len=0x0020, Ver=0x40 */ +app2_code_jump_v: .long _start /* Entry point for the bootloader */ +reserv3: .long 0x0 +dcd2_ptr: .long 0x0 +boot_data2_ptr: .long boot_data2 +self_ptr2: .long ivt2_header +app_code_csf2: .long 0x0 +reserv4: .long 0x0 +boot_data2: .long TEXT_BASE +image_len2: .long _end - TEXT_BASE +plugin2: .long 0x0 + /* Here starts the plugin code */ plugin_start: - /* Save the return address and the function arguments */ - push {r0-r6, lr} - /* We should distinguish USB recovery mode(SDP mode) and internal boot mode. - If ROM runs in SDP mode, then it needn't load boot code from storage media. - If ROM runs in SDP mode, then r0 must be 0x00 - If ROM runs in internal boot mode, then r0 should be larger than IRAM base address. */ - mov r7, r0 - - /* IOMUX */ - REG_LD_AND_STR_INIT(IOMUXC_BASE_ADDR) - REG_LD_AND_STR_OP(1, 0x6f4, 0x00000000) - REG_LD_AND_STR_OP(2, 0x714, 0x00000000) - REG_LD_AND_STR_OP(3, 0x6fc, 0x00000000) - REG_LD_AND_STR_OP(4, 0x724, 0x04000000) - REG_LD_AND_STR_OP(5, 0x72c, 0x00300000) - REG_LD_AND_STR_OP(6, 0x554, 0x00300000) - REG_LD_AND_STR_OP(7, 0x558, 0x00300040) - REG_LD_AND_STR_OP(8, 0x728, 0x00300000) - REG_LD_AND_STR_OP(9, 0x560, 0x00300000) - REG_LD_AND_STR_OP(10, 0x568, 0x00300040) - REG_LD_AND_STR_OP(11, 0x71c, 0x00300000) - REG_LD_AND_STR_OP(12, 0x594, 0x00300000) - REG_LD_AND_STR_OP(13, 0x590, 0x00300040) - REG_LD_AND_STR_OP(14, 0x718, 0x00300000) - REG_LD_AND_STR_OP(15, 0x584, 0x00300000) - REG_LD_AND_STR_OP(16, 0x57c, 0x00300040) - REG_LD_AND_STR_OP(17, 0x578, 0x00300000) - REG_LD_AND_STR_OP(18, 0x570, 0x00300000) - REG_LD_AND_STR_OP(19, 0x574, 0x00300000) - REG_LD_AND_STR_OP(20, 0x588, 0x00300000) - REG_LD_AND_STR_OP(21, 0x6f0, 0x00300000) - REG_LD_AND_STR_OP(22, 0x720, 0x00300000) - REG_LD_AND_STR_OP(23, 0x564, 0x00300040) - REG_LD_AND_STR_OP(24, 0x580, 0x00300040) - REG_LD_AND_STR_END(IOMUXC_BASE_ADDR) - - /* ESDCTL */ - REG_LD_AND_STR_INIT(ESDCTL_BASE_ADDR) - REG_LD_AND_STR_OP(25, 0x098, 0x00000000) - REG_LD_AND_STR_OP(26, 0x07c, 0x01340135) - REG_LD_AND_STR_OP(27, 0x080, 0x01390139) - REG_LD_AND_STR_OP(28, 0x0f8, 0x00000800) - REG_LD_AND_STR_OP(29, 0x088, 0x34343531) - REG_LD_AND_STR_OP(30, 0x090, 0x54475246) - REG_LD_AND_STR_OP(31, 0x018, 0x00011740) - REG_LD_AND_STR_OP(32, 0x000, 0xc3190000) - REG_LD_AND_STR_OP(33, 0x00c, 0x9f515333) - REG_LD_AND_STR_OP(34, 0x010, 0xb68e8a63) - REG_LD_AND_STR_OP(35, 0x014, 0x01ff00db) - REG_LD_AND_STR_OP(36, 0x02c, 0x000026d2) - REG_LD_AND_STR_OP(37, 0x030, 0x009f0e21) - REG_LD_AND_STR_OP(38, 0x008, 0x12373030) - REG_LD_AND_STR_OP(39, 0x004, 0x4402002d) - REG_LD_AND_STR_OP(40, 0x01c, 0x00008032) - REG_LD_AND_STR_OP(41, 0x01c, 0x00008033) - REG_LD_AND_STR_OP(42, 0x01c, 0x00008031) - REG_LD_AND_STR_OP(43, 0x01c, 0x092080b0) - REG_LD_AND_STR_OP(44, 0x01c, 0x04008040) - REG_LD_AND_STR_OP(45, 0x01c, 0x0000803a) - REG_LD_AND_STR_OP(46, 0x01c, 0x0000803b) - REG_LD_AND_STR_OP(47, 0x01c, 0x00028039) - REG_LD_AND_STR_OP(48, 0x01c, 0x09208138) - REG_LD_AND_STR_OP(49, 0x01c, 0x04008048) - REG_LD_AND_STR_OP(50, 0x020, 0x00001800) - REG_LD_AND_STR_OP(51, 0x040, 0x04b80003) - REG_LD_AND_STR_OP(52, 0x058, 0x00022227) - REG_LD_AND_STR_OP(53, 0x01C, 0x00000000) - REG_LD_AND_STR_OP(54, 0x004, 0x00194005) - REG_LD_AND_STR_END(ESDCTL_BASE_ADDR) + /* Save the return address and the function arguments */ + push {r0-r6, lr} + /* We should distinguish USB recovery mode(SDP mode) and internal boot mode. + If ROM runs in SDP mode, then it needn't load boot code from storage media. + If ROM runs in SDP mode, then r0 must be 0x00 + If ROM runs in internal boot mode, then r0 should be larger than IRAM base address. */ + mov r7, r0 -/* - * The following is to fill in those arguments for this ROM function - * pu_irom_hwcnfg_setup(void **start, size_t *bytes, const void *boot_data) - * - * This function is used to copy data from the storage media into DDR. - * - * start - Initial (possibly partial) image load address on entry. Final image - * load address on exit. - * bytes - Initial (possibly partial) image size on entry. Final image size on - * exit. - * boot_data - Initial @ref ivt Boot Data load address. - */ +/* DDR3 script for SMD and ARM2 CPU3 board */ + /* IOMUX Setup */ + ldr r0, =0x53fa8500 + mov r1, #0x00300000 + add r2, r1, #0x40 + + str r1, [r0, #0x54] + str r2, [r0, #0x58] + str r1, [r0, #0x60] + str r2, [r0, #0x64] + str r2, [r0, #0x68] + str r1, [r0, #0x70] + str r1, [r0, #0x74] + str r1, [r0, #0x78] + str r2, [r0, #0x7c] + str r2, [r0, #0x80] + str r1, [r0, #0x84] + str r1, [r0, #0x88] + str r2, [r0, #0x90] + str r1, [r0, #0x94] + + ldr r0, =0x53fa8600 + str r1, [r0, #0xf0] + mov r2, #0x00000000 + str r2, [r0, #0xf4] + str r2, [r0, #0xfc] + + ldr r0, =0x53fa8700 + str r2, [r0, #0x14] + str r1, [r0, #0x18] + str r1, [r0, #0x1c] + str r1, [r0, #0x20] + mov r2, #0x04000000 + str r2, [r0, #0x24] + str r1, [r0, #0x28] + str r1, [r0, #0x2c] + + /* Initialize DDR3 memory for calibration */ + ldr r0, =ESDCTL_BASE_ADDR + + ldr r1, =0x01340135 + str r1, [r0, #0x07c] + ldr r1, =0x01390139 + str r1, [r0, #0x080] + ldr r1, =0x35343534 + str r1, [r0, #0x088] + ldr r1, =0x4f485146 + str r1, [r0, #0x090] + + ldr r1, =0x00000800 + str r1, [r0, #0xf8] + + ldr r1, =0x00011740 + str r1, [r0, #0x018] + + ldr r1, =0xc3190000 + str r1, [r0, #0x00] + + ldr r1, =0x9f515333 + str r1, [r0, #0x0C] + + ldr r1, =0xb68e8a63 + str r1, [r0, #0x10] + + ldr r1, =0x01ff00db + str r1, [r0, #0x14] + + ldr r1, =0x000026d2 + str r1, [r0, #0x2C] + + ldr r1, =0x009f0e21 + str r1, [r0, #0x30] + + ldr r1, =0x12373030 + str r1, [r0, #0x08] + + ldr r1, =0x4402002d + str r1, [r0, #0x04] + + ldr r1, =0x00008032 + str r1, [r0, #0x1C] + + ldr r1, =0x00008033 + str r1, [r0, #0x1C] + + ldr r1, =0x00028031 + str r1, [r0, #0x1C] + + ldr r1, =0x092080b0 + str r1, [r0, #0x1C] + + ldr r1, =0x04008040 + str r1, [r0, #0x1C] + + ldr r1, =0x0000803a + str r1, [r0, #0x1C] + + ldr r1, =0x0000803b + str r1, [r0, #0x1C] + + ldr r1, =0x00028039 + str r1, [r0, #0x1C] + + ldr r1, =0x09208138 + str r1, [r0, #0x1C] + + ldr r1, =0x04008048 + str r1, [r0, #0x1C] + + ldr r1, =0x00001800 + str r1, [r0, #0x20] + +// ldr r1, =0x04b80003 + ldr r1, =0x04b90003 + str r1, [r0, #0x40] + + ldr r1, =0x00022227 + str r1, [r0, #0x58] + + ldr r1, =0x00000000 + str r1, [r0, #0x1C] + + ldr r6, =0x0 + +retry: + add r6, r6, #0x1 + + //delay + ldr r1, =0x0 +100: + nop + add r1, r1, #0x1 + cmp r1, #0x200 + bne 100b + + /* DQS calibration */ + ldr r3, =0x55aaaa55 + ldr r4, =0x55555555 + ldr r5, =0xAAAAAAAA + str r3, [r0, #0x0cc] + + ldr r1, =0x0 + ldr r2, =0x0 +110: + ldr r0, =CSD0_BASE_ADDR + add r0, r0, #0x10000000 + add r0, r0, r2 + str r4, [r0, #0x000] + str r5, [r0, #0x004] + str r5, [r0, #0x008] + str r4, [r0, #0x00c] + + add r2, r2, #0x10 + add r1, r1, #0x1 + cmp r1, #0x4 + bne 110b + + ldr r0, =ESDCTL_BASE_ADDR + ldr r1, [r0, #0x07c] + orr r1, r1, #(1 << 30) + str r1, [r0, #0x07c] + + ldr r1, [r0, #0x07c] + orr r1, r1, #(1 << 28) + str r1, [r0, #0x07c] + + // check for DQS calibration complete +120: + ldr r1, [r0, #0x07c] + mov r2, #0x00000000 + orr r2, r2, #(1 << 28) + and r2, r1, r2 + cmp r2, #0x0 + bne 120b + + // check for calibration error + mov r2, #0x00000000 + orr r2, r2, #(1 << 12) + and r2, r1, r2 + cmp r2, #0x0 + beq 130f + ldr r0, =WDOG1_BASE_ADDR + ldr r1, =0x0033 + strh r1, [r0, #0x00] + ldr r1, =0x0037 + strh r1, [r0, #0x00] + ldr r1, =0x5555 + strh r1, [r0, #0x02] + ldr r1, =0xaaaa + strh r1, [r0, #0x02] +// bne retry +130: + + /* Reset */ + ldr r1, [r0, #0x07c] + orr r1, r1, #(1 << 31) + str r1, [r0, #0x07c] + +140: + ldr r1, [r0, #0x07c] + mov r2, #0x00000000 + orr r2, r2, #(1 << 31) + and r1, r1, r2 + cmp r1, #0x0 + bne 140b + + ldr r2, =CSD0_BASE_ADDR + add r2, r2, #0x1100000 + ldr r3, =0xf0f0f0f0 + ldr r4, =0xc3c3c3c3 + str r3, [r2, #0x000] + str r4, [r2, #0x004] + ldr r3, [r2, #0x000] + ldr r4, [r2, #0x004] + + /* RD calibration */ + ldr r4, =0x55555555 + ldr r5, =0xAAAAAAAA + ldr r1, =0x0 + ldr r2, =0x0 + +150: + ldr r0, =CSD0_BASE_ADDR + add r0, r0, #0x10000000 + add r0, r0, r2 + str r4, [r0, #0x000] + str r5, [r0, #0x004] + str r5, [r0, #0x008] + str r4, [r0, #0x00c] + + add r2, r2, #0x10 + add r1, r1, #0x1 + cmp r1, #0x4 + bne 150b + + ldr r0, =ESDCTL_BASE_ADDR + ldr r1, =0x04000050 + str r1, [r0, #0x01c] + ldr r1, =0x00000030 + str r1, [r0, #0x0a0] + + // check for RD calibration complete +160: + ldr r1, [r0, #0x0a0] + and r2, r1, #0x10 + cmp r2, #0x0 + bne 160b + + // check for calibration error + and r2, r1, #0xf + cmp r2, #0x0 + beq 170f + ldr r0, =WDOG1_BASE_ADDR + ldr r1, =0x0033 + strh r1, [r0, #0x00] + ldr r1, =0x0037 + strh r1, [r0, #0x00] + ldr r1, =0x5555 + strh r1, [r0, #0x02] + ldr r1, =0xaaaa + strh r1, [r0, #0x02] +// bne retry +170: + + /* Reset */ + ldr r1, [r0, #0x07c] + orr r1, r1, #(1 << 31) + str r1, [r0, #0x07c] - adr r0, DDR_DEST_ADDR - adr r1, COPY_SIZE - adr r2, BOOT_DATA +180: + ldr r1, [r0, #0x07c] + mov r2, #0x00000000 + orr r2, r2, #(1 << 31) + and r1, r1, r2 + cmp r1, #0x0 + bne 180b + + ldr r2, =CSD0_BASE_ADDR + add r2, r2, #0x1000000 + ldr r3, =0x01234567 + ldr r4, =0x89abcdef + str r3, [r2, #0x000] + str r4, [r2, #0x004] + ldr r3, [r2, #0x000] + ldr r4, [r2, #0x004] + + //delay + ldr r1, =0x0 +181: + nop + add r1, r1, #0x1 + cmp r1, #0x200 + bne 181b + + /* WR calibration */ + ldr r4, =0x55555555 + ldr r5, =0xAAAAAAAA + ldr r1, =0x0 + ldr r2, =0x0 + +190: + ldr r0, =CSD0_BASE_ADDR + add r0, r0, #0x10000000 + add r0, r0, r2 + str r4, [r0, #0x000] + str r5, [r0, #0x004] + str r5, [r0, #0x008] + str r4, [r0, #0x00c] + + add r2, r2, #0x10 + add r1, r1, #0x1 + cmp r1, #0x4 + bne 190b + + ldr r0, =ESDCTL_BASE_ADDR + ldr r1, =0x04000050 + str r1, [r0, #0x01c] + ldr r1, =0x00000030 + str r1, [r0, #0x0a4] + + // check for WR calibration complete +200: + ldr r1, [r0, #0x0a4] + and r2, r1, #0x10 + cmp r2, #0x0 + bne 200b + + // check for calibration error + and r2, r1, #0xf + cmp r2, #0x0 + beq 210f + ldr r0, =WDOG1_BASE_ADDR + ldr r1, =0x0033 + strh r1, [r0, #0x00] + ldr r1, =0x0037 + strh r1, [r0, #0x00] + ldr r1, =0x5555 + strh r1, [r0, #0x02] + ldr r1, =0xaaaa + strh r1, [r0, #0x02] +// bne retry +210: + + /* Reset */ + ldr r1, [r0, #0x07c] + orr r1, r1, #(1 << 31) + str r1, [r0, #0x07c] + +220: + ldr r1, [r0, #0x07c] + mov r2, #0x00000000 + orr r2, r2, #(1 << 31) + and r1, r1, r2 + cmp r1, #0x0 + bne 220b + + ldr r2, =CSD0_BASE_ADDR + add r2, r2, #0x1000000 + ldr r3, =0x01234567 + ldr r4, =0x89abcdef + str r3, [r2, #0x000] + str r4, [r2, #0x004] + ldr r3, [r2, #0x000] + ldr r4, [r2, #0x004] + + /* Reset */ + ldr r1, [r0, #0x07c] + orr r1, r1, #(1 << 31) + str r1, [r0, #0x07c] + +230: + ldr r1, [r0, #0x07c] + mov r2, #0x00000000 + orr r2, r2, #(1 << 31) + and r1, r1, r2 + cmp r1, #0x0 + bne 230b + +// cmp r6, #0xff // for test only +// bls retry // for test only + + ldr r5, [r0, #0x07c] + bic r5, r5, #(1 << 30) // clear bit 30 + ldr r6, [r0, #0x080] + ldr r3, [r0, #0x088] + ldr r4, [r0, #0x090] + + // Disable the ESDCTL + ldr r0, =ESDCTL_BASE_ADDR + ldr r1, =0x00000000 + str r1, [r0, #0x00] + + //delay + ldr r1, =0x0 +260: + nop + nop + nop + nop + add r1, r1, #0x1 + cmp r1, #0x100 + bne 260b +#if 0 + /* Reset the DDR controller */ + ldr r1, [r0, #0x01c] + orr r1, r1, #(1 << 15) + str r1, [r0, #0x01c] + +240: + ldr r1, [r0, #0x01c] + mov r2, #0x00000000 + orr r2, r2, #(1 << 14) + and r1, r1, r2 + cmp r1, #0x0 + beq 240b + + ldr r1, [r0, #0x018] + orr r1, r1, #(1 << 1) + str r1, [r0, #0x018] + +250: + ldr r1, [r0, #0x018] + mov r2, #0x00000000 + orr r2, r2, #(1 << 1) + and r1, r1, r2 + cmp r1, #0x0 + bne 250b + + ldr r1, =0x00000000 + str r1, [r0, #0x01c] +#endif + nop + nop + nop + nop + + /* Re-initialize DDR3 memory with calibrated data */ + ldr r0, =ESDCTL_BASE_ADDR + + str r5, [r0, #0x07c] + str r6, [r0, #0x080] + str r3, [r0, #0x088] + str r4, [r0, #0x090] + + ldr r1, =0x00011740 + str r1, [r0, #0x018] + + ldr r1, =0xc3190000 + str r1, [r0, #0x00] + + ldr r1, =0x9f515333 + str r1, [r0, #0x0C] + + ldr r1, =0xb68e8a63 + str r1, [r0, #0x10] + + ldr r1, =0x01ff00db + str r1, [r0, #0x14] + + ldr r1, =0x000026d2 + str r1, [r0, #0x2C] + + ldr r1, =0x009f0e21 + str r1, [r0, #0x30] + + ldr r1, =0x12373030 + str r1, [r0, #0x08] + + ldr r1, =0x4402002d + str r1, [r0, #0x04] + + ldr r1, =0x00008032 + str r1, [r0, #0x1C] + + ldr r1, =0x00008033 + str r1, [r0, #0x1C] + + ldr r1, =0x00028031 + str r1, [r0, #0x1C] + + ldr r1, =0x092080b0 + str r1, [r0, #0x1C] + + ldr r1, =0x04008040 + str r1, [r0, #0x1C] + + ldr r1, =0x0000803a + str r1, [r0, #0x1C] + + ldr r1, =0x0000803b + str r1, [r0, #0x1C] + + ldr r1, =0x00028039 + str r1, [r0, #0x1C] + + ldr r1, =0x09208138 + str r1, [r0, #0x1C] + + ldr r1, =0x04008048 + str r1, [r0, #0x1C] + + ldr r1, =0x00001800 + str r1, [r0, #0x20] + + ldr r1, =0x04b80003 + str r1, [r0, #0x40] + + ldr r1, =0x00022227 + str r1, [r0, #0x58] + + ldr r1, =0x00000000 + str r1, [r0, #0x1C] + +/* + * The following is to fill in those arguments for this ROM function + * pu_irom_hwcnfg_setup(void **start, size_t *bytes, const void *boot_data) + * + * This function is used to copy data from the storage media into DDR. + * + * start - Initial (possibly partial) image load address on entry. Final image + * load address on exit. + * bytes - Initial (possibly partial) image size on entry. Final image size on + * exit. + * boot_data - Initial @ref ivt Boot Data load address. + */ + adr r0, DDR_DEST_ADDR + adr r1, COPY_SIZE + adr r2, BOOT_DATA before_calling_rom___pu_irom_hwcnfg_setup: - /* We should distinguish USB recovery mode(SDP mode) and internal boot mode. - If ROM runs in SDP mode, then it needn't load boot code from storage media. - If ROM runs in SDP mode, then r0 must be 0x00 - If ROM runs in internal boot mode, then r0 should be larger than IRAM base address. */ - cmp r7, #0xF8000000 - bls return_sdp - /* Different ROM address for TO 1.0 & TO 2.0 */ - ldr r3, =ROM_SI_REV - ldr r4, [r3] - - cmp r4, #0x21 - /* TO2.1 */ - moveq r6, #0x1800 - addeq r6, r6, #0x4d - beq 2f - - cmp r4, #0x20 - /* TO2 */ - moveq r6, #0x1800 - addeq r6, r6, #0x4d - beq 2f - - /* TO1 */ - mov r6, #0x400000 - add r6, r6, #0x5000 - add r6, r6, #0xc7 - -2: - blx r6 /* This address might change in future ROM versions */ + /* We should distinguish USB recovery mode(SDP mode) and internal boot mode. + If ROM runs in SDP mode, then it needn't load boot code from storage media. + If ROM runs in SDP mode, then r0 must be 0x00 + If ROM runs in internal boot mode, then r0 should be larger than IRAM base address. */ + cmp r7, #0xF8000000 + bls return_sdp + + /* Different ROM address for TO 1.0 & TO 2.x */ + ldr r3, =ROM_SI_REV + ldr r4, [r3] + + cmp r4, #0x21 + /* TO2.1 */ + moveq r6, #0x1800 + addeq r6, r6, #0x4d + beq 2f + + cmp r4, #0x20 + /* TO2 */ + moveq r6, #0x1800 + addeq r6, r6, #0x4d + beq 2f + + /* TO1 */ + mov r6, #0x400000 + add r6, r6, #0x5000 + add r6, r6, #0xc7 + + +2: blx r6 /* This address might change in future ROM versions */ after_calling_rom___pu_irom_hwcnfg_setup: return_sdp: - cmp r7, #0xF8000000 - bhi quit_plugin - - /* Workaround run plug-ins in SDP mode without USB re-enumeration. - how it works: - ROM running in usb download mode. - Host manufacturing application sends SDP command to download plug-in image. - Host manufacturing application sends SDP command to jump to plug-in image and run it. - Plug-in starts execution and after its regular tasks plug-in will then call into ROM - call into pl_parse_and_handle() */ - ldr r3, =ROM_SI_REV - ldr r5, [r3] - cmp r5, #0x20 /* check silicon revision to determine the function entry address */ - - ldrlt r4, =0x00000edd /* function entry in TO1 ROM */ - ldrge r4, =0x0040487d /* function entry in TO2 ROM */ - blx r4 + cmp r7, #0xF8000000 + bhi quit_plugin + + /* Workaround run plug-ins in SDP mode without USB re-enumeration. + how it works: + ROM running in usb download mode. + Host manufacturing application sends SDP command to download plug-in image. + Host manufacturing application sends SDP command to jump to plug-in image and run it. + Plug-in starts execution and after its regular tasks plug-in will then call into ROM + call into pl_parse_and_handle() */ + ldr r3, =ROM_SI_REV + ldr r5, [r3] + cmp r5, #0x20 /* check silicon revision to determine the function entry address */ + + ldrlt r4, =0x00000edd /* function entry in TO1 ROM */ + ldrge r4, =0x0040487d /* function entry in TO2 ROM */ + blx r4 /* To return to ROM from plugin, we need to fill in these argument. - * Here is what need to do: - * Need to construct the paramters for this function before return to ROM: - * plugin_download(void **start, size_t *bytes, UINT32 *ivt_offset) - */ + * Here is what need to do: + * Need to construct the paramters for this function before return to ROM: + * plugin_download(void **start, size_t *bytes, UINT32 *ivt_offset) + */ quit_plugin: - pop {r0-r6, lr} - ldr r7, DDR_DEST_ADDR - str r7, [r0] - ldr r7, COPY_SIZE - str r7, [r1] - mov r7, #0x400 /* Point to the second IVT table at offset 0x42C */ - add r7, r7, #0x2C - str r7, [r2] - mov r0, #1 - - bx lr /* return back to ROM code */ + pop {r0-r6, lr} + ldr r7, DDR_DEST_ADDR + str r7, [r0] + ldr r7, COPY_SIZE + str r7, [r1] + mov r7, #0x400 /* Point to the second IVT table at offset 0x42C */ + add r7, r7, #0x2C + str r7, [r2] + mov r0, #1 + + bx lr /* return back to ROM code */ DDR_DEST_ADDR: .word TEXT_BASE COPY_SIZE: .word _end - TEXT_BASE |