line source
+ − ;******************************************************************************
+ − ; TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION
+ − ;
+ − ; Property of Texas Instruments -- For Unrestricted Internal Use Only
+ − ; Unauthorized reproduction and/or distribution is strictly prohibited. This
+ − ; product is protected under copyright law and trade secret law as an
+ − ; unpublished work. Created 1987, (C) Copyright 1997 Texas Instruments. All
+ − ; rights reserved.
+ − ;
+ − ;
+ − ; Filename : int.s
+ − ;
+ − ; Description : Nucleus initialization
+ − ;
+ − ; Project : Drivers
+ − ;
+ − ; Author : proussel@ti.com Patrick Roussel.
+ − ;
+ − ; Version number : 1.3
+ − ;
+ − ; Date and time : 07/23/98 15:36:07
+ − ;
+ − ; Previous delta : 07/23/98 15:36:06
+ − ;
+ − ; SCCS file : /db/gsm_asp/db_ht96/dsp_0/gsw/rel_0/mcu_l1/release1.5/mod/emu/EMU_MCMP/eva3_drivers/source/SCCS/s.int.s
+ − ;
+ − ; Sccs Id (SID) : '@(#) int.s 1.3 07/23/98 15:36:07 '
+ − ;/*************************************************************************/
+ − ;/* */
+ − ;/* Copyright (c) 1993 - 1996 Accelerated Technology, Inc. */
+ − ;/* */
+ − ;/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the */
+ − ;/* subject matter of this material. All manufacturing, reproduction, */
+ − ;/* use, and sales rights pertaining to this subject matter are governed */
+ − ;/* by the license agreement. The recipient of this software implicitly */
+ − ;/* accepts the terms of the license. */
+ − ;/* */
+ − ;/*************************************************************************/
+ − ;
+ − ;/*************************************************************************/
+ − ;/* */
+ − ;/* FILE NAME VERSION */
+ − ;/* */
+ − ;/* int.s PLUS/THUMB/T 1.3 */
+ − ;/* */
+ − ;/* COMPONENT */
+ − ;/* */
+ − ;/* IN - Initialization */
+ − ;/* */
+ − ;/* DESCRIPTION */
+ − ;/* */
+ − ;/* This file contains the target processor dependent initialization */
+ − ;/* routines and data. */
+ − ;/* */
+ − ;/* AUTHOR */
+ − ;/* */
+ − ;/* Barry Sellew, Accelerated Technology, Inc. */
+ − ;/* */
+ − ;/* DATA STRUCTURES */
+ − ;/* */
+ − ;/* INT_Vectors Interrupt vector table */
+ − ;/* */
+ − ;/* FUNCTIONS */
+ − ;/* */
+ − ;/* INT_Initialize Target initialization */
+ − ;/* INT_Vectors_Loaded Returns a NU_TRUE if all the */
+ − ;/* default vectors are loaded */
+ − ;/* INT_Setup_Vector Sets up an actual vector */
+ − ;/* */
+ − ;/* DEPENDENCIES */
+ − ;/* */
+ − ;/* nucleus.h System constants */
+ − ;/* */
+ − ;/* HISTORY */
+ − ;/* */
+ − ;/* NAME DATE REMARKS */
+ − ;/* */
+ − ;/* B. Sellew 01-19-1996 Created initial version 1.0 */
+ − ;/* B. Sellew 01-22-1996 Verified version 1.0 */
+ − ;/* B. Sellew 03-14-1996 Modified to use the ROM */
+ − ;/* initialization method, */
+ − ;/* resulting in version 1.1 */
+ − ;/* B. Sellew 03-14-1996 Verified version 1.1 */
+ − ;/* B. Sellew 02-06-1997 Created version 1.3 */
+ − ;/* B. Sellew 02-06-1997 Verified version 1.3 */
+ − ;/* M. Manning 06-02-1997 Added support for FIQ */
+ − ;/* interrupts. Bumped to 1.4 */
+ − ;/* M. Manning 06-03-1997 Verified version 1.4 */
+ − ;/* */
+ − ;/*************************************************************************/
+ − ;#define NU_SOURCE_FILE
+ − ;
+ − ;#include "nucleus.h" /* System constants */
+ − ;
+ − ;
+ − ;/* Define constants used in low-level initialization. */
+ − ;
+ − ;
+ −
+ −
+ − .if LONG_JUMP >= 3
+ − .global IND_CALL
+ − .global _f_load_int_mem
+ − .global _ResetVector
+ −
+ − ; Initialization for variable S_D_Mem
+ − .sect ".cinit"
+ − .align 4
+ −
+ − ; S_D_Mem is a UWORD32, See mem_load.c
+ − ;
+ − .field 4,32
+ − .field _S_D_Mem+0,32
+ − .field 0,32 ; _S_D_Mem @ 0
+ −
+ − .sect ".text"
+ − .global _S_D_Mem
+ − _S_D_Mem: .usect "S_D_Mem",4,4
+ − .sym _S_D_Mem,_S_D_Mem,14,2,32 ; For debug only
+ −
+ −
+ − ; Initialization for variable E_D_Mem
+ −
+ − .sect ".cinit"
+ − .align 4
+ −
+ −
+ − ; E_D_Mem is a UWORD32, See mem_load.c
+ − ;
+ − .field 4,32
+ − .field _E_D_Mem+0,32
+ − .field 0,32 ; _E_D_Mem @ 0
+ −
+ − .sect ".text"
+ − .global _E_D_Mem
+ − _E_D_Mem: .usect "E_D_Mem",4,4
+ − .sym _E_D_Mem,_E_D_Mem,14,2,32 ; For debug only
+ −
+ − .endif ; (LONG_JUMP >= 3)
+ −
+ − .if CHIPSET == 12
+ − .global _f_load_int_mem
+ − .global _ResetVector
+ − .global _ResetVectorTestMode ; CALYPSO PLUS TEST MODE - TO BE ERASED
+ − .endif
+ −
+ − LOCKOUT .equ 00C0h ; Interrupt lockout value
+ − LOCK_MSK .equ 00C0h ; Interrupt lockout mask value
+ − MODE_MASK .equ 001Fh ; Processor Mode Mask
+ − SUP_MODE .equ 0013h ; Supervisor Mode (SVC)
+ − IRQ_MODE .equ 0012h ; Interrupt Mode (IRQ)
+ − FIQ_MODE .equ 0011h ; Fast Interrupt Mode (FIQ)
+ − ABORT_MODE .equ 0017h ; Abort Interrupt Mode
+ − UNDEF_MODE .equ 001Bh ; Undefined Interrupt Mode (should not happen)
+ −
+ − IRQ_STACK_SIZE .equ 128 ; Number of bytes in IRQ stack (must be align(8))
+ − ; Note that the IRQ interrupt,
+ − ; by default, is managed by
+ − ; Nucleus PLUS. Only several
+ − ; words are actually used. The
+ − ; system stack is what will
+ − ; actually be used for Nuclues
+ − ; PLUS managed IRQ interrupts.
+ − FIQ_STACK_SIZE .equ 512 ; Number of bytes in FIQ stack. (must be align(8))
+ − ; This value is application
+ − ; specific. By default, Nucleus
+ − ; does not manage FIQ interrupts
+ − ; and furthermore, leaves them
+ − ; enabled virtually all the time.
+ − SYSTEM_SIZE .equ 1024 ; Define the system stack size (must be align(8))
+ − TIMER_SIZE .equ 1024 ; Define timer HISR stack size (must be align(8))
+ − TIMER_PRIORITY .equ 2 ; Timer HISR priority (values from
+ −
+ − .if BOARD = 34
+ − ; Name value offset type W/E W/S D/Cycles
+ − CS0_CONFIG .short 0x044F ; 0 Flash 32 N F 2
+ − CS1_CONFIG .short 0x02CF ; 2 RAM 32 Y F 1
+ − CS2_CONFIG .short 0x02CF ; 4
+ − CS3_CONFIG .short 0x02CF ; 6
+ − CS7_CONFIG .short 0x02C0 ; 8 Int-RAM 32 Y 0 1
+ − CS5_CONFIG .short 0x02CF ; A
+ − CS6_CONFIG .short 0x02C0 ; C Int-RAM 32 Y 0 1
+ − RHEA_CONFIG .short 0x002A ; E ARM -> RHEA/API adaptation
+ − NUM_CS_REGS .equ 8 ; number of Chip Select Config regs to program
+ − .endif
+ − ; 0 to 2, where 0 is highest)
+ −
+ − ;
+ − ;/* End of low-level initialization constants. */
+ − ;
+ − ;
+ − ;/* Define the initialization flag that indicates whether or not all of the
+ − ; default vectors have been loaded during initialization. */
+ − ;
+ − ;INT INT_Loaded_Flag;
+ −
+ − .def _INT_Loaded_Flag
+ − .bss _INT_Loaded_Flag, 4, 4
+ − ;
+ − ;/* Define the vector table */
+ − ;
+ −
+ − .if CHIPSET = 12
+ − .sect ".start"
+ −
+ − .ref _INT_Bootloader_Start
+ −
+ − _ResetVector:
+ − B _INT_Bootloader_Start
+ −
+ − .sect ".indint"
+ −
+ − .def _IndirectVectorTable
+ − _IndirectVectorTable:
+ − LDR PC, [PC, #0x14]
+ − LDR PC, [PC, #0x14]
+ − LDR PC, [PC, #0x14]
+ − LDR PC, [PC, #0x14]
+ − LDR PC, [PC, #0x14]
+ − LDR PC, [PC, #0x14]
+ − LDR PC, [PC, #0x14]
+ −
+ − .word INT_Undef_Inst
+ − .word INT_Swi
+ − .word INT_Abort_Prefetch
+ − .word INT_Abort_Data
+ − .word INT_Reserved
+ − .word INT_IRQ
+ − .word INT_FIQ
+ −
+ − ; CALYPSO PLUS TEST MODE - TO BE ERASED
+ − .sect ".intvecs"
+ −
+ − _ResetVectorTestMode:
+ − B _INT_Bootloader_Start
+ − B INT_Undef_Inst
+ − B INT_Swi
+ − B INT_Abort_Prefetch
+ − B INT_Abort_Data
+ − B INT_Reserved
+ − B INT_IRQ
+ − B INT_FIQ
+ −
+ − .else ; CHIPSET = 12
+ −
+ − .sect ".intvecs"
+ −
+ − .if BOARD = 34
+ − B _INT_Initialize
+ − .elseif BOARD = 35
+ − B _INT_Initialize
+ − .else
+ − .ref _INT_Bootloader_Start
+ −
+ − B _INT_Bootloader_Start
+ − .endif
+ − B INT_Undef_Inst
+ − B INT_Swi
+ − B INT_Abort_Prefetch
+ − B INT_Abort_Data
+ − B INT_Reserved
+ − B Vect_IRQ
+ − .if WCP_PROF = 1
+ − .global _PR_StoreMonteCarloSample
+ −
+ − ; Timing profiler using FIQ - Handle FIQ directly here
+ −
+ − STMFD sp!,{R0-R4, LR} ; Save R0-R4 and LR on FIQ stack
+ −
+ − MOV R0, LR ; Retrieve link register in R0
+ − BL _PR_StoreMonteCarloSample ; Store into ring buffer
+ − BL _IQ_FIQ_isr ; Ack FIQ
+ −
+ − LDMFD sp!,{R0-R4, LR} ; Restore R0-R4 and LR from FIQ stack
+ − SUBS PC, LR, #4 ; return from FIQ
+ − .else
+ − B Vect_FIQ
+ − .endif
+ − .endif ; CHIPSET = 12
+ −
+ − ;
+ − ; .text
+ − ;
+ − ; .ref cinit
+ −
+ − .sect ".inttext"
+ − .global cinit ; Linker symbol for C variable init.
+ −
+ −
+ − ; Address definitions in the section where they are used.
+ −
+ − ;
+ − ;/* Define the global system stack variable. This is setup by the
+ − ; initialization routine. */
+ − ;
+ − ;extern VOID *TCD_System_Stack;
+ − ;
+ − .ref _TCD_System_Stack
+ − .ref _TCT_System_Limit
+ − ;
+ − ;
+ − ;/* Define the global data structures that need to be initialized by this
+ − ; routine. These structures are used to define the system timer management
+ − ; HISR. */
+ − ;
+ − ;extern VOID *TMD_HISR_Stack_Ptr;
+ − ;extern UNSIGNED TMD_HISR_Stack_Size;
+ − ;extern INT TMD_HISR_Priority;
+ − ;
+ − .ref _TMD_HISR_Stack_Ptr
+ − .ref _TMD_HISR_Stack_Size
+ − .ref _TMD_HISR_Priority
+ − ;
+ − ;
+ − ;/* Define extern function references. */
+ − ;
+ − ;VOID INC_Initialize(VOID *first_available_memory);
+ − ;VOID TCT_Interrupt_Context_Save(VOID);
+ − ;VOID TCT_Interrupt_Context_Restore(VOID);
+ − ;VOID TCC_Dispatch_LISR(INT vector_number);
+ − ;VOID TMT_Timer_Interrupt(void);
+ − ;
+ − .ref _INC_Initialize
+ − .ref _TCT_Interrupt_Context_Save
+ − .ref _TCT_Interrupt_Context_Restore
+ − .ref _TCC_Dispatch_LISR
+ − .ref _TMT_Timer_Interrupt
+ −
+ − ;/* Application ISR */
+ − .ref _IQ_IRQ_isr
+ − .ref _IQ_FIQ_isr
+ − ;
+ − ; /* Reference pointers defined by the linker */
+ − ;
+ − .ref .bss
+ − .ref end
+ −
+ − ;
+ − ;/* 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
+ −