view src/cs/system/main/int.s @ 632:d968a3216ba0

new tangomdm build target TCS211/Magnetite built for target leonardo runs just fine on the Tango-based Caramel board, but a more proper tangomdm build target is preferable in order to better market these Tango modems to prospective commercial customers. The only differences are in GPIO and MCSI config: * MCSI is enabled in the tangomdm build config. * GPIO 1 is loudspeaker amplifier control on Leonardo, but on Tango platforms it can be used for anything. On Caramel boards this GPIO should be configured as an output driving high. * GPIO 2 needs to be configured as Calypso input on Leonardo, but on Tango platforms it can be used for anything. On Caramel boards this GPIO should be configured as an output, either high or low is OK.
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 04 Jan 2020 19:27:41 +0000
parents ae18f9aad7ce
children 8cf3029429f3
line wrap: on
line source

;******************************************************************************
;            TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION           
;                                                                             
;   Property of Texas Instruments -- For  Unrestricted  Internal  Use  Only 
;   Unauthorized reproduction and/or distribution is strictly prohibited.  This 
;   product  is  protected  under  copyright  law  and  trade  secret law as an 
;   unpublished work.  Created 1987, (C) Copyright 1997 Texas Instruments.  All 
;   rights reserved.                                                            
;                  
;                                                           
;   Filename       	: int.s
;
;   Description    	: Nucleus initialization
;
;   Project        	: Drivers
;
;   Author         	: proussel@ti.com  Patrick Roussel.
;
;   Version number	: 1.3
;
;   Date and time	: 07/23/98 15:36:07
;
;   Previous delta 	: 07/23/98 15:36:06
;
;   SCCS file      	: /db/gsm_asp/db_ht96/dsp_0/gsw/rel_0/mcu_l1/release1.5/mod/emu/EMU_MCMP/eva3_drivers/source/SCCS/s.int.s
;
;   Sccs Id  (SID)      : '@(#) int.s 1.3 07/23/98 15:36:07 '
;/*************************************************************************/
;/*                                                                       */
;/*     Copyright (c) 1993 - 1996 Accelerated Technology, Inc.            */
;/*                                                                       */
;/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the      */
;/* subject matter of this material.  All manufacturing, reproduction,    */
;/* use, and sales rights pertaining to this subject matter are governed  */
;/* by the license agreement.  The recipient of this software implicitly  */
;/* accepts the terms of the license.                                     */
;/*                                                                       */
;/*************************************************************************/
;
;/*************************************************************************/
;/*                                                                       */
;/* FILE NAME                                            VERSION          */
;/*                                                                       */
;/*      int.s                                       PLUS/THUMB/T 1.3     */
;/*                                                                       */
;/* COMPONENT                                                             */
;/*                                                                       */
;/*      IN - Initialization                                              */
;/*                                                                       */
;/* DESCRIPTION                                                           */
;/*                                                                       */
;/*      This file contains the target processor dependent initialization */
;/*      routines and data.                                               */
;/*                                                                       */
;/* AUTHOR                                                                */
;/*                                                                       */
;/*      Barry Sellew, Accelerated Technology, Inc.                       */
;/*                                                                       */
;/* DATA STRUCTURES                                                       */
;/*                                                                       */
;/*      INT_Vectors                         Interrupt vector table       */
;/*                                                                       */
;/* FUNCTIONS                                                             */
;/*                                                                       */
;/*      INT_Initialize                      Target initialization        */
;/*      INT_Vectors_Loaded                  Returns a NU_TRUE if all the */
;/*                                            default vectors are loaded */
;/*      INT_Setup_Vector                    Sets up an actual vector     */
;/*                                                                       */
;/* DEPENDENCIES                                                          */
;/*                                                                       */
;/*      nucleus.h                           System constants             */ 
;/*                                                                       */ 
;/* HISTORY                                                               */
;/*                                                                       */
;/*         NAME            DATE                    REMARKS               */
;/*                                                                       */
;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
;/*	     B. Sellew	     01-22-1996	     Verified version 1.0	  	      */
;/*	     B. Sellew	     03-14-1996	     Modified to use the ROM          */
;/*				                          initialization method,          */
;/*	                                      resulting in version 1.1        */
;/*      B. Sellew       03-14-1996      Verified version 1.1             */
;/*      B. Sellew       02-06-1997      Created version 1.3              */
;/*	     B. Sellew	     02-06-1997	     Verified version 1.3	  	      */
;/*      M. Manning      06-02-1997      Added support for FIQ            */
;/*                                       interrupts. Bumped to 1.4       */
;/*      M. Manning      06-03-1997      Verified version 1.4             */
;/*                                                                       */
;/*************************************************************************/
;#define         NU_SOURCE_FILE
;
;#include        "nucleus.h"                 /* System constants          */
;
;
;/* Define constants used in low-level initialization.  */
;
;


  .if LONG_JUMP >= 3
        .global IND_CALL
        .global _f_load_int_mem
        .global _ResetVector
        
; Initialization for variable S_D_Mem
      	.sect	".cinit"
      	.align	4

; S_D_Mem is a UWORD32, See mem_load.c
;
      	.field  	4,32
      	.field  	_S_D_Mem+0,32
      	.field  	0,32		; _S_D_Mem @ 0

      	.sect	".text"
        .global _S_D_Mem
_S_D_Mem: .usect  "S_D_Mem",4,4
        .sym    _S_D_Mem,_S_D_Mem,14,2,32        ; For debug only


; Initialization for variable E_D_Mem

      	.sect	".cinit"
      	.align	4


; E_D_Mem is a UWORD32, See mem_load.c
;
      	.field  	4,32
      	.field  	_E_D_Mem+0,32
      	.field  	0,32		; _E_D_Mem @ 0

      	.sect	".text"
        .global _E_D_Mem
_E_D_Mem: .usect  "E_D_Mem",4,4
        .sym    _E_D_Mem,_E_D_Mem,14,2,32        ; For debug only

  .endif      ; (LONG_JUMP >= 3)
  
  .if CHIPSET == 12
        .global _f_load_int_mem
        .global _ResetVector
        .global _ResetVectorTestMode ; CALYPSO PLUS TEST MODE - TO BE ERASED
  .endif
  
LOCKOUT         .equ     00C0h              ; Interrupt lockout value
LOCK_MSK        .equ     00C0h              ; Interrupt lockout mask value
MODE_MASK       .equ     001Fh              ; Processor Mode Mask
SUP_MODE        .equ     0013h              ; Supervisor Mode (SVC)
IRQ_MODE        .equ     0012h              ; Interrupt Mode (IRQ)
FIQ_MODE        .equ     0011h              ; Fast Interrupt Mode (FIQ)
ABORT_MODE      .equ     0017h				; Abort Interrupt Mode
UNDEF_MODE      .equ     001Bh				; Undefined Interrupt Mode (should not happen)

IRQ_STACK_SIZE  .equ     128                ; Number of bytes in IRQ stack (must be align(8))
                                            ;   Note that the IRQ interrupt,
                                            ;   by default, is managed by 
                                            ;   Nucleus PLUS.  Only several
                                            ;   words are actually used.  The 
                                            ;   system stack is what will 
                                            ;   actually be used for Nuclues
                                            ;   PLUS managed IRQ interrupts.
FIQ_STACK_SIZE  .equ     512                ; Number of bytes in FIQ stack. (must be align(8))
                                            ;   This value is application 
                                            ;   specific.  By default, Nucleus
                                            ;   does not manage FIQ interrupts
                                            ;   and furthermore, leaves them
                                            ;   enabled virtually all the time.
SYSTEM_SIZE     .equ     1024               ; Define the system stack size (must be align(8))
TIMER_SIZE      .equ     1024               ; Define timer HISR stack size (must be align(8))
TIMER_PRIORITY  .equ     2                  ; Timer HISR priority (values from
    
  .if BOARD = 34
; Name                   value     offset   type      W/E W/S D/Cycles
CS0_CONFIG      .short   0x044F    ; 0     Flash 32    N   F   2
CS1_CONFIG      .short   0x02CF    ; 2     RAM   32    Y   F   1
CS2_CONFIG      .short   0x02CF    ; 4
CS3_CONFIG      .short   0x02CF    ; 6
CS7_CONFIG      .short   0x02C0    ; 8    Int-RAM 32   Y   0   1
CS5_CONFIG      .short   0x02CF    ; A                          
CS6_CONFIG      .short   0x02C0    ; C    Int-RAM 32   Y   0   1
RHEA_CONFIG     .short   0x002A    ; E   ARM -> RHEA/API adaptation
NUM_CS_REGS     .equ     8            ; number of Chip Select Config regs to program
  .endif
	                                        ;   0 to 2, where 0 is highest)

;
;/* End of low-level initialization constants.  */
;
;
;/* Define the initialization flag that indicates whether or not all of the
;   default vectors have been loaded during initialization.  */
;
;INT    INT_Loaded_Flag;

        .def    _INT_Loaded_Flag
        .bss    _INT_Loaded_Flag, 4, 4
;
;/* Define the vector table  */
;

  .if CHIPSET = 12
	        .sect ".start"

             .ref    _INT_Bootloader_Start

_ResetVector:
              B	_INT_Bootloader_Start

         .sect ".indint"
         
            .def  _IndirectVectorTable
