;----------------------------------------------------------------------------- ; This file contains the startup code used by the ICCARM C compiler. ; ; The modules in this file are included in the libraries, and may be replaced ; by any user-defined modules that define the PUBLIC symbol _program_start or ; a user defined start symbol. ; To override the cstartup defined in the library, simply add your modified ; version to the workbench project. ; ; All code in the modules (except ?RESET) will be placed in the ICODE segment. ; ; $Revision: 1.2.2.1 $ (by IAR) ; ;_____________________________________________________________________________ ; History : Name | Date | Change ; Christoph Meyer | 26.01.07 | Startup code for setting the CPU to ; | 41.78 MHz implemented. ; ;----------------------------------------------------------------------------- ; ; Naming covention of labels in this file: ; ; ?xxx - External labels only accessed from assembler. ; __xxx - External labels accessed from or defined in C. ; xxx - Labels local to one module (note: this file contains ; several modules). ; main - The starting point of the user program. ; ;--------------------------------------------------------------- ; Macros and definitions for the whole file ;--------------------------------------------------------------- ; Mode, correspords to bits 0-5 in CPSR MODE_BITS DEFINE 0x1F ; Bit mask for mode bits in CPSR USR_MODE DEFINE 0x10 ; User mode FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode IRQ_MODE DEFINE 0x12 ; Interrupt Request mode SVC_MODE DEFINE 0x13 ; Supervisor mode ABT_MODE DEFINE 0x17 ; Abort mode UND_MODE DEFINE 0x1B ; Undefined Instruction mode SYS_MODE DEFINE 0x1F ; System mode ; For setting CPU to 41.78 MHz MMR_BASE_0 DEFINE 0xFFFF0000 POWKEY1_OFFSET DEFINE 0x0404 POWCON_OFFSET DEFINE 0x0408 POWKEY2_OFFSET DEFINE 0x040C PLLCFG_Val DEFINE 0x00000000 ;--------------------------------------------------------------- ; ?RESET ; Reset Vector. ; Normally, segment INTVEC is linked at address 0. ; For debugging purposes, INTVEC may be placed at other ; addresses. ; A debugger that honors the entry point will start the ; program in a normal way even if INTVEC is not at address 0. ;--------------------------------------------------------------- MODULE ?RESET COMMON INTVEC:CODE:NOROOT(2) PUBLIC __program_start EXTERN ?cstartup EXTERN undef_handler, swi_handler, prefetch_handler EXTERN data_handler,irq_handler, fiq_handler CODE32 ; Always ARM mode after reset org 0x00 __program_start ldr pc,=?cstartup ; Absolute jump can reach 4 GByte org 0x04 ldr pc,=undef_handler org 0x08 ; ldr pc,=swi_handler org 0x0c ldr pc,=prefetch_handler org 0x10 ldr pc,=data_handler org 0x14 DCD 0x00000000 org 0x18 ldr pc,=irq_handler org 0x1c ldr pc,=fiq_handler ; Constant table entries (for ldr pc) will be placed at 0x20 org 0x20 LTORG ENDMOD ;--------------------------------------------------------------- ; ?CSTARTUP ;--------------------------------------------------------------- MODULE ?CSTARTUP RSEG IRQ_STACK:DATA(2) RSEG FIQ_STACK:DATA(2) RSEG SVC_STACK:DATA:NOROOT(2) RSEG ABT_STACK:DATA:NOROOT(2) RSEG UND_STACK:DATA:NOROOT(2) RSEG CSTACK:DATA(2) RSEG ICODE:CODE:NOROOT(2) PUBLIC ?cstartup EXTERN ?main ; Execution starts here. ; After a reset, the mode is ARM, Supervisor, interrupts disabled. CODE32 ?cstartup ; Add initialization needed before setup of stackpointers here ; Initialize the stack pointers. ; The pattern below can be used for any of the exception stacks: ; FIQ, IRQ, SVC, ABT, UND, SYS. ; The USR mode uses the same stack as SYS. ; The stack segments must be defined in the linker command file, ; and be declared above. mrs r0,cpsr ; Original PSR value bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#IRQ_MODE ; Set IRQ mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(IRQ_STACK) & 0xFFFFFFF8 ; End of IRQ_STACK bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#FIQ_MODE ; Set FIQ mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(FIQ_STACK) & 0xFFFFFFF8 ; End of FIQSTACK bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#ABT_MODE ; Set ABT mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(ABT_STACK) & 0xFFFFFFF8 ; End of ABTSTACK bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#UND_MODE ; Set UND mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(UND_STACK) & 0xFFFFFFF8 ; End of UNDSTACK bic r0,r0,#MODE_BITS ; Clear the mode bits orr r0,r0,#SYS_MODE ; Set System mode bits msr cpsr_c,r0 ; Change the mode ldr sp,=SFE(CSTACK) & 0xFFFFFFF8 ; End of CSTACK ; Add more initialization here ; Enable IRQ and FIQ interrupts mrs r0,cpsr ; Original PSR value bic r0,r0,#0xC0 orr r0,r0,#IRQ_MODE ; Set IRQ mode bits msr cpsr_c,r0 ; Settin the CPU to 41.78 MHz LDR R0, =MMR_BASE_0 MOV R1, #0x01 STR R1, [R0,#POWKEY1_OFFSET] MOV R1, #PLLCFG_Val STR R1, [R0,#POWCON_OFFSET] MOV R1, #0xF4 STR R1, [R0,#POWKEY2_OFFSET] ; Continue to ?main for more IAR specific system startup ldr r0,=?main bx r0 LTORG ENDMOD END