⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootstrap.s

📁 采用ST20 CPU的机顶盒的烧写程序
💻 S
📖 第 1 页 / 共 2 页
字号:
          mov   #ERR_NO_METHOD, r0              /* Illegal method; set error in R0 and spin */

method_ok:
        mov.l   1f, r0
        add     r1, r0                          /* R0 = address of method entry */
        mov.l   @r0, r0                         /* Get method function address */
        jsr     @r0
          nop

        tst     r0, r0                          /* Did the method succeed ? */
        bf/s    fatal
          mov   #ERR_METHOD_FAILED, r0          /* Method failed; set error in R0 and spin */

        dt      r9                              /* Do the next section */
        bf/s    next_section
          add   #0x10, r8

        bra     3f                              /* Finished loading CPU */
          nop

        .balign 4
1:      .long   method_table
2:      .long   method_table_size

3:
        /*
         * Now that all sections have been relocated purge the D-cache by
         * writing 0 to every OC array entry to ensure we execute what we
         * relocated.
         */
#define OC_ARRAY_BASE           0xF4000000
#define OC_NUM_ENTRIES          (CACHE_SIZE / 32)

        mov.l    3f, r1                         /* R1 = OC array base address */
        mov.w    2f, r2                         /* R2 = # of OC array entries */
        mov      #0, r0
1:
        mov.l    r0, @r1  
        dt       r2
        add      #32, r1
        bf       1b
#if defined(__SH4_300__) /* SH4-300 and newer cores */
        icbi    @r1                             /* Ensure next instruction is re-fetched */
#else
#if !(defined(__SH4_100__) || defined(__SH4_200__) || defined(__SH4_400__) || defined(__SH4_500__))
#warning -m4-<arch> was not specified - incorrect instructions may be used
#endif
        nop                                     /* Required delay to empty pipeline/prefetch */
        nop
        nop
        nop
        nop
        nop
        nop
        nop
#endif
        bra     4f
          nop

2:      .word   OC_NUM_ENTRIES
        .balign 4
3:      .long   OC_ARRAY_BASE

4:
        /*
         * If we have a Cryptocore, we now switch on checking of all regions
         * prepared as signed blocks and added to the config table, as all code
         * has been loaded.
         * This allows us to execute the code without the system being reset.
         * The function called is a C function and may use the stack, but takes
         * no parameters.
         */
#if defined(CRYPTOCORE1) || defined(CRYPTOCORE1_5)
        /*
         * Call cryptLLRestart() to transition to linked list mode.
         */
        mov.l   1f, r0                          /* R0 = cryptLLRestart() */
        jsr     @r0
          nop
        bra     2f
          nop

        .balign 4
1:      .long   _cryptLLRestart
#elif defined(CRYPTOCORE2)
        /*
         * Call cryptAddConfigTableRegions() to add the config table regions.
         */
        mov.l   1f, r0                          /* R0 = cryptAddConfigTableRegions() */
        jsr     @r0
          nop
        bra     2f
          nop

        .balign 4
1:      .long   _cryptAddConfigTableRegions
#endif /* Cryptocore versions */

2:       
        /*
         * Now call boot image entry point.
         */
        mov.l   @r15+, r0                       /* R0 = entry point */
        jsr     @r0
          nop
1:      bra     1b                              /* If return from entry point then loop forever */
          nop


        /*
         * Method to copy a word aligned section from ROM to RAM.
         *
         * R4 = src, R5 = dst, R6 = length (bytes)
         */
copy_section:
        add     #3, r6                          /* R6 = number of words */
        shlr2   r6
1:      mov.l   @r4+, r0                        /* Copy data ... */
        mov.l   r0, @r5
        dt      r6
        bf/s    1b
          add   #4, r5

        rts
          mov   #0, r0

        /*
         * Method to zero a section.
         *
         * R4 = src, R5 = dst, R6 = length (bytes)
         */
zero_section:
        mov     #4, r0                          /* length < 4 bytes, do byte writes */
        cmp/ge  r0, r6
        bt      2f

        mov     #0, r0
1:      mov.b   r0, @r5                         /* Zero bytes ... */
        dt      r6
        bf/s    1b
          add   #1, r5

        rts
          nop

        /*
         * length >= 4 bytes, section must be word aligned.
         */
2:      add     #3, r6                          /* Number of words to zero */
        shlr2   r6
        mov     #0, r0
1:      mov.l   r0, @r5                         /* Zero words ... */
        dt      r6
        bf/s    1b
          add   #4, r5

        rts
          nop

        /*
         * Method to run length decode a section.
         *
         * Not implemented.
         */
rl_decode_section:
        rts
          mov   #-1, r0

        /*
         * Method to skip a section (do nothing).
         */
skip_section:
        rts
          mov   #0, r0

        /*
         * Method to inflate a zlib compressed section.
         *
         * Move parameters into registers used for a C function call, and
         * call the C function to do the decompress.
         *
         * R4 = src, R5 = dst, R6 = srclen (bytes)
         *
         * uncompress() function requires:
         *
         * R4 = dst, R5 = &dstlen, R6 = src, R7 = srclen
         */
inflate_section:
        mov.l   2f, r0                          /* R0 = uncompress() */
        tst     r0, r0                          /* uncompress() available ? */
        bf      1f

        rts                                     /* No */
          mov   #-1, r0

1:      sts.l   pr, @-r15                       /* Preserve PR */
        mov     r6, r7                          /* Setup parameters */
        mov     r4, r6
        mov     r5, r4
        mov     #-1, r5
        mov.l   r5, @-r15
        jsr     @r0                             /* Call uncompress() */
          mov   r15, r5
        add     #4, r15
        lds.l   @r15+, pr                       /* Restore PR */
        rts
          nop

        .balign 4
