diff src/cs/system/main/int.s @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cs/system/main/int.s	Fri Oct 16 06:23:26 2020 +0000
@@ -0,0 +1,2255 @@
+;******************************************************************************
+;            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
+