/*****************************************************************************
  Exception handlers and startup code for TI TMS470.

  Copyright (c) 2005 Rowley Associates Limited.

  This file may be distributed under the terms of the License Agreement
  provided with this software. 
 
  THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE
  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *****************************************************************************/

  .section .vectors, "ax"
  .code 32
  .align 0
  
  #define SYS_BASE 0xFFFFFD00
  #define PCR_OFFS 0x030
  #define MFBAHR0_OFFS 0x100
  #define MFBALR0_OFFS 0x104
  #define MFBAHR1_OFFS 0x108
  #define MFBALR1_OFFS 0x10C
  #define MFBAHR2_OFFS 0x110
  #define MFBALR2_OFFS 0x114
  #define MFBAHR3_OFFS 0x118
  #define MFBALR3_OFFS 0x11C
  #define MFBAHR4_OFFS 0x120
  #define MFBALR4_OFFS 0x124
  #define MFBAHR5_OFFS 0x128
  #define MFBALR5_OFFS 0x12C
  #define SYSECR_OFFS 0x2E0

/*****************************************************************************
  Exception Vectors
 *****************************************************************************/
_vectors:
#ifdef __FLASH_BUILD
  b reset_handler
#else
  ldr pc, [pc, #reset_handler_address - . - 8]  /* reset */
#endif
  ldr pc, [pc, #undef_handler_address - . - 8]  /* undefined instruction */
  ldr pc, [pc, #swi_handler_address - . - 8]    /* swi handler */
  ldr pc, [pc, #pabort_handler_address - . - 8] /* abort prefetch */
  ldr pc, [pc, #dabort_handler_address - . - 8] /* abort data */
  nop
  ldr pc, [pc, #irq_handler_address - . - 8]    /* irq */
  ldr pc, [pc, #fiq_handler_address - . - 8]    /* fiq */

reset_handler_address:
  .word reset_handler
undef_handler_address:
  .word undef_handler
swi_handler_address:
  .word swi_handler
pabort_handler_address:
  .word pabort_handler
dabort_handler_address:
  .word dabort_handler
irq_handler_address:
  .word irq_handler
fiq_handler_address:
  .word fiq_handler

  .section .init, "ax"
  .code 32
  .align 0

/******************************************************************************
  Reset handler
 ******************************************************************************/
reset_handler:
#ifdef __FLASH_BUILD
  ldr r1, =SYS_BASE

  /* Disable reset on address access violation */
  ldr r0, =0x00004007
  str r0, [r1, #SYSECR_OFFS]

  /* Enable memory map */
  ldr r0, =0x00001030
  str r0, [r1, #MFBAHR2_OFFS]
  ldr r0, =0x00000080
  str r0, [r1, #MFBALR2_OFFS]

  ldr r0, =0x00001080
  str r0, [r1, #MFBAHR4_OFFS]
  ldr r0, =0x00000020
  str r0, [r1, #MFBALR4_OFFS]

  ldr r0, =0x00000000
  str r0, [r1, #MFBAHR1_OFFS]
  ldr r0, =0x000001c0
  str r0, [r1, #MFBALR1_OFFS]
  
  ldr r0, =0x00001000
  str r0, [r1, #MFBAHR0_OFFS]
  ldr r0, =0x000001c0
  str r0, [r1, #MFBALR0_OFFS]

  /* Setup clock ICLK = SYSCLK/16 */
  ldr r0, =0x0000001E
  str r0, [r1, #PCR_OFFS]
  ldr r0, =0x0000001F
  str r0, [r1, #PCR_OFFS]

  /* Jump to correct absolute address of the next instruction */
  ldr pc, =1f
1:

  /* Copy exception vectors into internal SRAM */
  ldr r10, =0x10300000
  ldr r11, =_vectors
  ldmia r11!, {r2-r9}
  stmia r10!, {r2-r9}
  ldmia r11!, {r2-r8}
  stmia r10!, {r2-r8}

  /* Disable FLASH @ 0x00000000 */
  ldr r0, =0x00000000
  str r0, [r1, #MFBAHR1_OFFS]
  ldr r0, =0x00000000
  str r0, [r1, #MFBALR1_OFFS]

  /* Enable internal SRAM @ 0x00000000 */
  ldr r0, =0x00000000
  str r0, [r1, #MFBAHR3_OFFS]
  ldr r0, =0x00000080
  str r0, [r1, #MFBALR3_OFFS]
#endif

  /* Jump to the default C runtime startup code. */
  b _start

/******************************************************************************
  Default exception handlers
  (These are declared weak symbols so they can be redefined in user code)
 ******************************************************************************/
undef_handler:
  b undef_handler
  
swi_handler:
  b swi_handler
  
pabort_handler:
  b pabort_handler
  
dabort_handler:
  b dabort_handler
  
irq_handler:
  b irq_handler
  
fiq_handler:
  b fiq_handler

  .weak undef_handler, swi_handler, pabort_handler, dabort_handler, irq_handler, fiq_handler

#ifdef __FLASH_BUILD

  .section .flashkeys, "a"
KEY1:
  .word 0xFFFFFFFF
KEY2:
  .word 0xFFFFFFFF
KEY3:
  .word 0xFFFFFFFF
KEY4:
  .word 0xFFFFFFFF

#endif