2:      .long   _uncompress

        /*
         * Method to iterate through a table of pokes.
         * Used to configure the on-chip/board peripherals.
         *
         * Note that the code is executed from the I-cache, with all its
         * data in the D-cache.
         */

        .balign 32

poke_loop:
        mov.l   @r1+, r0                        /* R0 = opcode */
        mov.l   @r1+, r2                        /* R2 = address */
        mov.l   @r1+, r3                        /* R3 = value */

/*#define END_MARKER					.long 0, 0, 0*/
        cmp/eq  #0, r0                          /* End marker ? */
        bf      1f

        rts                                     /* Return */
          nop

/*#define POKE_LONG(A, V)					.long 4, A, V*/
1:      cmp/eq  #4, r0                          /* 4 byte write ... */
        bf      1f
        mov.l   r3, @r2

/* #define POKE_SHORT(A, V)				.long 2, A, V*/
1:      cmp/eq  #2, r0                          /* 2 byte write ... */
        bf      1f
        mov.w   r3, @r2

/*#define POKE_CHAR(A, V)					.long 1, A, V*/
1:      cmp/eq  #1, r0                          /* 1 byte write ... */
        bf      1f
        mov.b   r3, @r2

/*#define OR_LONG(A, V)					.long 5, A, V*/
1:      cmp/eq  #5, r0                          /* 4 byte OR ... */
        bf      1f
        mov.l   @r2,r4
        or      r3,r4
        mov.l   r4,@r2

/*#define UPDATE_LONG(A, AND, OR)				.long 6, A, AND, OR*/
1:      cmp/eq  #6, r0                          /* 4 byte UPDATE ... */
        bf      1f
        mov.l   @r2,r4
        and     r3,r4
        mov.l   @r1+,r3                         /* R3 = OR value */
        or      r3,r4
        mov.l   r4,@r2

/*#define POKE_UPDATE_LONG(A1, A2, AND, SHIFT, OR)	.long 8, A1, A2, AND, SHIFT, OR*/
1:      cmp/eq  #8, r0                          /* 4 byte write UPDATE ... */
        bf      1f
        mov.l   @r3,r4
        mov.l   @r1+,r3                         /* R3 = AND value */
        and     r3,r4
        mov.l   @r1+,r3                         /* R3 = SHIFT value */
        shld    r3,r4
        mov.l   @r1+,r3                         /* R3 = OR value */
        or      r3,r4
        mov.l   r4,@r2

/*#define WHILE_NE(A, AND, VAL)				.long 7, A, AND, VAL*/
1:      cmp/eq  #7, r0                          /* WHILE != ... */
        bf      1f
        mov.l   @r1+,r5                         /* R5 = compare value */
2:      mov.l   @r2,r4
        and     r3,r4
        cmp/eq  r4,r5
        bf      2b

/*#define IF(A, AND, VAL, COMMAND)			.long 9, A, AND, VAL; COMMAND*/
1:      cmp/eq  #9,r0                           /* IF == ... next op */
        bf      1f
        mov.l   @r1+,r5
        mov.l   @r2,r4
        and     r3,r4
        cmp/eq  r4,r5
        bt      poke_loop                       /* Compare succeeded - perform next op */
2:                                              /* Skip the next operation (read past it) */
        mov.l   @r1+,r0                         /* R0 = opcode */
        mov.l   @r1+,r2                         /* skip address */
        mov.l   @r1+,r2                         /* skip value */
                                                /* How many further reads do we need to skip? */
        cmp/eq  #9,r0                           /* If it's another IF, skip 1 and go back to start of skip loop */
        bf      3f
        mov.l   @r1+,r2
        bra     2b
          nop

3:      mov     #5,r2
        cmp/gt  r2,r0
        bf      5f                              /* 0 further reads */

        cmp/eq  #8,r0                           /* Is it number 8 (3 reads, otherwise 1 read) */
        bf      4f
        mov.l   @r1+,r2                         /* Skip 1 read */
        mov.l   @r1+,r2                         /* Skip 1 read */        
4:      mov.l   @r1+,r2                         /* Skip 1 read and continue */
5:      bra     poke_loop
          nop

1:      mov     #1,r0                           /* Small delay (65536) */
        swap.w  r0, r0

2:      add     #-1,r0                          /* Delay ... */
        cmp/eq  #0, r0
        bf      2b
        bt      poke_loop

        /*
         * Simple implementation of memcpy() to avoid dependency on C library.
         *
         * R4 = dst, R5 = src, R6 = srclen (bytes)
         */
        .global _memcpy
_memcpy:
        mov     r4, r0                          /* Check if source and destination are word aligned */
        or      r5, r0
        tst     r6, r6
        bt/s    3f                              /* ... skip zero length copy */
          tst   #3, r0
        bf      2f

        mov     r6, r2
        shlr2   r6

1:      mov.l   @r5+, r0                        /* Copy words ... */
        dt      r6
        mov.l   r0, @r4
        bf/s    1b
          add   #4, r4

        mov     r2, r0
        and     #3, r0                          /* Fall through to byte copy for any odd bytes */
        mov     r0, r6
        tst     r6, r6
        bt      3f

2:      mov.b   @r5+, r0                        /* Copy bytes ... */
        dt      r6
        mov.b   r0, @r4
        bf/s    2b
          add   #1, r4

3:     rts
          mov   r4, r0

        .balign 4

p0_mask:
        .long   0x1FFFFFFF

failsafe_ics_addr:
        .long   FLASH_FAILSAFE_ICS

main_image_directory_ptr:
        .long   FLASH_MAIN_ICD_PTR

boot_signature:
        .long   BOOT_FLAG | CPU_NUMBER | FLASH_CPU_ARCH_SH4

        .end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -