/**
 * @brief   Reset handler for DB51903MT (Cortex-A5 MPCore)
 * @date    2015.09.03
 * @author  Copyright (c) 2015, eForce Co.,Ltd.  All rights reserved.
 *
 * @par     History
 *          - rev 1.0 (2015.09.03) i-cho
 *            Initial version.
 *
 * @history 2021_06_30  [SDK3.3] MMUアドレス変換テーブルの内蔵DRAM領域サイズをAG903Gに対応 (#3538)
 */

/* Program Status Register */

    .EQU I_BIT,     0x80
    .EQU F_BIT,     0x40
    .EQU T_BIT,     0x20
    .EQU USR_MOD,   0x10
    .EQU FIQ_MOD,   0x11
    .EQU IRQ_MOD,   0x12
    .EQU SVC_MOD,   0x13
    .EQU ABT_MOD,   0x17
    .EQU UND_MOD,   0x1B
    .EQU SYS_MOD,   0x1F
    .EQU MON_MOD,   0x16

/* System Primary Control */
    .EQU SYSC_BASE,             0xE0D00000
    .EQU SYSC_CA5_MISC_CTRL8,   0x0039C

/* SCU registers */
    .EQU SCU_BASE,      0x2C000000
    .EQU SCU_CTRL,      0x0000
    .EQU SCU_INVALL,    0x000C


/* vector entry */

        .ARM
        .section .vectors, "a", %progbits
        .globl  _PRST
        .type   _PRST, %function

        .extern _kernel_svchdr
        .extern _kernel_undhdr
        .extern _kernel_inthdr

        .globl  _vector_table
        .type   _vector_table, %function
_PRST:
_vector_table:
        b       _start
        ldr     pc,  _UndHandler
        ldr     pc,  _SwiHandler
        ldr     pc,  _PreHandler
        ldr     pc,  _AbtHandler
        nop
        ldr     pc,  _IrqHandler
        ldr     pc,  _FiqHandler

                .long   0
_UndHandler:    .long   _kernel_undhdr
_SwiHandler:    .long   _kernel_svchdr
_PreHandler:    .long   PreHandler
_AbtHandler:    .long   AbtHandler
                .long   0
_IrqHandler:    .long   _kernel_inthdr
_FiqHandler:    .long   FiqHandler


/*****************************************************************************
 *      Power On Reset Handler
 *
 ****************************************************************************
 */
        .text
        .align  4
        .globl  _start
        .type   _start, %function