_IndirectVectorTable:
                LDR   PC, [PC, #0x14]
                LDR   PC, [PC, #0x14]
                LDR   PC, [PC, #0x14]
                LDR   PC, [PC, #0x14]
                LDR   PC, [PC, #0x14]
                LDR   PC, [PC, #0x14]
                LDR   PC, [PC, #0x14]

                .word    INT_Undef_Inst
                .word    INT_Swi
                .word    INT_Abort_Prefetch
                .word    INT_Abort_Data
                .word    INT_Reserved
                .word    INT_IRQ
                .word    INT_FIQ

; CALYPSO PLUS TEST MODE - TO BE ERASED
	.sect ".intvecs"

_ResetVectorTestMode:
	B	_INT_Bootloader_Start
	B	INT_Undef_Inst
	B	INT_Swi
	B	INT_Abort_Prefetch
	B	INT_Abort_Data
	B	INT_Reserved
	B	INT_IRQ
	B	INT_FIQ

  .else ; CHIPSET = 12

	.sect ".intvecs"

  .if BOARD = 34
        B       _INT_Initialize
  .elseif BOARD = 35
        B       _INT_Initialize
  .else
        .ref    _INT_Bootloader_Start

	B	_INT_Bootloader_Start
  .endif
	B	INT_Undef_Inst
	B	INT_Swi
	B	INT_Abort_Prefetch
	B	INT_Abort_Data
	B	INT_Reserved
	B	Vect_IRQ
    .if WCP_PROF = 1
        .global    _PR_StoreMonteCarloSample

; Timing profiler using FIQ - Handle FIQ directly here

        STMFD    sp!,{R0-R4, LR}            ; Save R0-R4 and LR on FIQ stack

        MOV     R0, LR                      ; Retrieve link register in R0
        BL      _PR_StoreMonteCarloSample   ; Store into ring buffer
        BL      _IQ_FIQ_isr                 ; Ack FIQ

        LDMFD   sp!,{R0-R4, LR}             ; Restore R0-R4 and LR from FIQ stack
        SUBS    PC, LR, #4                  ; return from FIQ
    .else
	B	Vect_FIQ
    .endif
  .endif ; CHIPSET = 12

;
;	.text
;
;	.ref	cinit

	.sect       ".inttext"
	.global     cinit       ; Linker symbol for C variable init.


; Address definitions in the section where they are used.

;
;/* Define the global system stack variable.  This is setup by the 
;   initialization routine.  */
;
;extern VOID            *TCD_System_Stack;
;
        .ref  	_TCD_System_Stack
        .ref    _TCT_System_Limit
;
;
;/* Define the global data structures that need to be initialized by this
;   routine.  These structures are used to define the system timer management
;   HISR.  */
;   
;extern VOID     *TMD_HISR_Stack_Ptr;
;extern UNSIGNED  TMD_HISR_Stack_Size;
;extern INT       TMD_HISR_Priority;
;
        .ref  	_TMD_HISR_Stack_Ptr
        .ref  	_TMD_HISR_Stack_Size
        .ref  	_TMD_HISR_Priority
;
;
;/* Define extern function references.  */
;
;VOID   INC_Initialize(VOID *first_available_memory);
;VOID   TCT_Interrupt_Context_Save(VOID);
;VOID   TCT_Interrupt_Context_Restore(VOID);
;VOID   TCC_Dispatch_LISR(INT vector_number);
;VOID   TMT_Timer_Interrupt(void);
;
        .ref  	_INC_Initialize
        .ref  	_TCT_Interrupt_Context_Save
        .ref  	_TCT_Interrupt_Context_Restore
        .ref  	_TCC_Dispatch_LISR
        .ref  	_TMT_Timer_Interrupt

;/* Application ISR */
        .ref  	_IQ_IRQ_isr
        .ref  	_IQ_FIQ_isr
;
; /* Reference pointers defined by the linker */
;
	.ref	.bss
	.ref	end

  .if C155_TARGET = 1
	.def	INT_C155_Boot_Entry
INT_C155_Boot_Entry
	B	_INT_Initialize
  .endif

;
;/* Define indirect branching labels for the vector table  */
;

        .def    INT_Undef_Inst
INT_Undef_Inst
        B       arm_undefined               ; Undefined
;
        .def    INT_Swi
INT_Swi
        B       arm_swi                     ; Software Generated
;
        .def    INT_Abort_Prefetch
INT_Abort_Prefetch
        B		arm_abort_prefetch          ; Abort Prefetch
;
        .def    INT_Abort_Data
INT_Abort_Data
        B       arm_abort_data              ; Abort Data
;
        .def    INT_Reserved
INT_Reserved
        B       arm_reserved                ; Reserved
;
        .def    Vect_IRQ
Vect_IRQ
		.if TI_NUC_MONITOR = 1
        B       _INT_IRQ
        .else
        B       INT_IRQ
		.endif
;
        .def    Vect_FIQ
Vect_FIQ
		.if TI_PROFILER = 1
        B       _INT_FIQ
        .else
        B       INT_FIQ
		.endif
;

;
;/*************************************************************************/
;/*                                                                       */
;/* FUNCTION                                                              */
;/*                                                                       */
;/*      INT_Initialize                                                   */
;/*                                                                       */
;/* DESCRIPTION                                                           */
;/*                                                                       */
;/*      This function sets up the global system stack variable and       */
;/*      transfers control to the target independent initialization       */
;/*      function INC_Initialize.  Responsibilities of this function      */
;/*      include the following:                                           */
;/*                                                                       */
;/*             - Setup necessary processor/system control registers      */
;/*             - Initialize the vector table                             */
;/*             - Setup the system stack pointers                         */
;/*             - Setup the timer interrupt                               */
;/*             - Calculate the timer HISR stack and priority             */
;/*             - Calculate the first available memory address            */
;/*             - Transfer control to INC_Initialize to initialize all of */
;/*               the system components.                                  */
;/*                                                                       */
;/* AUTHOR                                                                */
;/*                                                                       */
;/*      Barry Sellew, Accelerated Technology, Inc.                       */
;/*                                                                       */
;/* CALLED BY                                                             */
;/*                                                                       */
;/*      none  					 			  */
;/*                                                                       */
;/* CALLS                                                                 */
;/*                                                                       */
;/*      INC_Initialize                      Common initialization        */
;/*                                                                       */
;/* INPUTS                                                                */
;/*                                                                       */
;/*      None                                                             */
;/*                                                                       */
;/* OUTPUTS                                                               */
;/*                                                                       */
;/*      None                                                             */
;/*                                                                       */
;/* HISTORY                                                               */
;/*                                                                       */
;/*         NAME            DATE                    REMARKS               */
;/*                                                                       */
;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
;/*	 B. Sellew	 01-22-1996	 Verified version 1.0	  	  */
;/*                                                                       */
;/*************************************************************************/
;VOID    INT_Initialize(void)
;{
	.def	_c_int00
_c_int00

	.include "init.asm"

addrCS0	      	.word	 0xfffffb00		    ; CS0 address space

    .if BOARD = 34
CSConfigTable   .long    CS0_CONFIG	
CS7_SIZE        .equ     0x2000       ; 8 kB
CS7_ADDR        .equ     0x03800000   ; initial address before toggling nIBOOT
SRAM_ADDR       .equ     0x03000000   ; Internal SRAM start address
SRAM_SIZE       .equ     0x00040000   ; 256kB 
EXTRA_CONF      .short   0x013E    ;     Boot configuration
DEF_EXTRA_CONF  .short   0x063E    ;     Default configuration
addrCS7         .word    0xFFFFFB08   ; CS7 configuration
addrExtraConf   .word    0xFFFFFB10   ; Extra configuration
armio_in        .word    0xFFFE4800   ; ARMIO_IN register address
armio_out       .word    0xFFFE4802   ; ARMIO_OUT register address
    .endif

    .if BOARD = 40 | 41
EX_MPU_CONF_REG .word    0xFFFEF006   ; Extended MPU configuration register address
EX_FLASH_VALUE  .short   0x0008       ; set bit to enable A22
    .endif

    .if CHIPSET = 4
CNTL_ARM_CLK_REG .word   0xFFFFFD00   ; CNTL_ARM_CLK register address
DPLL_CNTRL_REG   .word   0xFFFF9800   ; DPLL control register address
RHEA_CNTL_REG    .word   0xFFFFF900   ; RHEA control register address


CNTL_ARM_CLK_RST .short  0x1081	  ; Initialization of CNTL_ARM_CLK register
                                  ; Use DPLL, Divide by 1
DPLL_CONTROL_RST .short  0x2002   ; Configure DPLL in default state
RHEA_CONTROL_RST .short  0xFF22   ; Set access factor in order to access the DPLL register
                                  ; independently of the ARM clock
    .elseif CHIPSET = 6
CNTL_ARM_CLK_REG        .word  0xFFFFFD00   ; CNTL_ARM_CLK register address
CNTLCLK_26MHZ_SELECTOR  .short 0x0040       ; VTCXO_26 selector

    .elseif CHIPSET = 7
CNTL_ARM_CLK_REG  .word   0xFFFFFD00   ; CNTL_ARM_CLK register address
DPLL_CNTRL_REG    .word   0xFFFF9800   ; DPLL control register address
EXTRA_CONTROL_REG .word   0xFFFFFB10   ; Extra Control register CONF address
MPU_CTL_REG       .word   0xFFFFFF08   ; MPU_CTL register address

CNTL_ARM_CLK_RST  .short  0x1081       ; Initialization of CNTL_ARM_CLK register
                                       ; Use DPLL, Divide by 1
DPLL_CONTROL_RST  .short  0x2002       ; Configure DPLL in default state
DISABLE_DU_MASK   .short  0x0800       ; Mask to Disable the DU module
ENABLE_DU_MASK	  .short  0xF7FF       ; Mask to Enable the DU module
MPU_CTL_RST       .short  0x0000       ; Reset value of MPU_CTL register - All protections disabled

    .elseif CHIPSET = 8
CNTL_ARM_CLK_REG  .word   0xFFFFFD00   ; CNTL_ARM_CLK register address
DPLL_CNTRL_REG    .word   0xFFFF9800   ; DPLL control register address
EXTRA_CONTROL_REG .word   0xFFFFFB10   ; Extra Control register CONF address
MPU_CTL_REG       .word   0xFFFFFF08   ; MPU_CTL register address

CNTL_ARM_CLK_RST  .short  0x1081       ; Initialization of CNTL_ARM_CLK register
                                       ; Use DPLL, Divide by 1
DPLL_CONTROL_RST  .short  0x2002       ; Configure DPLL in default state
DISABLE_DU_MASK   .short  0x0800       ; Mask to Disable the DU module
ENABLE_DU_MASK	  .short  0xF7FF       ; Mask to Enable the DU module
MPU_CTL_RST       .short  0x0000       ; Reset value of MPU_CTL register - All protections disabled

    .elseif CHIPSET = 10
CNTL_ARM_CLK_REG  .word   0xFFFFFD00   ; CNTL_ARM_CLK register address
DPLL_CNTRL_REG    .word   0xFFFF9800   ; DPLL control register address
EXTRA_CONTROL_REG .word   0xFFFFFB10   ; Extra Control register CONF address
MPU_CTL_REG       .word   0xFFFFFF08   ; MPU_CTL register address

CNTL_ARM_CLK_RST  .short  0x1081       ; Initialization of CNTL_ARM_CLK register
                                       ; Use DPLL, Divide by 1
DPLL_CONTROL_RST  .short  0x2002       ; Configure DPLL in default state
DISABLE_DU_MASK   .short  0x0800       ; Mask to Disable the DU module
ENABLE_DU_MASK	  .short  0xF7FF       ; Mask to Enable the DU module
MPU_CTL_RST       .short  0x0000       ; Reset value of MPU_CTL register - All protections disabled

    .elseif CHIPSET = 11
CNTL_ARM_CLK_REG  .word   0xFFFFFD00   ; CNTL_ARM_CLK register address
DPLL_CNTRL_REG    .word   0xFFFF9800   ; DPLL control register address
EXTRA_CONTROL_REG .word   0xFFFFFB10   ; Extra Control register CONF address
MPU_CTL_REG       .word   0xFFFFFF08   ; MPU_CTL register address

CNTL_ARM_CLK_RST  .short  0x1081       ; Initialization of CNTL_ARM_CLK register
                                       ; Use DPLL, Divide by 1
DPLL_CONTROL_RST  .short  0x2002       ; Configure DPLL in default state
DISABLE_DU_MASK   .short  0x0800       ; Mask to Disable the DU module
ENABLE_DU_MASK	  .short  0xF7FF       ; Mask to Enable the DU module
MPU_CTL_RST       .short  0x0000       ; Reset value of MPU_CTL register - All protections disabled

    .elseif CHIPSET = 12
DBG_DMA_P2        .word   0xFFFEF02C   ; DBG_DMA_P2 register address    
CNTL_ARM_CLK_REG  .word   0xFFFFFD00   ; CNTL_ARM_CLK register address
DPLL_CNTRL_REG    .word   0xFFFF9800   ; DPLL control register address
EXTRA_CONTROL_REG .word   0xFFFFFB10   ; Extra Control register CONF address
MPU_CTL_REG       .word   0xFFFFFF08   ; MPU_CTL register address

CNTL_ARM_CLK_RST  .short  0x1081	     ; Initialization of CNTL_ARM_CLK register
                                       ; Use DPLL, Divide by 1
DPLL_CONTROL_RST  .short  0x2006       ; Configure DPLL in default state
DISABLE_DU_MASK   .short  0x0800       ; Mask to Disable the DU module
MPU_CTL_RST       .short  0x0000       ; Reset value of MPU_CTL register - All protections disabled
DBG_DMA_P2_RST    .short  0x0002       ; DBG_DMA_P2 register reset value
    .endif ; CHIPSET = 4 or 6 or 7 or 8 or 10 or 11 or 12


c_cinit	.long	cinit

        .def  	_INT_Initialize
_INT_Initialize

;
;  Configuration of ARM clock and DPLL frequency
;
    .if CHIPSET = 4
;
;  Configure RHEA access factor in order to allow the access of DPLL register
;
       ldr     r1,RHEA_CNTL_REG      ; Load address of RHEA control register in R1
       ldrh    r2,RHEA_CONTROL_RST   ; Load RHEA configuration value in R2
       strh    r2,[r1]               ; Store DPLL reset value in RHEA control register
  
;
;  Configure DPLL register with reset value
;
       ldr     r1,DPLL_CNTRL_REG     ; Load address of DPLL register in R1
       ldrh    r2,DPLL_CONTROL_RST   ; Load DPLL reset value in R2
       strh    r2,[r1]               ; Store DPLL reset value in DPLL register

;
; Wait that DPLL goes in BYPASS mode
;
Wait_DPLL_Bypass
       ldr     r2,[r1]               ; Load DPLL register
       and     r2,r2,#1              ; Perform a mask on bit 0
       cmp     r2,#1                 ; Compare DPLL lock bit
       beq     Wait_DPLL_Bypass      ; Wait Bypass mode (i.e. bit[0]='0')

;
;  Configure CNTL_ARM_CLK register with reset value: DPLL is used to
;  generate ARM clock with division factor of 1.
;
       ldr     r1,CNTL_ARM_CLK_REG  ; Load address of CNTL_ARM_CLK register in R1
       ldrh    r2,CNTL_ARM_CLK_RST  ; Load CNTL_ARM_CLK reset value in R2
       strh    r2,[r1]              ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register

    .elseif CHIPSET = 6

;
;  Set VTCXO_26MHZ bit to '1' in case of the VTCXO clock is 26MHz instead
;  of 13MHz.
;
       ldr     r1, CNTL_ARM_CLK_REG       ; Load CLKM base register address in R1
       ldrh    r2, [r1,#2]                ; Load contents of CNTL_CLK register in R2
       ldr     r0, CNTLCLK_26MHZ_SELECTOR ; Load configuration of 26MHz selector
       orr     r0, r0, r2;
       strh    r0, [r1,#2];

; Wait a while until clock is stable (required for AvengerII)
        mov     r0,#0x100
WaitAWhile1:
        sub     r0, r0, #1
        cmp     r0, #0
        bne     WaitAWhile1

    .elseif CHIPSET = 7
;
;  Configure DPLL register with reset value
;
       ldr     r1,DPLL_CNTRL_REG     ; Load address of DPLL register in R1
       ldrh    r2,DPLL_CONTROL_RST   ; Load DPLL reset value in R2
       strh    r2,[r1]               ; Store DPLL reset value in DPLL register

;
;  Wait that DPLL goes in BYPASS mode
;
Wait_DPLL_Bypass
       ldr     r2,[r1]               ; Load DPLL register
       and     r2,r2,#1              ; Perform a mask on bit 0
       cmp     r2,#1                 ; Compare DPLL lock bit
       beq     Wait_DPLL_Bypass      ; Wait Bypass mode (i.e. bit[0]='0')

;
;  Configure CNTL_ARM_CLK register with reset value: DPLL is used to
;  generate ARM clock with division factor of 1.
;
       ldr     r1,CNTL_ARM_CLK_REG  ; Load address of CNTL_ARM_CLK register in R1
       ldrh    r2,CNTL_ARM_CLK_RST  ; Load CNTL_ARM_CLK reset value in R2
       strh    r2,[r1]              ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
  
;
;  Disable/Enable the DU module by setting/resetting bit 11 to '1'/'0'
;
       ldr     r1,EXTRA_CONTROL_REG ; Load address of Extra Control register CONF
       ;ldrh    r2,DISABLE_DU_MASK   ; Load mask to write in Extra Control register CONF
       ldrh    r2,ENABLE_DU_MASK    ; Load mask to write in Extra Control register CONF
       ldrh    r0,[r1]              ; Load Extra Control register CONF in r0
       ;orr     r0,r0,r2             ; Disable DU module
       and     r0,r0,r2             ; Enable DU module
       strh    r0,[r1]              ; Store configuration in Extra Control register CONF
  
;
;  Disable all MPU protections
;
       ldr     r1,MPU_CTL_REG       ; Load address of MPU_CTL register
       ldrh    r2,MPU_CTL_RST       ; Load reset value of MPU_CTL register
       strh    r2,[r1]              ; Store reset value of MPU_CTL register

    .elseif CHIPSET = 8
;
;  Configure DPLL register with reset value
;
       ldr     r1,DPLL_CNTRL_REG     ; Load address of DPLL register in R1
       ldrh    r2,DPLL_CONTROL_RST   ; Load DPLL reset value in R2
       strh    r2,[r1]               ; Store DPLL reset value in DPLL register

;
;  Wait that DPLL goes in BYPASS mode
;
Wait_DPLL_Bypass
       ldr     r2,[r1]               ; Load DPLL register
       and     r2,r2,#1              ; Perform a mask on bit 0
       cmp     r2,#1                 ; Compare DPLL lock bit
       beq     Wait_DPLL_Bypass      ; Wait Bypass mode (i.e. bit[0]='0')

;
;  Configure CNTL_ARM_CLK register with reset value: DPLL is used to
;  generate ARM clock with division factor of 1.
;
       ldr     r1,CNTL_ARM_CLK_REG  ; Load address of CNTL_ARM_CLK register in R1
       ldrh    r2,CNTL_ARM_CLK_RST  ; Load CNTL_ARM_CLK reset value in R2
       strh    r2,[r1]              ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
  
;
;  Disable/Enable the DU module by setting/resetting bit 11 to '1'/'0'
;
       ldr     r1,EXTRA_CONTROL_REG ; Load address of Extra Control register CONF
       ;ldrh    r2,DISABLE_DU_MASK   ; Load mask to write in Extra Control register CONF
       ldrh    r2,ENABLE_DU_MASK    ; Load mask to write in Extra Control register CONF
       ldrh    r0,[r1]              ; Load Extra Control register CONF in r0
       ;orr     r0,r0,r2             ; Disable DU module
       and     r0,r0,r2             ; Enable DU module
       strh    r0,[r1]              ; Store configuration in Extra Control register CONF
  
;
;  Disable all MPU protections
;
       ldr     r1,MPU_CTL_REG       ; Load address of MPU_CTL register
       ldrh    r2,MPU_CTL_RST       ; Load reset value of MPU_CTL register
       strh    r2,[r1]              ; Store reset value of MPU_CTL register

    .elseif CHIPSET = 10
;
;  Configure DPLL register with reset value
;
       ldr     r1,DPLL_CNTRL_REG     ; Load address of DPLL register in R1
       ldrh    r2,DPLL_CONTROL_RST   ; Load DPLL reset value in R2
       strh    r2,[r1]               ; Store DPLL reset value in DPLL register

;
;  Wait that DPLL goes in BYPASS mode
;
Wait_DPLL_Bypass
       ldr     r2,[r1]               ; Load DPLL register
       and     r2,r2,#1              ; Perform a mask on bit 0
       cmp     r2,#1                 ; Compare DPLL lock bit
       beq     Wait_DPLL_Bypass      ; Wait Bypass mode (i.e. bit[0]='0')

;
;  Configure CNTL_ARM_CLK register with reset value: DPLL is used to
;  generate ARM clock with division factor of 1.
;
       ldr     r1,CNTL_ARM_CLK_REG  ; Load address of CNTL_ARM_CLK register in R1
       ldrh    r2,CNTL_ARM_CLK_RST  ; Load CNTL_ARM_CLK reset value in R2
       strh    r2,[r1]              ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
  
;
;  Disable/Enable the DU module by setting/resetting bit 11 to '1'/'0'
;
       ldr     r1,EXTRA_CONTROL_REG ; Load address of Extra Control register CONF
       ;ldrh    r2,DISABLE_DU_MASK   ; Load mask to write in Extra Control register CONF
       ldrh    r2,ENABLE_DU_MASK    ; Load mask to write in Extra Control register CONF
       ldrh    r0,[r1]              ; Load Extra Control register CONF in r0
       ;orr     r0,r0,r2             ; Disable DU module
       and     r0,r0,r2             ; Enable DU module
       strh    r0,[r1]              ; Store configuration in Extra Control register CONF
  
;
;  Disable all MPU protections
;
       ldr     r1,MPU_CTL_REG       ; Load address of MPU_CTL register
       ldrh    r2,MPU_CTL_RST       ; Load reset value of MPU_CTL register
       strh    r2,[r1]              ; Store reset value of MPU_CTL register

    .elseif CHIPSET = 11
;
;  Configure DPLL register with reset value
;
       ldr     r1,DPLL_CNTRL_REG     ; Load address of DPLL register in R1
       ldrh    r2,DPLL_CONTROL_RST   ; Load DPLL reset value in R2
       strh    r2,[r1]               ; Store DPLL reset value in DPLL register

;
;  Wait that DPLL goes in BYPASS mode
;
Wait_DPLL_Bypass
       ldr     r2,[r1]               ; Load DPLL register
       and     r2,r2,#1              ; Perform a mask on bit 0
       cmp     r2,#1                 ; Compare DPLL lock bit
       beq     Wait_DPLL_Bypass      ; Wait Bypass mode (i.e. bit[0]='0')

;
;  Configure CNTL_ARM_CLK register with reset value: DPLL is used to
;  generate ARM clock with division factor of 1.
;
       ldr     r1,CNTL_ARM_CLK_REG  ; Load address of CNTL_ARM_CLK register in R1
       ldrh    r2,CNTL_ARM_CLK_RST  ; Load CNTL_ARM_CLK reset value in R2
       strh    r2,[r1]              ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
  
;
;  Disable/Enable the DU module by setting/resetting bit 11 to '1'/'0'
;
       ldr     r1,EXTRA_CONTROL_REG ; Load address of Extra Control register CONF
       ;ldrh    r2,DISABLE_DU_MASK   ; Load mask to write in Extra Control register CONF
       ldrh    r2,ENABLE_DU_MASK    ; Load mask to write in Extra Control register CONF
       ldrh    r0,[r1]              ; Load Extra Control register CONF in r0
       ;orr     r0,r0,r2             ; Disable DU module
       and     r0,r0,r2             ; Enable DU module
       strh    r0,[r1]              ; Store configuration in Extra Control register CONF
  
;
;  Disable all MPU protections
;
       ldr     r1,MPU_CTL_REG       ; Load address of MPU_CTL register
       ldrh    r2,MPU_CTL_RST       ; Load reset value of MPU_CTL register
       strh    r2,[r1]              ; Store reset value of MPU_CTL register

    .elseif CHIPSET = 12
  
  .if BOARD = 6
  ; Configure DBG_DMA_P2 reg => GPO_2 output pin for EVA4
  ldr	r1,DBG_DMA_P2         ; Load address of DBG_DMA_P2 register in R1
  ldrh	r2,DBG_DMA_P2_RST     ; Load DBG_DMA_P2 reset value in R2
  strh	r2,[r1]               ; Store reset value in register
  ;
  .endif ; BOARD = 6

  ;
  ;  Configure DPLL register with reset value
  ;
	ldr	  r1,DPLL_CNTRL_REG     ; Load address of DPLL register in R1
	ldrh	r2,DPLL_CONTROL_RST   ; Load DPLL reset value in R2
	strh	r2,[r1]               ; Store DPLL reset value in DPLL register

;
;  Wait that DPLL goes in BYPASS mode
;
Wait_DPLL_Bypass
  ldr   r2,[r1]               ; Load DPLL register
  and   r2,r2,#1              ; Perform a mask on bit 0
  cmp   r2,#1                 ; Compare DPLL lock bit
  beq   Wait_DPLL_Bypass      ; Wait Bypass mode (i.e. bit[0]='0')

  ;
  ;  Configure CNTL_ARM_CLK register with reset value: DPLL is used to
  ;  generate ARM clock with division factor of 1.
  ;
	ldr	  r1,CNTL_ARM_CLK_REG  ; Load address of CNTL_ARM_CLK register in R1
	ldrh	r2,CNTL_ARM_CLK_RST  ; Load CNTL_ARM_CLK reset value in R2
	strh	r2,[r1]              ; Store CNTL_ARM_CLK reset value in CNTL_ARM_CLK register
  
;
;  Disable the DU module by setting bit 11 to '1'
;
;  ldr   r1,EXTRA_CONTROL_REG ; Load address of Extra Control register CONF
;  ldrh  r2,DISABLE_DU_MASK   ; Load mask to write in Extra Control register CONF
;  ldrh  r0,[r1]              ; Load Extra Control register CONF in r0
;  orr   r0,r0,r2             ; Disable DU module
;  strh  r0,[r1]              ; Store configuration in Extra Control register CONF
  
  ;
  ;  Disable all MPU protections
  ;
  ldr   r1,MPU_CTL_REG       ; Load address of MPU_CTL register
  ldrh  r2,MPU_CTL_RST       ; Load reset value of MPU_CTL register
  strh  r2,[r1]              ; Store reset value of MPU_CTL register

    .endif ; CHIPSET = 4 or 6 or 7 or 8 or 10 or 11 or 12

;
;  Wait-state configuration of external and internal memories
;
    .if BOARD = 34
;
;       Wait states for Perseus - see IQ_InitWaitStates for details
;


        mov     r0, #NUM_CS_REGS        ; number of chip selects to configure
        ldr     r1, addrCS0             ; first CS register
        ldr     r2, CSConfigTable       ; table of values to program
        
ConfigCS:          
        ldrh    r3,[r2]
        strh    r3,[r1]
        add     r1, r1, #2
        add     r2, r2, #2
        sub     r0, r0, #1
        cmp     r0, #0
        bne     ConfigCS

        bl    Ensure_external_access
        bl    Copy_code_into_CS7
        bl    Toggle_nIBoot

; Wait a while - not quite sure why, but it is required for Avenger II
        mov     r0,#0x100
WaitAWhile2:
        sub     r0, r0, #1
        cmp     r0, #0
        bne     WaitAWhile2

        bl    Clear_Internal_SRAM       ; This is required if the BSS is not in SRAM

    .elseif BOARD = 35

        ldr    r1,addrCS0
        ldrh   r2,CS0_MEM_REG           ; CS0 initialization
        strh   r2,[r1]
        ldrh   r2,CS1_MEM_REG           ; CS1 initialization
        strh   r2,[r1,#0x2]
        ldrh   r2,CS2_MEM_REG           ; CS2 initialization
        strh   r2,[r1,#0x4]
        ldrh   r2,CS7_MEM_REG           ; CS7 initialization
        strh   r2,[r1,#0x8]
        ldrh   r2,CS6_MEM_REG           ; CS6 initialization
        strh   r2,[r1,#0xC]
        mov    r2,#API_ADAPT            ; API-RHEA configuration
        strh   r2,[r1,#0xE]

        bl    Ensure_external_access
        bl    Copy_code_into_CS7
        bl    Toggle_nIBoot
        bl    Clear_Internal_SRAM       ; This is required if the BSS is not in SRAM

    .else

       ldr     r1,addrCS0
  .if CHIPSET != 12
       ldrh    r2,CS0_MEM_REG			    ; ROM initialization
       strh    r2,[r1]                      ; CS0

       ldrh    r2,CS1_MEM_REG               ; RAM Initialization
       strh    r2,[r1,#2]		            ; CS1

       ldrh    r2,CS2_MEM_REG               ; RAM Initialization
       strh    r2,[r1,#4]		            ; CS2

       ldrh    r2,CS3_MEM_REG               ; Parallel I/O on B-Sample
       strh    r2,[r1,#6]                   ; CS3 (unused on EVA4?)

       ldrh    r2,CS4_MEM_REG               ; Latch on B-Sample
       strh    r2,[r1,#0xa]                 ; CS4 (unused on EVA4)

  .else

  ldrh  r2,CS0_MEM_REG  ; CALYPSO PLUS TEST MODE - TO BE ERASED - FLASH Initialization
  strh  r2,[r1,#0x0]    ; CS0

  ldrh  r2,CS5_MEM_REG  ; FLASH Initialization
  strh  r2,[r1,#0xA]    ; CS5

  ldrh  r2,CS4_MEM_REG  ; RAM Initialization
  strh  r2,[r1,#0x8]    ; CS4

  .endif

    .if CHIPSET = 3
       ldrh    r2,CS6_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0xc]		            ; CS6 Internal RAM

    .elseif CHIPSET = 4
       ldrh    r2,CS6_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0xc]	               	; CS6 Internal RAM
        
       ldrh    r2,CS7_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0x8]	               	; CS7 Internal Boot RAM

    .elseif CHIPSET = 5
       ldrh    r2,CS6_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0xc]		            ; CS6 Internal RAM

    .elseif CHIPSET = 6
       ldrh    r2,CS6_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0xc]		            ; CS6 Internal RAM

    .elseif CHIPSET = 7
       ldrh    r2,CS6_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0xc]		            ; CS6 Internal RAM
  
       ldrh    r2,CS7_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0x8]		            ; CS7 Internal Boot ROM

    .elseif CHIPSET = 8
       ldrh    r2,CS6_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0xc]		            ; CS6 Internal RAM
  
       ldrh    r2,CS7_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0x8]		            ; CS7 Internal Boot ROM

    .elseif CHIPSET = 10
       ldrh    r2,CS6_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0xc]		            ; CS6 Internal RAM
  
       ldrh    r2,CS7_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0x8]		            ; CS7 Internal Boot ROM

    .elseif CHIPSET = 11
       ldrh    r2,CS6_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0xc]		            ; CS6 Internal RAM
  
       ldrh    r2,CS7_MEM_REG               ; Internal SRAM initialization
       strh    r2,[r1,#0x8]		            ; CS7 Internal Boot ROM
    .endif ; CHIPSET = 3 or 4 or 5 or 6 or 7 or 8 or 10 or 11

       ldrh    r2,CTL_MEM_REG               ; API-RHEA configuration
       strh    r2,[r1,#0xe]

    .endif ; BOARD = 34 | 35

    .if BOARD = 40 | 41
;    /* On D-Sample Board, use A22 mode (ADD(22) instead of CS4) to be able to
;       address 8 Mbytes especially with CS0 (Flash) & CS3 (External Peripherals) */
       ldr     r1,EX_MPU_CONF_REG
       ldrh    r2,[r1]
       ldr     r0,EX_FLASH_VALUE
       orr     r0, r0, r2
       strh    r0,[r1]
    .endif

;
;    /* Insure that the processor is in supervisor mode.  */
;
        MRS     a1,CPSR                     ; Pickup current CPSR
        BIC     a1,a1,#MODE_MASK            ; Clear the mode bits
        ORR     a1,a1,#SUP_MODE             ; Set the supervisor mode bits
        ORR     a1,a1,#LOCKOUT              ; Insure IRQ and FIQ interrupts are
                                            ;   locked out
        MSR     CPSR,a1                     ; Setup the new CPSR
;

;
;
; REWORK OF .bss INITIALIZATION - start
; Creation of INT_memset and INT_memcpy, respectively identical to memset and 
; memcpy from the rts library of compiler V2.51/2.54.
; They are used to make the initialization of the .bss section and the load 
; of the internal ram code not dependent to the 32-bit alignment.
; The old code used for the initialization and the load used a loop with
; 4-byte increment, assuming the 32-bit alignment of the .bss section.
; This alignment is not necessary true.
;
;    /* Clear the un-initialized global and static C data areas.  */
;       Initialize the system stack pointer a first time to allow use of memset function
;       which needs stack.
;       The system stack pointers will be fully initialized after having cleared
;       the BSS area.  */
;        
        LDR     a1,StackSegment             ; Pickup the begining address from .cmd file
                                            ;   (is aligned on 8 byte boundary)

        MOV     a2,#SYSTEM_SIZE             ; Pickup system stack size
        SUB     a2,a2,#4                    ; Subtract one word for first addr
        ADD     a3,a1,a2                    ; Build start of system stack area

        MOV     sp,a3                       ; Setup initial stack pointer

        STMFD   sp!,{a1-a4}               ; Save a1-a4 registers to stack

        LDR     a1,BSS_Start              ; Pickup the start of the BSS area
        LDR     a3,BSS_End                ; Pickup the end of the BSS area
        SUB     a3,a3,a1                  ; Calculate size of the BSS area
        MOV     a2,#0                     ; Clear value in a2

        BL      _INT_memset                   ; Clear the BSS area using memset function

  .if LONG_JUMP >= 3                      ;
        LDR     a1,BSS_IntMem_Start       ; Pickup the start of the BSS area
        LDR     a3,BSS_IntMem_End         ; Pickup the end of the BSS area
        SUB     a3,a3,a1                  ; Calculate size of the BSS area
        MOV     a2,#0                     ; Clear value in a2

        BL      _INT_memset               ; Clear the BSS area using memset function

  .endif

        LDMFD   sp!,{a1-a4}               ; Restore a1-a4 registers from stack

; REWORK OF .bss INITIALIZATION - end  

;
;    /* Setup the vectors loaded flag to indicate to other routines in the 
;       system whether or not all of the default vectors have been loaded. 
;       If INT_Loaded_Flag is 1, all of the default vectors have been loaded.
;       Otherwise, if INT_Loaded_Flag is 0, registering an LISR cause the
;       default vector to be loaded.  In the THUMB this variable is always
;       set to 1.  All vectors must be setup by this function.  */
;    INT_Loaded_Flag =  0;
;
        MOV     a1,#1                       ; All vectors are assumed loaded
        LDR     a2,Loaded_Flag   	        ; Build address of loaded flag  
        STR     a1,[a2,#0]                  ; Initialize loaded flag
;
;    /* Initialize the system stack pointers.  This is done after the BSS is
;       cleared because the TCD_System_Stack pointer is a BSS variable!  It is
;       assumed that the .cmd file is written to direct where these stacks should
;       be allocated and to align them on double word boundaries.
;
        LDR     a1,StackSegment             ; Pickup the begining address from .cmd file
                                            ;   (is aligned on 8 byte boundary)
        MOV     a2,#SYSTEM_SIZE             ; Pickup system stack size
        SUB     a2,a2,#4                    ; Subtract one word for first addr
        ADD     a3,a1,a2                    ; Build start of system stack area
        MOV     v7,a1                       ; Setup initial stack limit
        LDR     a4,System_Limit             ; Pickup system stack limit address
        STR     v7,[a4, #0]                 ; Save stack limit
        MOV     sp,a3                       ; Setup initial stack pointer
        LDR     a4,System_Stack             ; Pickup system stack address
        STR     sp,[a4, #0]                 ; Save stack pointer
        MOV     a2,#IRQ_STACK_SIZE          ; Pickup IRQ stack size in bytes
        ADD     a3,a3,a2                    ; Allocate IRQ stack area
        MRS     a1,CPSR                     ; Pickup current CPSR
        BIC     a1,a1,#MODE_MASK            ; Clear the mode bits
        ORR     a1,a1,#IRQ_MODE             ; Set the IRQ mode bits
        MSR     CPSR,a1                     ; Move to IRQ mode
        MOV     sp,a3                       ; Setup IRQ stack pointer
        MOV     a2,#FIQ_STACK_SIZE          ; Pickup FIQ stack size in bytes
        ADD     a3,a3,a2                    ; Allocate FIQ stack area
        MRS     a1,CPSR                     ; Pickup current CPSR
        BIC     a1,a1,#MODE_MASK            ; Clear the mode bits
        ORR     a1,a1,#FIQ_MODE             ; Set the FIQ mode bits
        MSR     CPSR,a1                     ; Move to the FIQ mode
        MOV     sp,a3                       ; Setup FIQ stack pointer

        MRS     a1,CPSR                     ; Pickup current CPSR
        BIC     a1,a1,#MODE_MASK            ; Clear the mode bits
        ORR     a1,a1,#ABORT_MODE           ; Set the Abort mode bits
        MSR     CPSR,a1                     ; Move to the Abort mode
        LDR     sp,Exception_Stack          ; Setup Abort stack pointer

        MRS     a1,CPSR                     ; Pickup current CPSR
        BIC     a1,a1,#MODE_MASK            ; Clear the mode bits
        ORR     a1,a1,#UNDEF_MODE           ; Set the Undefined mode bits
        MSR     CPSR,a1                     ; Move to the Undefined mode
        LDR     sp,Exception_Stack          ; Setup Undefined stack pointer
                                            ;   (should never be used)

; go to Supervisor Mode
        MRS     a1,CPSR                     ; Pickup current CPSR
        BIC     a1,a1,#MODE_MASK            ; Clear mode bits
        ORR     a1,a1,#SUP_MODE             ; Set the supervisor mode bits
        MSR     CPSR,a1                     ; All interrupt stacks are setup,
                                            ;   return to supervisor mode
;
;    /* Define the global data structures that need to be initialized by this
;       routine.  These structures are used to define the system timer 
;       management HISR.  */
;    TMD_HISR_Stack_Ptr =        (VOID *) a3;
;    TMD_HISR_Stack_Size =       TIMER_SIZE;
;    TMD_HISR_Priority =         TIMER_PRIORITY;
;
; TMD_HISR_Stack_Ptr points at the top (the lowest address) of the allocated
; area. The Timer HISR (called "SYSTEM H") and its related stack will be created
; in TMI_Initialize(). The current stack pointer will be set at the bottom (the
; lowest address) of the expected area.

        LDR     a4,HISR_Stack_Ptr  	        ; Pickup variable's address
        ADD     a3,a3,#4                    ; Increment to next available word
        STR     a3,[a4, #0]                 ; Setup timer HISR stack pointer
        MOV     a2,#TIMER_SIZE              ; Pickup the timer HISR stack size
        BIC     a2,a2,#3                    ; Insure word alignment
        ADD     a3,a3,a2                    ; Allocate the timer HISR stack 
                                            ;   from available memory
        LDR     a4,HISR_Stack_Size    	    ; Pickup variable's address
        STR     a2,[a4, #0]                 ; Setup timer HISR stack size
        MOV     a2,#TIMER_PRIORITY          ; Pickup timer HISR priority (0-2)
        LDR     a4,HISR_Priority            ; Pickup variable's address
        STR     a2,[a4, #0]                 ; Setup timer HISR priority

  .if CHIPSET = 12
      ; This sequence must be always done in order to download the interrupt
      ; vector remapping
        MOV     V1, a3                      ; Save a3 register
        BL      _f_load_int_mem             ; Download FLASH to Internal RAM
        MOV     a3, V1                      ; Restore a3 register
  .else

  .if LONG_JUMP >= 3
        MOV     V1, a3                      ; Save a3 register
        BL      _f_load_int_mem             ; Download FLASH to Internal RAM
        MOV     a3, V1                      ; Restore a3 register
  .endif

  .endif ; CHIPSET != 12

; We now fill up the System, IRQ, FIQ and System Timer HISR stacks with 0xFE for
; checking the status of the stacks later. 
; inputs:
;     a3 still has the bottom of all four stacks and is aligned. 
; algorithm:
;     We start from the top of all four stacks (*System_Limit), which is
;     necessarily aligned.  We store 0xFEFEFEFE until we have filled the
;     bottom of the fourth stack
; outputs:
;     memory has 0xFE on all four stacks: System, FIQ, IRQ and System Timer HISR
;     a3 still has the bottom of all four stacks

        LDR     a2,System_Limit             ; pickup system stack limit address
        LDR     a1,[a2]                     ; a1 = StackSegment
        MOV     a4,#0FEh                    ; use this and the next 7 instructons to set a4 = 0xFEFEFEFE
        STRB    a4,[a1, #0]
        STRB    a4,[a1, #1]
        STRB    a4,[a1, #2]
        STRB    a4,[a1, #3]
        LDR     a4,[a1],#4                  ; stored first word, move to second

fill_stack:
        STR     a4,[a1],#4                  ; store a word and increment by four
        CMP     a1,a3                       ; is this the last address?
        BLT     fill_stack                  ; if not, loop back

;
;       Perform auto-initialization.  if cinit is -1, then there is none.
;
        LDR     r0, c_cinit
        CMN     r0, #1
        BLNE    _auto_init
;
;     /* Call INC_Initialize with a pointer to the first available memory 
;        address after the compiler's global data.  This memory may be used
;        by the application.  */
;     INC_Initialize(first_available_memory);
;
        MOV     a1,a3                       ; Pass the first available memory
	B       _INC_Initialize		        ; to high-level initialization
;}
;


  .if  BOARD=35 | BOARD=34

;/*
; * FUNCTION
; *
; *      Ensure_external_access
; */
Ensure_external_access: 
        ;AI_ResetBit(4);             // request shared mem clock
        ldr    r1, armio_out
        ldrh   r2, [r1]
        bic    r2, r2, #0x10
        strh   r2, [r1]

        ;while(AI_ReadBit(5)!=1);    // wait for acknowledge
ack:
        ldr     r1, armio_in
        ldrh    r2, [r1]
        and     r2, r2, #0x20
        cmp     r2, #0x20
        bne     ack  
        bx      lr                      ; Return to caller

;/*
; * FUNCTION
; *
; *      Copy_code_into_CS7
; */
Copy_code_into_CS7:
        ldr     r1, addrExtraConf
        ldr     r3, DEF_EXTRA_CONF
        strh    r3, [r1]                ; ensure CS7 selects internal memory

        mov     r0, #CS7_SIZE           ; size of CS7 memory in bytes
        mov     r1, #CS7_ADDR           ; destination
        mov     r2, #0                  ; source
CopyIntCode:          
        ldr     r3,[r2]
        str     r3,[r1]
        add     r1, r1, #4
        add     r2, r2, #4
        sub     r0, r0, #4
        cmp     r0, #0
        bne     CopyIntCode

        ldr     r1, addrCS7
        ldr     r2, [r1]
        bic     r2, r2, #0x80           ; Write Enable OFF on CS7
        strh    r2, [r1]
        bx      lr                      ; Return to caller

;/*
; * FUNCTION
; *
; *      Toggle_nIBoot
; */
Toggle_nIBoot:                                                                       
        ldr     r1, addrExtraConf       ; Address of Extra Conf Register
        ldr     r3, EXTRA_CONF          ; set CS7 at address zero
        strh    r3, [r1]
        bx      lr                      ; Return to caller

;/*
; * FUNCTION
; *
; *      Clear_Internal_SRAM
; */
Clear_Internal_SRAM:
        mov     r0, #SRAM_ADDR          ; r0 points to SRAM start
        mov     r1, #SRAM_SIZE
        add     r1, r0, r1              ; r1 points to SRAM end
        mov     r2, #0

ClearSram:
        str     r2,[r0], #4
        cmp     r0, r1                  ; done?
        bne     ClearSram               ; no - loop
        bx      lr                      ; Return to caller

  .endif ; BOARD=34 | BOARD=35

;
;/*************************************************************************/
;/*                                                                       */
;/* FUNCTION                                                              */
;/*                                                                       */
;/*      INT_Vectors_Loaded                                               */
;/*                                                                       */
;/* DESCRIPTION                                                           */
;/*                                                                       */
;/*      This function returns the flag that indicates whether or not     */
;/*      all the default vectors have been loaded.  If it is false,       */
;/*      each LISR register also loads the ISR shell into the actual      */
;/*      vector table.                                                    */
;/*                                                                       */
;/* AUTHOR                                                                */
;/*                                                                       */
;/*      Barry Sellew, Accelerated Technology, Inc.                       */
;/*                                                                       */
;/* CALLED BY                                                             */
;/*                                                                       */
;/*      TCC_Register_LISR                   Register LISR for vector     */
;/*                                                                       */
;/* CALLS                                                                 */
;/*                                                                       */
;/*      None                                                             */
;/*                                                                       */
;/* INPUTS                                                                */
;/*                                                                       */
;/*      None                                                             */
;/*                                                                       */
;/* OUTPUTS                                                               */
;/*                                                                       */
;/*      None                                                             */
;/*                                                                       */
;/* HISTORY                                                               */
;/*                                                                       */
;/*         NAME            DATE                    REMARKS               */
;/*                                                                       */
;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
;/*	 B. Sellew	 01-22-1996	 Verified version 1.0	  	  */
;/*                                                                       */
;/*************************************************************************/
;INT    INT_Vectors_Loaded(void)
;{
	.def	$INT_Vectors_Loaded
$INT_Vectors_Loaded			    ; Dual-state interworking veneer
	.state16
	BX	pc
	NOP
	.state32
	B	_INT_Vectors_Loaded
;
        .def    _INT_Vectors_Loaded
_INT_Vectors_Loaded
;
;    /* Just return the loaded vectors flag.  */
;    return(INT_Loaded_Flag);
;
        MOV     a1,#1                       ; Always return TRUE since there 
                                            ;   are really only two normal 
                                            ;   vectors IRQ & FIQ
        BX      lr                          ; Return to caller
;}
;
;
;/*************************************************************************/
;/*                                                                       */
;/* FUNCTION                                                              */
;/*                                                                       */
;/*      INT_Setup_Vector                                                 */
;/*                                                                       */
;/* DESCRIPTION                                                           */
;/*                                                                       */
;/*      This function sets up the specified vector with the new vector   */
;/*      value.  The previous vector value is returned to the caller.     */
;/*                                                                       */
;/* AUTHOR                                                                */
;/*                                                                       */
;/*      Barry Sellew, Accelerated Technology, Inc.                       */
;/*                                                                       */
;/* CALLED BY                                                             */
;/*                                                                       */
;/*      Application                                                      */
;/*      TCC_Register_LISR                   Register LISR for vector     */
;/*                                                                       */
;/* CALLS                                                                 */
;/*                                                                       */
;/*      None                                                             */
;/*                                                                       */
;/* INPUTS                                                                */
;/*                                                                       */
;/*      vector                              Vector number to setup       */
;/*      new                                 Pointer to new assembly      */
;/*                                            language ISR               */
;/*                                                                       */
;/* OUTPUTS                                                               */
;/*                                                                       */
;/*      old vector contents                                              */
;/*                                                                       */
;/* HISTORY                                                               */
;/*                                                                       */
;/*         NAME            DATE                    REMARKS               */
;/*                                                                       */
;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
;/*	 B. Sellew	 01-22-1996	 Verified version 1.0	  	  */
;/*                                                                       */
;/*************************************************************************/
;VOID  *INT_Setup_Vector(INT vector, VOID *new)
;{
	.def	$INT_Setup_Vector
$INT_Setup_Vector			    ; Dual-state interworking veneer
	.state16
	BX	pc
	NOP
	.state32
	B	_INT_Setup_Vector
;
        .def    _INT_Setup_Vector
_INT_Setup_Vector
;
;VOID    *old_vector;                        /* Old interrupt vector      */
;VOID   **vector_table;                      /* Pointer to vector table   */
;
;    /* Calculate the starting address of the actual vector table.  */
;    vector_table =  (VOID **) 0;
;
;    /* Pickup the old interrupt vector.  */
;    old_vector =  vector_table[vector];
;    
;    /* Setup the new interrupt vector.  */
;    vector_table[vector] =  new;
;    
;    /* Return the old interrupt vector.  */
;    return(old_vector);
;
        MOV     a1,#0                       ; This routine is not applicable to
                                            ;   THUMB, return a NULL pointer
        BX      lr                          ; Return to caller
;}
;
;
;
;
;/*************************************************************************/
;/*                                                                       */
;/* FUNCTIONS                                                             */
;/*                                                                       */
;/*      INT_EnableIRQ, INT_DisableIRQ                                    */
;/*                                                                       */
;/* DESCRIPTION                                                           */
;/*                                                                       */
;/*      This function enable/disable IRQ/FIQ in current mode             */
;/*                                                                       */
;/*************************************************************************/
;
        .global $INT_EnableIRQ
$INT_EnableIRQ:
	.state16
        BX      pc
	nop

	.state32
        MRS     a1, CPSR                ; read current PSR
        BIC     a1,a1,#MODE_MASK        ; remove all mode bits
        ORR     a1,a1,#IRQ_MODE         ; retrieve desired mode
        MSR     CPSR,a1                 ; IRQ mode

        MRS     a1, CPSR                ; read current PSR
        BIC     a1,a1,#LOCKOUT          ; interrupt lockout value
        MSR     CPSR,a1                 ; Lockout interrupts

        BIC     a1,a1,#MODE_MASK        ; remove all mode bits
        ORR     a1,a1,#SUP_MODE         
        MSR     CPSR,a1                 ; Lockout interrupts

	add	a1, pc, #1		; back to Thumb mode 
	bx	a1

	.state16
        BX      lr                      ; Return to caller

;
;
        .global $INT_DisableIRQ
$INT_DisableIRQ:
	.state16
        BX      pc
	nop

	.state32
        MRS     a1, CPSR                ; read current PSR
        BIC     a1,a1,#MODE_MASK        ; remove all mode bits
        ORR     a1,a1,#IRQ_MODE         ; retrieve desired mode
        MSR     CPSR,a1                 ; IRQ mode

        MRS     a1, CPSR                ; read current PSR
        ORR     a1,a1,#LOCKOUT          ; Build interrupt lockout value
        MSR     CPSR,a1                 ; Lockout interrupts

        BIC     a1,a1,#MODE_MASK        ; remove all mode bits
        ORR     a1,a1,#SUP_MODE         
        MSR     CPSR,a1                 ; Lockout interrupts

	add	a1, pc, #1		; back to Thumb mode 
	bx	a1

	.state16
         BX      lr                      ; Return to caller
;
;
;/*************************************************************************/
;/*                                                                       */
;/* FUNCTION                                                              */
;/*                                                                       */
;/*      INT_Retrieve_Shell                                               */
;/*                                                                       */
;/* DESCRIPTION                                                           */
;/*                                                                       */
;/*      This function retrieves the pointer to the shell interrupt       */
;/*      service routine.  The shell interrupt service routine calls      */
;/*      the LISR dispatch routine.                                       */
;/*                                                                       */
;/* AUTHOR                                                                */
;/*                                                                       */
;/*      Barry Sellew, Accelerated Technology, Inc.                       */
;/*                                                                       */
;/* CALLED BY                                                             */
;/*                                                                       */
;/*      TCC_Register_LISR                   Register LISR for vector     */
;/*                                                                       */
;/* CALLS                                                                 */
;/*                                                                       */
;/*      None                                                             */
;/*                                                                       */
;/* INPUTS                                                                */
;/*                                                                       */
;/*      vector                              Vector number to setup       */
;/*                                                                       */
;/* OUTPUTS                                                               */
;/*                                                                       */
;/*      shell pointer                                                    */
;/*                                                                       */
;/* HISTORY                                                               */
;/*                                                                       */
;/*         NAME            DATE                    REMARKS               */
;/*                                                                       */
;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
;/*	 B. Sellew	 01-22-1996	 Verified version 1.0	  	  */
;/*                                                                       */
;/*************************************************************************/
;VOID  *INT_Retrieve_Shell(INT vector)
;{
	.def	$INT_Retrieve_Shell
$INT_Retrieve_Shell			    ; Dual-state interworking veneer
	.state16
	BX	pc
	NOP
	.state32
	B	_INT_Retrieve_Shell
;
        .def    _INT_Retrieve_Shell
_INT_Retrieve_Shell
;
;    /* Return the LISR Shell interrupt routine.  */
;    return(INT_Vectors[vector]);
;
        MOV     a1,#0                       ; This routine is not applicable to
                                            ;   THUMB, return a NULL pointer
        BX      lr                          ; Return to caller
;}
;
;
;
;/* The following section contains default interrupt handlers.  */
;
     .if TI_NUC_MONITOR = 1
; define a new section to be mapped independently
        .sect ".irqtext"
             
        .def    _INT_IRQ
		.global _INT_IRQ
_INT_IRQ
     .else
        .def    INT_IRQ
INT_IRQ
	 .endif

;
;    /* Call Prepare for IRQ interrupt processing by calling 
;       TCT_Interrupt_Context_Save.  */
        STMDB   sp!,{a1-a4}                 ; Save a1-a4 on temporary IRQ stack

;BUG correction 1st part -------------------
;It looks like there is an issue with ARM7 IRQ masking in the CPSR register
;which leads to crashes in Nucleus+ scheduler.
;Basically the code below  (correct as LOCKOUT = 0xC0) is used in many places by N+ but do not 
;prevent from having an interrupt after the execution of the third line (I mean execution, not 
;fetch).
;        MRS     a1,CPSR                     ; Pickup current CPSR
;        ORR     a1,a1,#LOCKOUT              ; Build interrupt lockout value
;        MSR     CPSR,a1                     ; Lockout interrupts
;       * IRQ INTERRUPT ! *
;       Next instructions...
;
;SW workaround:
;When a task is interrupted at this point an interrupted context is stored on its task and will 
;be resumed later on at the next instruction but to make a long story short it leads to some 
;problem as the OS does not expect to be interrupted there.
;Further testing tends to show that the CPSR *seems* to be loaded with the proper masking value 
;but that the IRQ is still triggered (has been hardwarewise requested during the instruction 
;exectution by the ARM7 core?)
        MRS     a1,spsr                     ; check for the IRQ bug:
        TST     a1,#080h                    ; if the I - flag is set,
        BNE     IRQBUG                      ; then postpone execution of this IRQ
;Bug correction 1st part end ---------------
    
        SUB     a4,lr,#4                    ; Save IRQ's lr (return address)
        BL      _TCT_Interrupt_Context_Save ; Call context save routine

  .if TI_NUC_MONITOR = 1
; Log the IRQ call entry
  		.global _ti_nuc_monitor_LISR_log
		BL		_ti_nuc_monitor_LISR_log		; Call the LISR Log function.
  .endif

;
;    /* On actuall hardware, a register must be examined to see what the 
;       IRQ interrupt was caused from.   For default processing, the 
;       timer is the only IRQ interrupt source.  It is assumed that further
;       timer interrupts are disabled upon this call.  */
;
        BL      _IQ_IRQ_isr 			; Call  int. service routine

  .if TI_NUC_MONITOR = 1
; Log the IRQ exit
  		.global _ti_nuc_monitor_LISR_log_end
		BL		_ti_nuc_monitor_LISR_log_end		; Call the LISR end function.
  .endif

;
;    /* IRQ interrupt processing is complete.  Restore context- Never 
;       returns!  */
        B       _TCT_Interrupt_Context_Restore

;BUG correction 2nd part  ------------------
IRQBUG: LDMFD  sp!,{a1-a4}                  ; return from interrupt
        SUBS   pc,r14,#4
;BUG correction 2nd part end  --------------

;
  .if TI_NUC_MONITOR = 1
      .sect ".inttext"
  .endif
;
     .if TI_PROFILER = 1
; define a new section to be mapped independently
        .sect ".fiqtext"
             
        .def    _INT_FIQ
		.global _INT_FIQ
_INT_FIQ
     .else
        .def    INT_FIQ
INT_FIQ
	 .endif

   .if TI_PROFILER = 1
; Warning : 
; This code has been added for profiliing purpose.
; It removes all other FIQ. 
        .global    _ti_profiler_handler
; Timing profiler using FIQ - Handle FIQ directly here
        STMFD    sp!,{R0-R4, LR}            ; Save R0-R4 and LR on FIQ stack

        MOV     R0, LR                      ; Retrieve link register in R0
        BL      _ti_profiler_handler        ; Store into buffer
        BL      _IQ_FIQ_isr                 ; Call the FIQ ISR
        LDMFD   sp!,{R0-R4, LR}            ; Restore R0-R4 and LR from FIQ stack
        SUBS    PC, LR, #4                 ; return from FIQ
    .else

;
;    /* Call Prepare for FIQ interrupt processing by calling 
;       TCT_Interrupt_Context_Save.  */
        STMDB   sp!,{a1-a4}                 ; Save a1-a4 on temporary FIQ stack
        SUB     a4,lr,#4                    ; Save FIQ's lr (return address)
        BL      _TCT_Interrupt_Context_Save ; Call context save routine
;
;    /* On actuall hardware, a register must be examined to see what the 
;       FIQ interrupt was caused from.   For default processing, the 
;       test is the only FIQ interrupt source.  */
;
;    /* Replace this with a call to your own ISR */
        BL      _IQ_FIQ_isr              ; Call the FIQ ISR

;
;    /* FIQ interrupt processing is complete.  Restore context- Never 
;       returns!  */
        B       _TCT_Interrupt_Context_Restore

  .endif

  .if TI_PROFILER = 1
      .sect ".inttext"
  .endif

;***************************************************************
;* CONSTANT TABLE                                              *
;***************************************************************

;
;    /* Define all the global addresses used in this section */
;

; internal/external RAM
    .if CHIPSET = 3	| CHIPSET = 5 | CHIPSET = 6
RAM_SIZE       .equ    0x40000          ; size (in bytes) of internal RAM 
RAM_LOW        .equ    0x3000000        ; first address of internal RAM
    .elseif CHIPSET = 4
RAM_SIZE       .equ    0x40000          ; size (in bytes) of internal RAM 
RAM_LOW        .equ    0x800000         ; first address of internal RAM
    .elseif CHIPSET = 7	| CHIPSET = 8 | CHIPSET = 10 | CHIPSET = 11 | CHIPSET = 12
	.if L1_GPRS = 1
RAM_SIZE       .equ    0x200000         ; size (in bytes) of external RAM 
RAM_LOW        .equ    0x1000000        ; first address of external RAM
		.else	; GSM ONLY
RAM_SIZE       .equ    0x80000          ; size (in bytes) of internal RAM 
RAM_LOW        .equ    0x800000         ; first address of internal RAM
		.endif
	.endif

RAM_HIGH       .equ    RAM_LOW + RAM_SIZE ; first address after internal/external RAM
               

	.global exception_stack        ; top address of SVC mode stack

	.global _xdump_buffer          ; first address of state data

	.global stack_segment		   ; address of the top of the system stack

;
; /* Define exception functions */
;
    .ref    _dar_exception

XDUMP_STACK_SIZE .equ   20

; layout of xdump buffer:
; struct xdump_s {
;     long registers[16] // svc mode registers
;     long cpsr          // svc mode CPSR
;     long exception     // magic word + index of vector taken
;     long stack[20]     // bottom 20 words of usr mode stack
; }

arm_undefined:
        stmfd   r13!,{r11,r12}		; store r12 for Xdump_buffer pointer, r11 for index
		mov     r11,#1
		b       save_regs
		
arm_swi:
        stmfd   r13!,{r11,r12}		; store r12 for Xdump_buffer pointer, r11 for index
		mov     r11,#2
		b       save_regs
        
arm_abort_prefetch:
        stmfd   r13!,{r11,r12}		; store r12 for Xdump_buffer pointer, r11 for index
		mov     r11,#3
		b       save_regs
		
        
arm_abort_data:
        stmfd   r13!,{r11,r12}		; store r12 for Xdump_buffer pointer, r11 for index
		mov     r11,#4
		b       save_regs

arm_reserved:
        ldr     r13,Exception_Stack     ; should never happen, but mode is unknown at this point
        stmfd   r13!,{r11,r12}		; store r12 for Xdump_buffer pointer, r11 for index
		mov     r11,#5
		b       save_regs
        
save_regs:
        ldr     r12,Xdump_buffer
        str     r14,[r12,#4*15] ; save r14_abt (original PC) into r15 slot

        stmia   r12,{r0-r10}    ; save unbanked registers (except r11 and r12)
        ldmfd   r13!,{r0,r1}    ; get original r11 and r12
        str     r0,[r12,#4*11]  ; save original r11
        str     r1,[r12,#4*12]  ; save original r12
        mrs     r0,spsr         ; get original psr
        str     r0,[r12,#4*16]  ; save original cpsr

        mrs     r1,cpsr         ; save mode psr
        bic     r2,r1,#0x1f     ; psr with mode bits cleared
        and     r0,r0,#0x1f     ; get original mode bits
        add     r0,r0,r2

        msr     cpsr,r0		  ; move to pre-exception mode
        str     r13,[r12,#4*13] ; save original SP
        str     r14,[r12,#4*14] ; save original LR
        msr     cpsr,r1 	  ; restore mode psr

        ; r11 has original index
        orr     r10,r11,#0xDE<<24; r10 = 0xDEAD0000 + index of vector taken
        orr     r10,r10,#0xAD<<16
        str     r10,[r12,#4*17] ; save magic + index

        mov     r0,r11          ; put index into 1st argument
        b       _dar_exception
        
	.global $exception		       ; export function

$exception: ; Veneer function
        .ref    _exception
		.state16
		adr     r0,_exception
		bx      r0
		.align
		.state32
		.def    _exception
_exception:
        ldr     r12,Xdump_buffer ; redundant unless _exception is called
        ldr     r11,[r12,#4*13]  ; get svc mode r13
        add     r12,r12,#4*18    ; base of stack buffer

        ; check if svc r13(sp) is within internal/external RAM. It *could* be invalid.
        ; we boldly assume stack is only within internal RAM except for GPRS build on 
		; Calypso chipset : stack is within external RAM
    .if CHIPSET = 7	| CHIPSET = 8 | CHIPSET = 10 | CHIPSET = 11
         .if L1_GPRS = 1
              ; if GPRS, check for internal RAM as well as 2Mbytes of external RAM
              cmp     r11,#0x800000			 ; INTERNAL RAM_LOW
              blt     nostack
              mov     r0, #0x880000			 ; INTERNAL RAM_HIGH
              sub     r0,r0,#XDUMP_STACK_SIZE
              cmp     r11,r0
              blt     stack_range
              ; was not less than 0x880000, so check for external RAM
              cmp     r11,#RAM_LOW
              blt     nostack
              mov     r0,#RAM_HIGH
              sub     r0,r0,#XDUMP_STACK_SIZE
              cmp     r11,r0
              bge     nostack
		.else	; GSM ONLY
              cmp     r11,#RAM_LOW
              blt     nostack
              mov     r0,#RAM_HIGH
              sub     r0,r0,#XDUMP_STACK_SIZE
              cmp     r11,r0
              bge     nostack
		.endif
	.endif
              
stack_range:              
        ldmfd   r11!,{r0-r9}    ; copy ten stack words..
        stmia   r12!,{r0-r9}
        ldmfd   r11!,{r0-r9}    ; copy ten stack words..
        stmia   r12!,{r0-r9}

nostack:
STACKS       .equ    SYSTEM_SIZE + IRQ_STACK_SIZE +	FIQ_STACK_SIZE + TIMER_SIZE
	.ref _dar_reset
        ; we're finished saving all state. Now execute C code for more flexibility.
        ; set up a stack for this C call
        LDR     a1,StackSegment             ; Pickup the begining address from .cmd file
                                            ;    (is aligned on 8 byte boundary)
        MOV     a2,#STACKS					; Pickup all stacks size
        ADD     a2,a2,#0x80                 ; Add 128 to get past all used data
        ADD     a3,a1,a2                    
        MOV     sp,a3                       ; Setup exception stack pointer
        b _dar_reset


BSS_Start
	.word	.bss
;
BSS_End
	.word	end
;
  .if LONG_JUMP >= 3
  .align 4
BSS_IntMem_Start: .field  _S_D_Mem,32
  .align 4
BSS_IntMem_End:   .field  _E_D_Mem,32
  .endif

StackSegment
	.word	stack_segment
;
Loaded_Flag
	.word	_INT_Loaded_Flag
;
System_Limit
	.word	_TCT_System_Limit
;
System_Stack
	.word	_TCD_System_Stack
;
HISR_Stack_Ptr
	.word	_TMD_HISR_Stack_Ptr
;
HISR_Stack_Size	
	.word	_TMD_HISR_Stack_Size
;
HISR_Priority
	.word	_TMD_HISR_Priority
;
Exception_Stack
    .word   exception_stack
;
Xdump_buffer
    .word   _xdump_buffer
;
;   The following code is pulled from rts.src, which is part of the
;   TI tools installation.
;
;***************************************************************************
;*  PROCESS INITIALIZATION TABLE.
;*
;*  THE TABLE CONSISTS OF A SEQUENCE OF RECORDS OF THE FOLLOWING FORMAT:
;*                                                                          
;*       .word  <length of data (bytes)>
;*       .word  <address of variable to initialize>                         
;*       .word  <data>
;*                                                                          
;*  THE INITIALIZATION TABLE IS TERMINATED WITH A ZERO LENGTH RECORD.
;*                                                                          
;***************************************************************************
;****auto_init(register int *table)
;****{
;****   register int length;
;****   register int *addr;
;****
;****   while (length = *table++)
;****   {
;****      addr = (int *)*table++;
;****      while (length)
;****      {
;****         if (length > 3)
;****	      {
;****	         *addr++ = *table++;
;****	         length -= 4;
;****	      }
;****	      else
;****	      {
;****	         *(char *)addr++ = *(char *)table++;
;****	         length--;
;****	      }
;****      }
;****   }
;****}

tbl_addr: .set    R0
var_addr: .set    R1
length:   .set    R3
data:     .set    R4

_auto_init:
	B	rec_chk

record:
        ;*------------------------------------------------------
	;* PROCESS AN INITIALIZATION RECORD
        ;*------------------------------------------------------
	LDR	var_addr, [tbl_addr], #4

copy:
        ;*------------------------------------------------------
	;* COPY THE INITIALIZATION DATA
        ;*------------------------------------------------------
	CMP	length, #3

	LDRHI	data, [tbl_addr], #4  
	STRHI	data, [var_addr], #4	   ; COPY A WORD OF DATA
	SUBHI	length, length, #4	   ; OR ...
	LDRLSB	data, [tbl_addr], #1       ;
	STRLSB	data, [var_addr], #1       ; COPY A BYTE OF DATA
	SUBLS	length, length, #1

	CMP     length, #0		   ; CONTINUE TO COPY IF
	BNE	copy                       ; LENGTH IS NONZERO

	ANDS	length, tbl_addr, #0x3     ; MAKE SURE THE ADDRESS
	RSBNE	length, length, #0x4       ; IS WORD ALIGNED
	ADDNE	tbl_addr, tbl_addr, length ;

rec_chk:LDR	length, [tbl_addr], #4     ; PROCESS NEXT
	CMP	length, #0                 ; RECORD IF LENGTH IS
	BNE	record                     ; NONZERO

	MOV	PC, LR
;

;
; Creation of INT_memset and INT_memcpy, respectively identical to memset and 
; memcpy from the rts library of compiler 2.51/2.54.
; They are used to make the initialization of the .bss section and the load 
; of the internal ram code not dependent to the 32-bit alignment.
; The old code used for the initialization and the load used a loop with
; 4-byte increment, assuming the 32-bit alignment of the .bss section.
; This alignment is not necessary true.
;  
;******************************************************************************
;* INT_memset - INITIALIZE MEMORY WITH VALUE                                  *
;******************************************************************************
;* MEMSET32.ASM  - 32 BIT STATE -  v2.51                                      *
;* Copyright (c) 1996-2003 Texas Instruments Incorporated                     *
;******************************************************************************

;****************************************************************************
;* INT_memset - INITIALIZE MEMORY WITH VALUE.
;*
;*  Same memset defined in rts.src.
;*  Used in INT_Initialize to clear bss area.
;*  Used in f_load_int_mem() function to clear internal memory space used
;*  for data and code.
;*  The memset function defined in rts library is loaded into internal memory,
;*  then, it can not be used in either INT_Initialize, or f_load_int_mem().
;*
;*  C Prototype   : void *INT_memset(void *s, int c, size_t n);
;*  C++ Prototype : void *std::INT_memset(void *s, int c, std::size_t n);
;*
;****************************************************************************
;*
;*   o DESTINATION LOCATION IS IN r0
;*   o INITIALIZATION VALUE IS IN r1
;*   o NUMBER OF BYTES TO INITIALIZE IS IN r2
;*
;*   o ORIGINAL DESTINATION LOCATION RETURNED IN r0
;****************************************************************************
	.state32
  .def _INT_memset

_INT_memset:
	STMFD	SP!, {R0, LR}		      ; save R0 also since original dst
					                    ; address is returned.

	TST	R0, #3			            ; check for word alignment
	BEQ	_word_aligned

	CMP	R2, #0			            ; set bytes until there are no more
					                    ; to set or until address is aligned
_unaligned_loop:
	STRHIB	R1, [R0], #1
	SUBHIS	R2, R2, #1
	TSTHI	R0, #3
	BNE	_unaligned_loop
          
	CMP	R2, #0			            ; return early if no more bytes
	LDMEQFD	SP!, {R0, PC}		    ; to set.

_word_aligned:
	AND	R1, R1, #255		        ; be safe since prototype has value as
					                    ; as an int rather than unsigned char

	ORR	R1, R1, R1, LSL	#8      ; replicate byte in 2nd byte of
					                    ; register

	CMP	R2,#4			              ; are at least 4 bytes being set
	BCC	_INT_memset3

	ORR	R1, R1, R1, LSL	#16	    ; replicate byte in upper 2 bytes
					                    ; of register. note that each of
					                    ; the bottom 2 bytes already contain 
					                    ; the byte value from above.

	CMP	R2,#8	              		; are at least 8 bytes being set
	BCC	_INT_memset7
        
	MOV	LR,R1		              	; copy bits into another register so
					                    ; 8 bytes at a time can be copied.
				                    	; use LR since it is already being
				                    	; saved/restored.

	CMP	R2,#16		            	; are at least 16 bytes being set
	BCC	_INT_memset15

	STMFD	SP!, {R4}		          ; save regs needed by 16 byte copies

	MOV	R4, R1		            	; copy bits into 2 other registers so
	MOV	R12, R1		            	; 16 bytes at a time can be copied

	SUB	R3, R2, #15	          	; set up loop count
	AND	R2, R2, #15		          ; determine number of bytes to set
					                    ; after setting 16 byte blocks

_INT_memset16_loop:			    	; set blocks of 16 bytes
	STMIA	R0!, {R1, R4, R12, LR}
	SUBS	R3, R3, #16
	BHI	_INT_memset16_loop

	LDMFD	SP!, {R4}	          	; resotre regs used by 16 byte copies

_INT_memset15:			         	; may still be as many as 15 bytes to 
					                    ; set. the address in R0 is guaranteed
					                    ; to be word aligned here.

	TST	R2, #8		            	; are at least 8 bytes being set
	STMNEIA	R0!, {R1, LR}


_INT_memset7:		          		; may still be as many as 7 bytes to 
					                    ; set. the address in R0 is guaranteed
					                    ; to be word aligned here.

	TST	R2, #4			            ; are at least 4 bytes being set
	STRNE	R1, [R0], #4

_INT_memset3:	          			; may still be as many as 3 bytes to 
				                    	; set. the address in R0 is guaranteed
				                    	; to be word aligned here.

	TST	R2, #2		            	; are there at least 2 more bytes to 
	STRNEH	R1, [R0], #2	     	; set.  the address in R0 is guaranteed
				                    	; to be half-word aligned here.
	
	TST	R2, #1		            	; is there one remaining byte to set
	STRNEB	R1, [R0]


	LDMFD     SP!, {R0, PC}		  ; restore regs and return


;******************************************************************************
;* INT_memcpy - COPY CHARACTERS FROM SOURCE TO DEST                           *
;******************************************************************************
;* MEMCPY32.ASM  - 32 BIT STATE -  v2.51                                      *
;* Copyright (c) 1996-2003 Texas Instruments Incorporated                     *
;******************************************************************************
 
;****************************************************************************
;* INT_memcpy - COPY CHARACTERS FROM SOURCE TO DEST
;*
;*  Same as C_MEMCPY defined in rts.src.
;*  Used in INT_Initialize to download code into internal memory space.
;*  The memcpy function defined in rts library is loaded into internal memory.
;*  then, it can not be used in f_load_int_mem().
;*
;****************************************************************************
;*
;*   o DESTINATION LOCATION IS IN r0
;*   o SOURCE LOCATION IS IN r1
;*   o NUMBER OF CHARACTERS TO BE COPIED IS IN r2
;****************************************************************************
 	.state32
  .def _INT_memcpy

_INT_memcpy: 
	CMP	r2, #0			                    ; CHECK FOR n == 0
	BXEQ	lr			;

	STMFD	sp!, {r0, lr}		              ; SAVE RETURN VALUE AND ADDRESS

	TST	r1, #0x3		                    ; CHECK ADDRESS ALIGNMENT
	BNE	_unaln			                    ; IF NOT WORD ALIGNED, HANDLE SPECIALLY
	TST	r0, #0x3		                    ;
	BNE	_saln			;

_aln:	CMP	r2, #16			                ; CHECK FOR n >= 16
	BCC	_l16			;

	STMFD	sp!, {r4}		;
	SUB	r2, r2, #16		;
_c16:	LDMIA	r1!, {r3, r4, r12, lr}	  ; COPY 16 BYTES
	STMIA	r0!, {r3, r4, r12, lr}	;
	SUBS	r2, r2, #16		;
	BCS	_c16			;
	LDMFD	sp!, {r4}		;
	ADDS	r2, r2, #16		                ; RETURN IF DONE
	LDMEQFD	sp!, {r0, pc}		;
	
_l16:	ANDS	r3, r2, #0xC		;
	BEQ	_cp1			;
	BICS	r2, r2, #0xC		;
	ADR	r12, _4line - 16	;
	ADD	pc, r12, r3, LSL #2	;

_4line:	LDR	r3, [r1], #4		          ; COPY 4 BYTES
	STR	r3, [r0], #4		;
	LDMEQFD	sp!, {r0, pc} 	          	; CHECK FOR n == 0
	B	_cp1			;

	LDMIA	r1!, {r3, r12}		            ; COPY 8 BYTES
	STMIA	r0!, {r3, r12}		;
	LDMEQFD	sp!, {r0, pc} 		          ; CHECK FOR n == 0
	B	_cp1			;

	LDMIA	r1!, {r3, r12, lr}	          ; COPY 12 BYTES
	STMIA	r0!, {r3, r12, lr}	;
	LDMEQFD	sp!, {r0, pc} 		          ; CHECK FOR n == 0

_cp1:	SUBS	r2, r2, #1		;
	ADRNE	r3, _1line - 4		            ; SETUP TO COPY 1 - 3 BYTES...
	ADDNE	pc, r3, r2, LSL #4	;

_1line:	LDRB	r3, [r1], #1		        ; COPY 1 BYTE
	STRB	r3, [r0], #1		;
	LDMFD	sp!, {r0, pc}		;

	LDRH	r3, [r1], #2		              ; COPY 2 BYTES
	STRH	r3, [r0], #2		;
	LDMFD	sp!, {r0, pc}		;
	NOP				;

	LDRH	r3, [r1], #2		              ; COPY 3 BYTES
	STRH	r3, [r0], #2		;
	LDRB	r3, [r1], #1		;
	STRB	r3, [r0], #1		;
	LDMFD	sp!, {r0, pc}		;

_unaln:	LDRB	r3, [r1], #1		        ; THE ADDRESSES ARE NOT WORD ALIGNED.
	STRB	r3, [r0], #1		              ; COPY BYTES UNTIL THE SOURCE IS
	SUBS	r2, r2, #1		                ; WORD ALIGNED OR THE COPY SIZE
	LDMEQFD	sp!, {r0, pc}		            ; BECOMES ZERO
	TST	r1, #0x3		;
	BNE	_unaln			;

_saln:	TST	r0, #0x1		              ; IF THE ADDRESSES ARE OFF BY 1 BYTE
	BNE	_off1			                      ; JUST BYTE COPY

	TST	r0, #0x2	                    	; IF THE ADDRESSES ARE NOW WORD ALIGNED
	BEQ	_aln			                      ; GO COPY.  ELSE THEY ARE OFF BY 2, SO
					                            ; GO SHORT WORD COPY

_off2:	SUBS	r2, r2, #4		          ; COPY 2 BYTES AT A TIME...
	BCC	_c1h			;
_c2:	LDR	r3, [r1], #4		            ; START BY COPYING CHUNKS OF 4,
	.if	.TMS470_BIG
	STRH	r3, [r0, #2]		;
	MOV	r3, r3, LSR #16		;
	STRH	r3, [r0], #4		;
	.else
	STRH	r3, [r0], #4		;
	MOV	r3, r3, LSR #16		;
	STRH	r3, [r0, #-2]		;
	.endif
	SUBS	r2, r2, #4		;
	BCS	_c2			;
	CMN	r2, #4			;
	LDMEQFD	sp!, {r0, pc}		;

_c1h:	ADDS	r2, r2, #2		            ; THEN COPY THE ODD BYTES.
	LDRCSH	r3, [r1], #2		;
	STRCSH	r3, [r0], #2		;
	SUBCS	r2, r2, #2		;
	ADDS	r2, r2, #1		;
	LDRCSB	r3, [r1], #1		;
	STRCSB	r3, [r0], #1		;
	LDMFD	sp!, {r0, pc}		;

_off1:	SUBS	r2, r2, #4		          ; COPY 1 BYTE AT A TIME...
	BCC	_c1b			;
_c1:	LDR	r3, [r1], #4		            ; START BY COPYING CHUNKS OF 4,
	.if	.TMS470_BIG
	STRB	r3, [r0, #3]		              ;
	MOV	r3, r3, LSR #8		              ;
	STRB	r3, [r0, #2]		              ;
	MOV	r3, r3, LSR #8		              ;
	STRB	r3, [r0, #1]		              ;
	MOV	r3, r3, LSR #8		              ;
	STRB	r3, [r0], #4		              ;
	.else
	STRB	r3, [r0], #4		              ;
	MOV	r3, r3, LSR #8		              ;
	STRB	r3, [r0, #-3]		              ;
	MOV	r3, r3, LSR #8		              ;
	STRB	r3, [r0, #-2]		              ;
	MOV	r3, r3, LSR #8		              ;
	STRB	r3, [r0, #-1]		              ;
	.endif
	SUBS	r2, r2, #4		;
	BCS	_c1			;

_c1b:	ADDS	r2, r2, #4	            	; THEN COPY THE ODD BYTES.
	LDMEQFD	sp!, {r0, pc}		;
_lp1:	LDRB	r3, [r1], #1		;
	STRB	r3, [r0], #1		;
	SUBS	r2, r2, #1		;
	BNE	_lp1			; 
	LDMFD	sp!, {r0, pc}		;

        .end