📄 bootstrap.s
字号:
/*
* Synopsys : ST40 ROM bootstrapper which supports fail-safe booting from ROM.
*
* Copyright 2003-2006 STMicroelectronics Limited. All right reserved.
*
* Sets up the memory interfaces based on a user supplied poke table. The
* memory setup code is run entirely from within the ST40 caches. Then loads
* the master CPU boot application (a fail-safe applciation if present), before
* jumping to its start address.
*
* If performance is critical, re-define the CACHE_SIZE macro to the correct
* operand (data) cache size for the CPU in use to reduce the time spent purging
* the cache. The default is 64KB (the maximum).
*
* The code contained in this file is built to be position independent, and
* is fixed up when placed into ROM.
*
* If Cryptocore support is required, Cryptocore version must be defined by
* defining one of:
* #define CRYPTOCORE1
* #define CRYPTOCORE1_5
* #define CRYPTOCORE2
*/
/*
* FLASH header defines
*/
#ifndef FLASH_START
#if defined(__mb376__) || defined(__espresso__)
#define FLASH_START 0x00000400
#elif defined(__mb548__)
#define FLASH_START 0x01000000
#else
#define FLASH_START 0x00000000
#endif
#endif
#define FLASH_MAIN_ICD_PTR (FLASH_START + 0x00000440)
#define FLASH_FAILSAFE_ICS (FLASH_START + 0x00000444)
#define IMAGE_DIRECTORY_SIZE 64
#define CPU_NUMBER 0
#define BOOT_FLAG 0x80000000
#define FLASH_CPU_ARCH_SH4 0x00000100
#define _SH4REG_ASM_
#include <boardreg.h>
/*
* Error codes (shown as a flashing LED)
*/
#define ERR_NO_IMAGE 1
#define ERR_NO_METHOD 2
#define ERR_METHOD_FAILED 3
/*
* Re-define CACHE_SIZE to the correct value to speed up cache flushing.
* Note: It is possible to interrogate the cache to find out how large they are,
* but it's not a simple procedure, so for now we hard-code the size (this also
* keeps the bootstrap smaller).
*/
#ifndef CACHE_SIZE
#define CACHE_SIZE 65536
#endif
.import __memory_setup_table
.import __memory_setup_table_end
.import _led_on
.import _led_off
#if defined(CRYPTOCORE1) || defined(CRYPTOCORE1_5)
.import _cryptLLRestart
#elif defined(CRYPTOCORE2)
.import _cryptAddConfigTableRegions
#endif
#ifdef SE_MODE_BOOTSTRAP
.import __pmb_setup_table
#endif
.import _uncompress
.weak _uncompress
.global start
.global fatal
.section .text
.org 0x0
/*
* Entrypoint - jump over the method table.
*/
start:
bra 1f
nop
/*
* 32 bytes into the bootstrap is the method table, so others
* can use it if they want.
*/
.balign 32
method_table_size:
.long 7
method_table:
.long skip_section
.long copy_section
.long zero_section
.long rl_decode_section
.long inflate_section
.long copy_section /* Copy SYMBOLS sections */
.long copy_section /* Copy RELOCATIONS sections */
.balign 32
/*
* Stop the watchdog timer.
*/
1: mov.l 1f, r0
mov.w 2f, r1
mov.w r1, @r0
bra 3f
nop
.balign 4
1: .long ST40_CPG_WTCSR
2: .word 0xA500
3: .balign 2
/*
* Enable I-cache & D-cache; D-cache in copy-back mode.
*/
mov.l 1f, r0 /* R0 = CCR address */
mov.l 2f, r1 /* R1 = CCR mode */
mov.l r1, @r0
#if defined(__SH4_300__) /* SH4-300 and newer cores */
icbi @r0 /* 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 3f
nop
.balign 4
1: .long SH4_CCN_CCR
2: .long 0x8000090D /* Caches on, D-cache copy-back,
enhanced mode on SH4-200
series cores */
3:
/*
* Ensure that the poke loop and the associated data table are in
* the on-chip caches.
*
* The poke loop is structured so that all of it is pulled into the
* I-cache on its first iteration. To ensure that the data table is
* pulled into the D-cache, we simply read all the data.
*
* Setting up the on-chip peripherals may cause the EMI (where this
* FLASH image resides) to briefly hang, but the CPU will be safely
* executing from cache should this happen.
*/
mov.l p0_mask, r3 /* R3 = P0 translation mask */
mov.l 2f, r1 /* R1 = poke table start address */
mov.l 3f, r2 /* R2 = poke table end address */
mov.l 4f, r6 /* R6 = poke loop function */
and r3, r1 /* Convert to P0 addresses */
and r3, r2
and r3, r6
mov r1, r5 /* R5 = poke table start address (scratch) */
1: mov.l @r5+, r4
cmp/eq r5, r2
bf 1b
bra 5f
nop
.balign 4
2: .long __memory_setup_table
3: .long __memory_setup_table_end
4: .long poke_loop
5:
/*
* Its now safe to call the poke loop, since the data table will now
* be in the D-cache.
*/
jsr @r6
nop
3: mova 1f, r0 /* Get address to jump to */
mov.l p0_mask, r1
and r1, r0 /* Mask address to P0 */
jmp @r0 /* Start running from P0 */
nop
.balign 4
1:
#ifdef SE_MODE_BOOTSTRAP
/*
* We now call the poke loop with the __pmb_setup_table address in R5 to
* configure the PMBs as required for 32-bit 'space enhancement' mode.
*/
mov.l 1f, r1 /* R1 = PMB pokes start address */
mov.l 2f, r2 /* R6 = poke loop function */
jsr @r2
nop
bra 3f
nop
.balign 4
1: .long __pmb_setup_table
2: .long poke_loop
/*
* Now we transition to 32-bit mode. Note that the ST40 Core
* Architecture Manual says we should be executing from P1 or P2 in
* order to make the transition safely, but we cannot do this as we may
* well not have mapped any FLASH in the PMBs. We ignore the
* restriction (and get lucky)!
*/
3: mov.l 1f, r1 /* R1 = register address */
mov.l @r1, r0
mov.l 2f, r2 /* R2 = SE bit set */
or r2, r0 /* OR in SE bit */
mov.l r0, @r1
#if defined(__SH4_200__) || defined(__SH4_500__)
nop /* Ensure coherency using nops */
nop
nop
nop
nop
nop
nop
nop
bra 3f
nop
.balign 4
1: .long SH4_CCN_MMUCR
2: .long (1 << 4)
3:
#elif defined(__SH4_300__)
.balignw 4, 0x0009 /* Pad with nops to word aligned address */
mova @(4, pc), r0 /* Ensure coherency using icbi */
icbi @r0
bra 3f
nop
.balign 4
1: .long SH4_CCN_PASCR
2: .long (1 << 31)
3:
#else
#error Specified core does not support 32-bit space enhancement mode - check your -m4-<variant> compiler option
#endif
#endif /* SE_MODE_BOOTSTRAP */
/*
* Now we are configured, locate the boot image and load it. First we
* check for a fail-safe image. If the first word in the fail-safe
* image control structure ROM is 0xFFFFFFFF, there is no fail-safe
* image.
*/
mov.l failsafe_ics_addr, r1 /* R1 = fail-safe image control structures base */
mov.l @r1, r0 /* R0 = value in word 1 of ICS */
add #1, r0 /* If R0 is -1, no fail-safe image */
cmp/eq #0, r0 /* We add 1 and compare with 0 */
bt no_failsafe_image
/* There is a failsafe image, so select it for relocation */
mov r1, r8 /* R8 = R1 = fail-safe image control structures base */
bra found_slot
nop
no_failsafe_image:
/*
* No fail-safe image - scan for a main image which is for this CPU
* number and with the top bit set in its signature (boot image).
*/
mov.l main_image_directory_ptr, r0 /* R0 = image directory pointer address */
mov.l @r0, r0 /* R0 = image directory address */
mov #IMAGE_DIRECTORY_SIZE, r1 /* R1 = maximum number of entries */
mov.l boot_signature, r4 /* R4 = boot image signature to find */
check_slot:
mov.l @r0, r8 /* R8 = image address */
tst r8, r8 /* Skip if NULL */
bt skip_entry
mov.l @(0x20, r8), r3 /* R3 = image signature */
cmp/eq r3, r4 /* Image signature matches ? */
bt found_slot /* Yes, relocate image */
skip_entry:
dt r1 /* Scan rest of table */
bf/s check_slot
add #4, r0
mov #ERR_NO_IMAGE, r0 /* No boot image; set error in R0 and spin */
/*
* Fatal error loop.
*
* R0 = error code.
*/
fatal: mov r0,r6
mov r6,r7
mov.l 1f, r8 /* R8 = led_on() */
mov.l 2f, r9 /* R9 = led_off() */
mova fatal_again, r0
jmp @r0
nop
.balign 4
1: .long _led_on
2: .long _led_off
fatal_again:
jsr @r8 /* LED on */
nop
bsr fatal_delay
mov #5,r0
jsr @r9 /* LED off */
nop
bsr fatal_delay
mov #5,r0
add #-1,r7
tst r7,r7
bf fatal_again
bsr fatal_delay
mov #10,r0
bra fatal_again
mov r6,r7
fatal_delay:
mov #30,r1
swap.w r1,r1
1: add #-1,r1
tst r1,r1
bf 1b
add #-1,r0
tst r0,r0
bf fatal_delay
rts
nop
/*
* Load CPU boot image.
*
* R8 = boot image control structure address.
*/
found_slot:
mov.l @(0x2C, r8), r9 /* R9 = number of sections */
mov.l @(0x24, r8), r15 /* R15 = stack address */
mov.l @(0x28, r8), r14 /* R14 = entry point */
mov.l r14, @-r15 /* Push entry point onto stack */
next_section:
mov.l @(0x30, r8), r1 /* R1 = method number */
mov.l @(0x34, r8), r4 /* R4 = source */
mov.l @(0x38, r8), r5 /* R5 = destination */
mov.l @(0x3C, r8), r6 /* R6 = length */
mov.l 2f, r7 /* R7 = method table size */
mov.l @r7, r7
cmp/ge r7, r1 /* Is the method legal ? */
bf/s method_ok
shll2 r1 /* Scale method by 4 */
bt/s fatal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -