You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
8.2 KiB
Plaintext
213 lines
8.2 KiB
Plaintext
;-----------------------------------------------------------------------------
|
|
; 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.1 $
|
|
;
|
|
;-----------------------------------------------------------------------------
|
|
|
|
;
|
|
; 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
|
|
;---------------------------------------------------------------
|
|
|
|
|
|
; --- Standard definitions of mode bits and interrupt (I & F) flags in PSRs
|
|
|
|
|
|
|
|
Mode_USR DEFINE 0x10
|
|
Mode_FIQ DEFINE 0x11
|
|
Mode_IRQ DEFINE 0x12
|
|
Mode_SVC DEFINE 0x13
|
|
Mode_ABT DEFINE 0x17
|
|
Mode_UNDEF DEFINE 0x1B
|
|
Mode_SYS DEFINE 0x1F ; available on ARM Arch 4 and later
|
|
|
|
I_Bit DEFINE 0x80 ; when I bit is set, IRQ is disabled
|
|
F_Bit DEFINE 0x40 ; when F bit is set, FIQ is disabled
|
|
|
|
|
|
; --- System memory locations
|
|
|
|
RAM_Base DEFINE 0x20000000
|
|
RAM_Limit DEFINE 0x20010000
|
|
SRAM_Base DEFINE 0x60000000
|
|
|
|
SVC_Stack DEFINE RAM_Limit ; 512 byte SVC stack at
|
|
; top of memory - used by kernel.
|
|
IRQ_Stack DEFINE SVC_Stack-512 ; followed by IRQ stack
|
|
USR_Stack DEFINE IRQ_Stack-512 ; followed by USR stack. Tasks run in
|
|
; system mode but task stacks are allocated
|
|
; when the task is created.
|
|
FIQ_Stack DEFINE USR_Stack-8 ; followed by FIQ stack
|
|
ABT_Stack DEFINE FIQ_Stack-8 ; followed by ABT stack
|
|
UNDEF_Stack DEFINE ABT_Stack-8 ; followed by UNDEF stack
|
|
|
|
EIC_Base_addr DEFINE 0xFFFFF800 ; EIC base address
|
|
ICR_off_addr DEFINE 0x00 ; Interrupt Control register offset
|
|
CIPR_off_addr DEFINE 0x08 ; Current Interrupt Priority Register offset
|
|
IVR_off_addr DEFINE 0x18 ; Interrupt Vector Register offset
|
|
FIR_off_addr DEFINE 0x1C ; Fast Interrupt Register offset
|
|
IER_off_addr DEFINE 0x20 ; Interrupt Enable Register offset
|
|
IPR_off_addr DEFINE 0x40 ; Interrupt Pending Bit Register offset
|
|
SIR0_off_addr DEFINE 0x60 ; Source Interrupt Register 0
|
|
|
|
EMI_Base_addr DEFINE 0x6C000000 ; EMI base address
|
|
BCON0_off_addr DEFINE 0x00 ; Bank 0 configuration register offset
|
|
BCON1_off_addr DEFINE 0x04 ; Bank 1 configuration register offset
|
|
BCON2_off_addr DEFINE 0x08 ; Bank 2 configuration register offset
|
|
BCON3_off_addr DEFINE 0x0C ; Bank 3 configuration register offset
|
|
|
|
GPIO2_Base_addr DEFINE 0xE0005000 ; GPIO2 base address
|
|
PC0_off_addr DEFINE 0x00 ; Port Configuration Register 0 offset
|
|
PC1_off_addr DEFINE 0x04 ; Port Configuration Register 1 offset
|
|
PC2_off_addr DEFINE 0x08 ; Port Configuration Register 2 offset
|
|
PD_off_addr DEFINE 0x0C ; Port Data Register offset
|
|
|
|
CPM_Base_addr DEFINE 0xA0000040 ; CPM Base Address
|
|
BOOTCONF_off_addr DEFINE 0x10 ; CPM - Boot Configuration Register
|
|
FLASH_mask DEFINE 0x0000 ; to remap FLASH at 0x0
|
|
RAM_mask DEFINE 0x0002 ; to remap RAM at 0x0
|
|
EXTMEM_mask DEFINE 0x0003 ; to remap EXTMEM at 0x0
|
|
|
|
;---------------------------------------------------------------
|
|
; ?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
|
|
CODE32 ; Always ARM mode after reset
|
|
|
|
__program_start
|
|
ldr pc,=?cstartup ; Absolute jump can reach 4 GByte
|
|
b ?cstartup ; Relative branch allows remap, limited to 32 MByte
|
|
|
|
LTORG
|
|
ENDMOD
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
; ?CSTARTUP
|
|
;---------------------------------------------------------------
|
|
MODULE ?CSTARTUP
|
|
|
|
; RSEG IRQ_STACK:DATA(2)
|
|
; RSEG SVC_STACK:DATA:NOROOT(2)
|
|
; RSEG CSTACK:DATA(2)
|
|
RSEG ICODE:CODE:NOROOT(2)
|
|
PUBLIC ?cstartup
|
|
EXTERN ?main
|
|
|
|
|
|
|
|
|
|
CODE32
|
|
?cstartup
|
|
|
|
|
|
NOP ; Wait for OSC stabilization
|
|
NOP
|
|
NOP
|
|
NOP
|
|
NOP
|
|
NOP
|
|
NOP
|
|
NOP
|
|
NOP
|
|
|
|
|
|
/* Setup a stack for each mode - note that this only sets up a usable stack
|
|
for system/user, SWI and IRQ modes. Also each mode is setup with
|
|
interrupts initially disabled. */
|
|
msr CPSR_c, #Mode_UNDEF|I_Bit|F_Bit /* Undefined Instruction Mode */
|
|
LDR SP, =UNDEF_Stack
|
|
|
|
msr CPSR_c, #Mode_ABT|I_Bit|F_Bit /* Abort Mode */
|
|
LDR SP, =ABT_Stack
|
|
|
|
msr CPSR_c, #Mode_FIQ|I_Bit|F_Bit /* FIQ Mode */
|
|
LDR SP, =FIQ_Stack
|
|
|
|
msr CPSR_c, #Mode_IRQ|I_Bit|F_Bit /* IRQ Mode */
|
|
LDR SP, =IRQ_Stack
|
|
|
|
msr CPSR_c, #Mode_SVC|I_Bit|F_Bit /* Supervisor Mode */
|
|
LDR SP, =SVC_Stack
|
|
|
|
msr CPSR_c, #Mode_SYS|I_Bit|F_Bit /* System Mode */
|
|
LDR SP, =USR_Stack
|
|
|
|
/* We want to start in supervisor mode. Operation will switch to system
|
|
mode when the first task starts. */
|
|
msr CPSR_c, #Mode_SVC|I_Bit|F_Bit
|
|
|
|
|
|
IMPORT T0TIMI_Addr
|
|
|
|
EIC_INIT
|
|
LDR r3, =EIC_Base_addr
|
|
LDR r4, =0x00000000
|
|
STR r4, [r3, #ICR_off_addr] ; Disable FIQ and IRQ
|
|
STR r4, [r3, #IER_off_addr] ; Disable all channels interrupts
|
|
LDR r4, =0xFFFFFFFF
|
|
STR r4, [r3, #IPR_off_addr] ; Clear all IRQ pending bits
|
|
LDR r4, =0x0C
|
|
STR r4, [r3, #FIR_off_addr] ; Disable FIQ channels and clear FIQ pending bits
|
|
LDR r4, =0x00000000
|
|
STR r4, [r3, #CIPR_off_addr] ; Reset the current priority register
|
|
LDR r4, =0xE59F0000
|
|
STR r4, [r3, #IVR_off_addr] ; Write the LDR pc,pc,#offset instruction code in IVR[31:16]
|
|
LDR r2, =32 ; 32 Channel to initialize
|
|
LDR r0, =T0TIMI_Addr ; Read the address of the IRQs address table
|
|
LDR r1, =0x00000FFF
|
|
AND r0,r0,r1
|
|
LDR r5, =SIR0_off_addr ; Read SIR0 address
|
|
SUB r4,r0,#8 ; subtract 8 for prefetch
|
|
LDR r1, =0xF7E8 ; add the offset to the 0x00000000 address(IVR address + 7E8 = 0x00000000)
|
|
; 0xF7E8 used to complete the LDR pc,pc,#offset opcode
|
|
ADD r1,r4,r1 ; compute the jump offset
|
|
EIC_INI MOV r4, r1, LSL #16 ; Left shift the result
|
|
STR r4, [r3, r5] ; Store the result in SIRx register
|
|
ADD r1, r1, #4 ; Next IRQ address
|
|
ADD r5, r5, #4 ; Next SIR
|
|
SUBS r2, r2, #1 ; Decrement the number of SIR registers to initialize
|
|
BNE EIC_INI ; If more then continue
|
|
|
|
|
|
ldr r0,=?main
|
|
bx r0
|
|
|
|
LTORG
|
|
|
|
ENDMOD
|
|
|
|
|
|
END
|
|
|
|
|