This repository has been archived on 2023-11-05. You can view files and clone it, but cannot push or open issues or pull requests.
FreeRTOS-Kernel/Demo/ARM7_STR71x_IAR/cstartup.s79
2006-05-02 09:39:15 +00:00

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