_start:
        cpsid   if,  #SYS_MOD
        ldr     sp,  =_stack

        ldr     r0,  =SYSC_BASE
        ldr     r1,  [r0, #SYSC_CA5_MISC_CTRL8]
        bic     r1,  r1, #(0x1 << 24)
        str     r1,  [r0, #SYSC_CA5_MISC_CTRL8]

        /* Disable MMU */
        mrc     p15, 0,   r2,  c1,  c0, 0
        bic     r2,  r2, #0x00000001        @ Disable MMU
        bic     r2,  r2, #0x00000004        @ Disable D-Cache
        bic     r2,  r2, #0x00001000        @ Disable I-Cache
        mcr     p15, 0,  r2,  c1,  c0,  0
        dsb
        isb

        /* Invalidate TLB */
        bl      _kernel_invalid_tlb
        mov     r0,  #0
        mcr     p15,  0,  r0,  c7,  c5, 6 @ BPIALL - Invalidate entire branch predictor array

        /* Invalidate I/D cache */
        bl      _kernel_invalid_cache

        /* mmu initialization and address map setup */
        ldr     r0,  =mmu_space
        adr     r1,  mmu_cfgtbl
        bl      _ddr_cortexa_mmu_init

        /* Set vector address */
        mrc     p15, 0,  r0,  c1,   c0,  0
        bic     r0,  r0, #(0x1 << 13)
        mcr     p15, 0,  r0,  c1,   c0,  0
        ldr     r0,  =_PRST
        mcr     p15, 0,  r0,  c12,  c0,  0   @ set VBAR
        mcr     p15, 0,  r0,  c12,  c0,  1   @ set MVBAR
        isb

        /* Initialize L2 cache */
        bl      _kernel_init_l2_cache

#if !defined(__SOFTFP__)
        /*------------------------------------------------------
         * setup privileged and user mode access to coprocessors
         * 10 and 11, required to enable neon/vfp
         *------------------------------------------------------
         */
        mrc     p15, #0, r0, c1, c0, #2
        mov     r3,  #0x00f00000
        orr     r0,  r0, r3
        mcr     p15, #0, r0, c1, c0, #2
        mov     r0,  #0x40000000
        fmxr    fpexc, r0
#endif

        /*------------------------------------------------------
         * Unaligned access support
         *------------------------------------------------------
         */
        mrc     p15, 0, r0, c1, c0, 0
        bic     r0, r0, #2
        mcr     p15, 0, r0, c1, c0, 0

        /*------------------------------------------------------
         * Initialize stack pointer
         *------------------------------------------------------
         */
        mov     r0,  #FIQ_MOD|I_BIT|F_BIT
        msr     cpsr_c, r0
        ldr     sp,  =__fiq_stack

        mov     r0,  #UND_MOD|I_BIT|F_BIT
        msr     cpsr_c, r0
        ldr     sp,  =__undefined_stack

        mov     r0,  #ABT_MOD|I_BIT|F_BIT
        msr     cpsr_c, r0
        ldr     sp,  =__abort_stack

        mov     r0,  #SVC_MOD|I_BIT|F_BIT
        msr     cpsr_c, r0
        ldr     sp,  =__supervisor_stack

        mov     r0,  #IRQ_MOD|I_BIT|F_BIT
        msr     cpsr_c, r0
        ldr     sp,  =__irq_stack

        mov     r0,  #MON_MOD|I_BIT|F_BIT
        msr     cpsr_c, r0
        ldr     sp,  =__monitor_stack

        mov     r0,  #SYS_MOD|I_BIT|F_BIT
        msr     cpsr_c, r0

        /* Relocate the .data section */
        ldr     r3,  =_data
        ldr     r1,  =_sdata
        ldr     r2,  =_edata
1:
        cmp     r1,  r2
        bge     2f
        ldr     r0,  [r3],  #4
        str     r0,  [r1],  #4
        b       1b
2:

        /*------------------------------------------------------
         * call __kmc_startup_main
         *  zero clear .bss section
         *  # _fbss and _end (defined by linker script) symbols are required.
         *  initialize heap memory used by malloc()
         *  # _heap and _heap_size (defined by linker script) symbols are required.
         *  set frame pointer to 0
         *  setup VLINK (if necessary)
         *  _kmc_c_init() (user-defined initialize routine written by C)
         *  call C++ global constuctors
         *  setup argc, argv, env, and call main(argc, argv, env)
         *------------------------------------------------------
         */
        ldr     r12, =__kmc_startup_main
        mov     lr,  pc
        bx      r12
_err_loop:
        b     _err_loop


/********************************************************************************/
#include "DDR_CortexA_MMU.sh"

        .align  2
/*******************************************************************************
 *       Target dependent MMU configuration
 *
 *       Memory region attributes
 *
 *           ATR_STRG -----------------------------------------+
 *           ATR_SDEV -----------------------------------------+
 *           ATR_WTNW -----------------------------------------+
 *           ATR_WBNW -----------------------------------------+
 *           ATR_NONC -----------------------------------------+-- [ATR_SHRD] -- [ATR_NEXC] -- [ATR_NGLB]
 *           ATR_WBAW -----------------------------------------+
 *           ATR_NDEV -----------------------------------------+
 *           ATR_SELA --+-- ATR_INONC --+---+-- ATR_ONONC --+--+
 *                      +-- ATR_IWBAW --+   +-- ATR_OWBAW --+
 *                      +-- ATR_IWTNW --+   +-- ATR_OWTNW --+
 *                      +-- ATR_IWBNW --+   +-- ATR_OWBNW --+
 ******************************************************************************
 */
mmu_cfgtbl:
@               SIZE,       PADDR,      VADDR,      AP,     ATR
        .long   0x14000000, 0x2C000000, 0x2C000000, AP_RW,  ATR_STRG | ATR_NEXC @ Cortex-A5 peripherals
        .long   0x04000000, 0x60000000, 0x60000000, AP_RW,  ATR_NONC | ATR_NEXC @ EQS
        .long   0x00200000, 0x80000000, 0x80000000, AP_RW,  ATR_WBAW            @ Program code
        .long   0x00100000, mmu_space,  mmu_space,  AP_RW,  ATR_WBAW | ATR_NEXC @ TTB (1MB)
        .long   0x00200000, 0x80300000, 0x80300000, AP_RW,  ATR_WBAW | ATR_NEXC @ Program data
        .long   0x03B00000, 0x80500000, 0x80500000, AP_RW,  ATR_NONC | ATR_NEXC @ Non-cacheable user area
        .long   0x04000000, 0x84000000, 0x84000000, AP_RW,  ATR_NONC | ATR_NEXC @ AG903G extension
        .long   0x1E000000, 0xE0000000, 0xE0000000, AP_RW,  ATR_STRG | ATR_NEXC @ AG903 peripherals
        .long   0x00008000, 0xFE000000, 0xFE000000, AP_RW,  ATR_NONC | ATR_NEXC @ workram
        .long   0x00200000, 0xFFE00000, 0xFFE00000, AP_RO,  ATR_SDEV | ATR_NEXC @ BootROM(high)
        .long   0x00000000, 0x00000000, 0x00000000, 0,      0

/* TLB space */
        .section .mmu_tbl
        .align  14
        .globl  mmu_space
mmu_space:  .space  0x00100000


        .text
        .align  4
/****************************************************************************
 *      FIQ Handler                                                         *
 ****************************************************************************
 */
        .type   FiqHandler, %function
FiqHandler:
        b     FiqHandler

/****************************************************************************
 *      Prefetch Handler                                                    *
 ****************************************************************************
 */
        .type   PreHandler, %function
PreHandler:
        b     PreHandler

/****************************************************************************
 *      Abort Handler                                                       *
 ****************************************************************************
 */
        .type   AbtHandler, %function
AbtHandler:
        b     AbtHandler


/* end */
