NextVOD_Baremetal_SPL/startup_stx7105.S

260 lines
7.6 KiB
ArmAsm

/* Startup code, we can't use non-PIC code nor RAM before the LMI is initialized:
* The CPU starts with physical address 0x0, however the linker is linked to virtual
* addresses and LMI.
* Non-PIC code means any indirect addressing other than relative to PC.
*/
.section .text.init, "ax"
.global _start
_start:
nop
nop
mov.l _sr_k, r0
ldc r0, sr
_disable_wdt:
mov.l _cpg_wdt_wtcsr_k, r0
mov.l _cpg_wdt_wtcsr_value_k, r1
mov.w r1, @r0
_configure_spinor:
mov.l _emi_spinor_config_data_k, r0
mov.l _emi_spinor_config_data_value_k, r1
mov.l r1, @r0
mov.l _emi_spinor_modeselect_k, r0
mov.l _emi_spinor_modeselect_value_k, r1
mov.l r1, @r0
/* TODO: Initialize PMB, setup caches !! */
/*
* We need PMBs for LMI and EMI, both cached and uncached.
* To configure an PMB region, two register writes need to be issued:
* 1: Write to PMB address array, with region virtual address.
* The PMB address array entry is calculated as follows:
* - PMB_SLOT_X_ADDR=0xF610_0X00, X=0-F, with a maximum of 16 regions.
* The slot contents are defined as follows:
* - 0xAA00_0100, AA=Virtual page number, bit 31:30 has to be 0b10
* i.e. VA should located in range 0x8000_0000 - 0xBFFF_FFFF
* Note: VA needs to align with its configured size.
* 2: Write to PMB data array, with region size and cache modes.
* The PMB data array entry is calculated as follows:
* PMB_SLOT_X_DATA=0xF710_0X00, X=0-F, with a maximum of 16 regions.
*/
_invalidate_pmb:
mov.l _pmb_address_base, r1 /* PMB address slot base address */
mov #0, r2 /* Value to be written to PMB address slot */
mov #1, r3 /* PMB address stride, 0x100 */
shll8 r3 /* See above */
mov #0, r0 /* Counter */
_loop_invalid_pmb:
mov.l r2, @r1 /* Clear slot N */
add r3, r1 /* Slot += 1 */
cmp/eq #15, r0 /* Counter == 15? */
bf/s _loop_invalid_pmb /* Note: this is a delayed branch, be careful. */
add #1, r0 /* Counter += 1 */
_setup_pmb:
mova _pmb_poke_start_k, r0
mov r0, r1
mova _pmb_poke_end_k, r0
mov r0, r2
_loop_setup_pmb:
mov.l @r1+, r0 /* 1st word, register address */
mov.l @r1+, r3 /* 2nd word, register value */
mov.l r3, @r0
cmp/gt r1, r2
bt _loop_setup_pmb
_invalidate_caches:
mov.l _ccn_ccr_k, r0
mov #0, r1
mov.l r1, @r0 /* Clear all bits */
nop
nop
nop
nop
nop
nop
nop
nop
nop
_setup_caches:
mov.l _ccn_ccr_value_k, r1
mov.l r1, @r0
nop
nop
nop
nop
nop
nop
nop
nop
nop
_init_lmi:
mov.l _init_ram_k, r1 /* Load actual function address to r1 */
jsr @r1 /* Jump to the init_ram function */
nop
_enable_se_mode:
mov.l _ccn_mmucr_k, r0
mov #4, r1 /* SH4_MMUCR_TI */
mov.l r1, @r0
mov.l _ccn_pascr_k, r0
mov.l _ccn_pascr_value_k, r1
mov.l r1, @r0
_go_non_privileged:
mov.l _copy_app_k, r0
ldc r0, spc
stc sr, r0
ldc r0, ssr
rte
nop
_copy_app:
mov.l _app_copy_end_k, r0 /* App load location, in EMI */
mov.l @r0, r1 /* Offset 0x04, eidata */
mov.l _app_base_k, r0 /* App base location, in LMI */
mov.l @r0, r2 /* Offset 0x00, stext */
_loop_copy_app:
mov.l @r0+, r3
mov.l r3, @r2
add #4, r2
cmp/gt r2, r1
bt _loop_copy_app
_jump_to_app:
mov.l _app_entry_k, r0 /* App entry point, in LMI, defined by app */
mov.l @r0, r1
jsr @r1
/* It would be more efficient by using indirect addressing instead of 8 instructions... */
/* Align to 4 byte boundary since we are loading the whole word */
.align 4
/* PMB address register */
_pmb_address_base:
.long 0xF6100000
/* PMB poke tables */
_pmb_poke_start_k:
.long 0xF6100000 /* Address entry #0 register : LMI lower half, 128MB, mapped to 0x8000_0000 */
.long 0x80000100 /* Address entry #0 data : LMI lower half, 128MB, mapped to 0x8000_0000 */
.long 0xF6100100 /* Address entry #1 register : LMI higher half, 128MB, mapped to 0x8800_0000 */
.long 0x88000100 /* Address entry #1 data : LMI higher half, 128MB, mapped to 0x8800_0000 */
.long 0xF6100200 /* Address entry #2 register : LMI lower half, 128MB, mapped to 0x9000_0000 */
.long 0x90000100 /* Address entry #2 data : LMI lower half, 128MB, mapped to 0x9000_0000 */
.long 0xF6100300 /* Address entry #3 register : LMI higher half, 128MB, mapped to 0x9800_0000 */
.long 0x98000100 /* Address entry #3 data : LMI higher half, 128MB, mapped to 0x9800_0000 */
.long 0xF6100400 /* Address entry #4 register : EMI NOR uncached, 64MB, mapped to 0xA000_0000 */
.long 0xA0000100 /* Address entry #4 data : EMI NOR uncached, 64MB, mapped to 0xA000_0000 */
.long 0xF6100500 /* Address entry #5 register : EMI NOR cached, 64MB, mapped to 0xA400_0000 */
.long 0xA4000100 /* Address entry #5 data : EMI NOR cached, 64MB, mapped to 0xA400_0000 */
.long 0xF7100000 /* Data entry #0 register : LMI lower half, 128MB, uncached, unbuffered */
.long 0x40000380 /* Data entry #0 data : LMI lower half, 128MB, uncached, unbuffered */
.long 0xF7100100 /* Data entry #1 register : LMI higher half, 128MB, uncached, unbuffered */
.long 0x48000380 /* Data entry #1 data : LMI higher half, 128MB, uncached, unbuffered */
.long 0xF7100200 /* Data entry #2 register : LMI lower half, 128MB, cached, buffered */
.long 0x40000188 /* Data entry #2 data : LMI lower half, 128MB, cached, buffered */
.long 0xF7100300 /* Data entry #3 register : LMI higher half, 128MB, cached, buffered */
.long 0x48000188 /* Data entry #3 data : LMI higher half, 128MB, cached, buffered */
.long 0xF7100400 /* Data entry #4 register : EMI NOR uncached, 64MB, uncached, unbuffered */
.long 0x00000310 /* Data entry #4 data : EMI NOR uncached, 64MB, uncached, unbuffered */
.long 0xF7100500 /* Data entry #5 register : EMI NOR cached, 64MB, cached, buffered */
.long 0x00000118 /* Data entry #5 data : EMI NOR cached, 64MB, cached, buffered */
_pmb_poke_end_k:
.long 0x0000000
/* CCN CCR address */
_ccn_ccr_k:
.long 0xFF00001C
_ccn_ccr_value_k:
.long 0x8000090D
_ccn_mmucr_k:
.long 0xFF000010
_ccn_pascr_k:
.long 0xFF000070
_ccn_pascr_value_k:
.long 0x80000000
/* SR content */
_sr_k:
.long 0x400000F0
/* WDT */
_cpg_wdt_wtcsr_k:
.long 0xFFC0000C
_cpg_wdt_wtcsr_value_k:
.long 0x0000A500
/* EMI SPI NOR configuration registers */
_emi_spinor_config_data_k:
.long 0xFE702020
_emi_spinor_config_data_value_k:
.long 0x00020011
_emi_spinor_modeselect_k:
.long 0xFE702018
_emi_spinor_modeselect_value_k:
.long 0x00000002
/* PIO registers for debugging */
_gpio_set_k:
.long 0xFD020004
_gpio_clr_k:
.long 0xFD020008
_gpio_clr_pc0_k:
.long 0xFD020028
_gpio_set_pc1_k:
.long 0xFD020034
_gpio_clr_pc2_k:
.long 0xFD020048
_system_config_34_k:
.long 0xFE001188
_system_config_34_value_k:
.long 0x00000F00
_gpio4_clr_pc0_k:
.long 0xFD024028
_gpio4_set_pc1_k:
.long 0xFD024034
_gpio4_set_pc2_k:
.long 0xFD024044
_copy_app_k:
.long _copy_app
/* libc FPU routine */
_set_fpscr_k:
.long ___set_fpscr
/* C library consts */
_stack_k:
.long _stack
_sidata_k:
.long _sidata
_sdata_k:
.long _sdata
_edata_k:
.long _edata
_end_k:
.long _end
/* Function pointers */
_init_ram_k:
.long _memory_setup_init_ram
_app_base_k:
.long 0xA0008000U /* stext */
_app_copy_end_k:
.long 0xA0008004U /* eiaddr */
_app_entry_k:
.long 0xA0008008U /* entry */