| /* ------------------------------------------ |
| * Copyright (c) 2016, Synopsys, Inc. All rights reserved. |
| |
| * Redistribution and use in source and binary forms, with or without modification, |
| * are permitted provided that the following conditions are met: |
| |
| * 1) Redistributions of source code must retain the above copyright notice, this |
| * list of conditions and the following disclaimer. |
| |
| * 2) Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation and/or |
| * other materials provided with the distribution. |
| |
| * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may |
| * be used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
| * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| * \version 2016.05 |
| * \date 2014-07-15 |
| * \author Wayne Ren(Wei.Ren@synopsys.com) |
| --------------------------------------------- */ |
| |
| /** |
| * \file |
| * \ingroup ARC_HAL_STARTUP |
| * \brief assembly part of startup process |
| */ |
| |
| /** |
| * \addtogroup ARC_HAL_STARTUP |
| * @{ |
| */ |
| /** @cond STARTUP_ASM */ |
| |
| #define __ASSEMBLY__ |
| #include "embARC_BSP_config.h" |
| #include "inc/arc/arc.h" |
| |
| .file "arc_startup.S" |
| |
| .weak _f_sdata /* start of small data, defined in link script */ |
| .weak init_hardware_hook /* app hardware init hook */ |
| .weak init_software_hook /* app software init hook */ |
| |
| .extern board_main |
| .extern exc_entry_table |
| |
| /* initial vector table */ |
| .section .init_vector, "a" |
| .long _arc_reset |
| .section .init_bootstrap, "ax" |
| .global _arc_reset |
| .align 4 |
| _arc_reset: |
| _arc_reset_stage1: |
| kflag STATUS32_RESET_VALUE |
| |
| /* STAGE 1 */ |
| |
| /* necessary hardware should be done first to speed up initialization |
| 1. system clk |
| 2. mem controller must be initialized before any access to external |
| mem. |
| 3. others |
| */ |
| _arc_cache_init_start: |
| lr r0, [AUX_BCR_D_CACHE] |
| cmp r0, 2 |
| /* invalidate dcache */ |
| jle _arc_icache_init |
| mov r0, 1 |
| sr r0, [AUX_DC_IVDC] |
| sr r0, [AUX_DC_CTRL] |
| _arc_icache_init: |
| lr r0, [AUX_BCR_I_CACHE] |
| cmp r0, 2 |
| jle _arc_cache_init_end |
| /* invalidate icache */ |
| mov r0, 1 |
| sr r0, [AUX_IC_IVIC] |
| nop_s |
| nop_s |
| nop_s |
| sr r0, [AUX_IC_CTRL] |
| |
| _arc_cache_init_end: |
| mov r0, init_hardware_hook |
| cmp r0, 0 |
| jlne [r0] |
| |
| /* STAGE 2: init necessary registers */ |
| |
| _arc_reset_stage2: |
| mov r0, 0 |
| |
| /* interrupt related init */ |
| sr r0, [AUX_IRQ_ACT] |
| sr r0, [AUX_IRQ_CTRL] |
| sr r0, [AUX_IRQ_HINT] |
| |
| /* use the new vector table to replace the old one */ |
| #if defined(ARC_FEATURE_SEC_PRESENT) && (SECURESHIELD_VERSION < 2) |
| sr exc_entry_table, [AUX_INT_VECT_BASE_S] |
| #else |
| sr exc_entry_table, [AUX_INT_VECT_BASE] |
| #endif |
| |
| /* init stack */ |
| #if ARC_FEATURE_RGF_BANKED_REGS >= 16 && ARC_FEATURE_RGF_BANKED_REGS > 1 && ARC_FEATURE_FIRQ == 1 |
| #if _STACKSIZE < 512 |
| #error "not enough stack size for irq and firq" |
| #endif |
| |
| /* switch to register bank1 */ |
| lr r0, [AUX_STATUS32] |
| bic r0, r0, 0x70000 |
| or r0, r0, 0x10000 |
| kflag r0 |
| /* set sp, gp, fp in bank1 */ |
| mov sp, _e_stack |
| mov gp, _f_sdata |
| mov fp, 0 |
| /* come back to bank0 */ |
| lr r0, [AUX_STATUS32] |
| bic r0, r0, 0x70000 |
| kflag r0 |
| mov sp, _e_stack-256 |
| #else |
| mov sp, _e_stack /* init stack pointer */ |
| #endif |
| mov gp, _f_sdata /* init small-data base register */ |
| mov fp, 0 /* init fp register */ |
| |
| _arc_reset_stage3: |
| _s3_copy_text: |
| mov r0, _f_text |
| mov r1, _load_addr_text |
| cmp r0, r1 |
| |
| /* if load addr == run addr, no need to copy */ |
| jeq _s3_copy_rodata |
| mov r3, _e_text |
| _s3_copy_text_loop: |
| ld.ab r2, [r1, 4] |
| st.ab r2, [r0, 4] |
| cmp r0, r3 |
| jlt _s3_copy_text_loop |
| _s3_copy_rodata: |
| mov r0, _f_rodata |
| mov r1, _load_addr_rodata |
| cmp r0, r1 |
| |
| /* if load addr == run addr, no need to copy */ |
| jeq _s3_copy_data |
| mov r3, _e_rodata |
| _s3_copy_rodata_loop: |
| ld.ab r2, [r1, 4] |
| st.ab r2, [r0, 4] |
| cmp r0, r3 |
| jlt _s3_copy_rodata_loop |
| _s3_copy_data: |
| mov r0, _f_data |
| mov r1, _load_addr_data |
| cmp r0, r1 |
| jeq _s3_clear_bss |
| |
| /* if load addr == run addr, no need to copy */ |
| mov r3, _e_data |
| _s3_copy_data_loop: |
| ld.ab r2, [r1, 4] |
| st.ab r2, [r0, 4] |
| cmp r0, r3 |
| jlt _s3_copy_data_loop |
| _s3_clear_bss: |
| mov r0, _f_bss |
| mov r1, _e_bss |
| cmp r0, r1 |
| jge _arc_reset_call_main |
| mov r2, 0 |
| _s3_clear_bss_loop: |
| st.ab r2, [r0, 4] |
| cmp r0, r1 |
| jlt _s3_clear_bss_loop |
| |
| /* STAGE 3: go to main */ |
| |
| _arc_reset_call_main: |
| |
| /* \todo add cpp init here */ |
| mov r0, init_software_hook |
| cmp r0, 0 |
| jlne [r0] |
| /* board level library init */ |
| #ifdef LIB_SECURESHIELD |
| jl secureshield_start |
| #else |
| /* early init of interrupt and exception */ |
| jl exc_int_init |
| #endif |
| /* init cache */ |
| jl arc_cache_init |
| #if defined(__MW__) |
| jl _init |
| #elif defined(__GNU__) |
| jl __do_global_ctors_aux |
| jl __do_init_array_aux |
| #endif |
| jl board_main /* board-level main */ |
| #if defined(__MW__) |
| jl _fini |
| #elif defined(__GNU__) |
| jl __do_global_dtors_aux |
| #endif |
| .global _exit_loop |
| .global _exit_halt |
| .align 4 |
| _exit_halt: |
| _exit_loop: |
| flag 0x1 |
| nop |
| nop |
| nop |
| b _exit_loop |
| |
| #if defined(__MW__) |
| .global _init, _fini |
| .section ".init",text |
| _init: |
| .cfa_bf _init |
| push %blink |
| .cfa_push {%blink} |
| |
| .section ".init$999999", text, 1, 2, check_text_align=0 |
| pop %blink |
| .cfa_pop {%blink} |
| j [%blink] |
| .cfa_ef |
| |
| .section ".fini", text |
| _fini: |
| .cfa_bf _fini |
| push %blink |
| .cfa_push {%blink} |
| |
| .section ".fini$999999", text, 1, 2, check_text_align=0 |
| pop %blink |
| .cfa_pop {%blink} |
| j [%blink] |
| .cfa_ef |
| #endif |
| /** @endcond */ |
| |
| /** }@*/ |