|
楼主 |
发表于 2010-8-17 14:09:32
|
显示全部楼层
大家帮忙看看我的启动代码.
; ARM xPSR
ModeClear EQU 0xFFFFFFE0
UsrMode EQU 0x00000010
FIQMode EQU 0x00000011
IRQMode EQU 0x00000012
SvcMode EQU 0x00000013
AbtMode EQU 0x00000017
UndMode EQU 0x0000001B
SysMode EQU 0x0000001F
I_Bit EQU 0x00000080
F_Bit EQU 0x00000040
T_Bit EQU 0x00000020
SR_IF_BITS EQU (I_Bit:or:F_Bit)
; backward compatible synonyms
IRQDBit EQU I_Bit
FIQDBit EQU F_Bit
Mode_USR EQU UsrMode
Mode_FIQ EQU FIQMode
Mode_IRQ EQU IRQMode
Mode_SVC EQU SvcMode
; IF VEGA_BB:LOR:VEGA_TB:LOR:VEGA_XS:LOR:VEGA_LITE:LOR:VEGA_ONE
; IF VEGA_ONE
ICU_BASE EQU 0x01102000 ; Base address, Obj Spec. V0.2 PNX8xxxx
SDC_BASE EQU 0x00200000
GPIO_BASE EQU 0x0111E400
GPIO_DATP EQU 0x0100 ; pin
GPIO_DATW EQU 0x0210 ; word
SCU_BASE EQU 0x0111D800
DAIF_BASE EQU 0x0111CC00
SCU_SYS_PCON EQU SCU_BASE + 0x0C
APU_RANA8 EQU DAIF_BASE + 0x9C
; ENDIF
; ICU offsets
FIQRequest EQU 0x00 ; R-
FIQSource EQU 0x04 ; R-
FIQEnable EQU 0x08 ; R-
FIQClear EQU 0x10 ; -W
FIQEnable_Set EQU 0x14 ; -W
FIQEnable_Clear EQU 0x18 ; -W
IRQRequest EQU 0x20 ; R-
IRQSource EQU 0x24 ; R-
IRQEnable EQU 0x28 ; R-
IRQClear EQU 0x30 ; -W
IRQEnable_Set EQU 0x34 ; -W
IRQEnable_Clear EQU 0x38 ; -W
; backward compatible synonyms
FIQ_CLEAR EQU FIQClear
FIQ_ENBC EQU FIQEnable_Clear
IRQ_CLEAR EQU IRQClear
IRQ_ENBC EQU IRQEnable_Clear
; Vega register values, bits, masks, ..
CLK_IF_Bit EQU 0x08
DCL_EN_Bit EQU 0x20
; IF VEGA_ONE
; IMPORT |Image$$DTCM$$Base|
; ELSE
RAM_Base EQU 0x0400000
; ENDIF
RAM_Limit EQU 0x0040FFF8 ; 64kB ;tc added
IRQ_StackLen EQU 0x080
USR_StackLen EQU 0x400
; IF DF_FIQ_MON
; (4 Priority groups stacking * 8 regs) + Max(Prio0) => 156bytes (0x9C)
FIQ_StackLen EQU 0x0A0
; ELSE
; (4 Priority groups stacking * 6 regs) + Max(Prio0) => 124bytes (0x7C)
;FIQ_StackLen EQU 0x080
; ENDIF
SVC_StackLen EQU 0x000
FIQ_Stack EQU RAM_Limit ; FIQ stack down from top
IRQ_Stack EQU FIQ_Stack-FIQ_StackLen ; IRQ stack follows
SVC_Stack EQU IRQ_Stack-IRQ_StackLen ; followed by SVC stack
USR_Stack EQU SVC_Stack-SVC_StackLen ; followed by USR stack
USR_StackTop EQU USR_Stack-USR_StackLen ; followed by ZI Data
; --- Macro to provide a WEAK dummy function in its own AREA
; the function returns -1 (common rejection code)
MACRO ; (functionName)
dummyFunc $func
AREA DummyArea_$func, CODE
EXPORT $func[WEAK]
$func
IF {CODESIZE}=32
mvn r0,#0
ELSE
mov r0,#0
mvn r0,r0
ENDIF
bx r14
MEND
;;;;;;;;;;;;;;;;;; startup.s ;;;;;;;;;;;;
IF :LNOT:({CODESIZE}=32)
CODE32
ENDIF
AREA RESET, CODE, READONLY
ARM
; == DEFINES ============================================================
; -------------------------------------------------------------------------
; Macro for exception handlers enterring a loop (Not IRQ/FIQ/Reset)
; -------------------------------------------------------------------------
;;;;;;;;;;;;;gm mark ;;;;;;;;;;;
Vectors LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP ; Reserved Vector
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
IRQ_Handler B IRQ_Handler
FIQ_Handler PROC
EXPORT FIQ_Handler [WEAK]
B .
ENDP
Default_Handler PROC
B .
ENDP
; Reset Handler
EXPORT Reset_Handler
Reset_Handler
; --------------------------------------
; Disable IRQs and FIQs
MRS a1,CPSR ; read status register
ORR a1,a1,#SR_IF_BITS ; set I and F bits
MSR CPSR_cf,a1 ; and write back
EXPORT FIQ_Stack
EXPORT IRQ_Stack
SSW_RAM_Limit EQU RAM_Limit
EXPORT SSW_RAM_Limit
SSW_USR_Stack_Limit EQU USR_Stack
EXPORT SSW_USR_Stack_Limit
;VTT_MMI
u32_BootPowerStatus EQU RAM_Limit
EXPORT u32_BootPowerStatus
u32_BootSignature EQU RAM_Limit+4
EXPORT u32_BootSignature
; == Start of code ==========================================================
;----------------------------------------------------------------------------
; The FIQ Interrupt handler should be linked directly on the vectore table
; address 0x1c (last exception entry) to save cycles.
; Installing an exception handler see User Guide 11.4
; ROM start, Vector Table at begin (start ad address 0)
; The RESET entry point
; EXPORT __main
ENTRY
;__main
; IF VEGA_BB:LOR:VEGA_TB:LOR:XS_ON_TB_DEMO:LOR:LITE_ON_TB_DEMO:LOR:VEGA_LITE:LOR:XS_ON_LITEFLASH:LOR:LITE_ON_LITEFLASH
; IF VEGA_ONE ; if needed, add to condition above!
MOV r0, #0x00200000 ; SDC_BASE in r0, FCTR address for VegaOne
; ELSE
;workaround suggested by JWE for TB (???? to be removed for BB ?????)
;the content of address 0x0111de00 should be 0x15 (LDR doesn't work before this)
; MOV r1, #0x0110 ; construct the target addr of PFlashCtrl
; ADD r1, r1, #1 ; due to not be able to use a LDR cmd here
; MOV r0, #0xDE00
; ADD r0, r0, r1, LSL #0x10 ; SDC_BASE in r0, FCTR address for !VegaOne
; ENDIF
MOV r1, #0x15 ; write 0x15 value to FCTR
STR r1, [r0] ; now we can use also ldr commands !!!!
NOP ; give the PFlash contr. a chance
NOP
;add further 7 NOPS
NOP
NOP
NOP
NOP
NOP
NOP
NOP
ADD r0, r0, #0x10 ; handle to FWST
LDR r1,[r0]
SUB r1, r1, #0xC000
CMP r1, #4
BNE GoAhead ; we are from power-up
MOV r1, #0xC000
ADD r1, r1, #3 ; get 3 waitstates for PFlash
STR r1,[r0]
;
GoAhead
; ENDIF
; --- Reset DC-DC Converter , but not for OM6116
; Enable CLK_IF
LDR r0, =SCU_SYS_PCON
LDR r1, [r0]
ORR r2, r1, #CLK_IF_Bit
STR r2, [r0]
; Switch DCDC OFF, wait for transmission, and switch ON again
LDR r3, =APU_RANA8
LDR r4, [r3]
AND r5, r4, #:NOT:DCL_EN_Bit
STR r5, [r3]
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
STR r4, [r3]
; Wait until transmission completed and disable CLK_IF
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
STR r1, [r0]
; --- Initialise stack pointer registers
; Enter FIQ mode and set up the FIQ stack pointer
MOV R0, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; No interrupts
MSR CPSR_cf, R0
LDR R13, =FIQ_Stack
; Enter IRQ mode and set up the IRQ stack pointer
MOV R0, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts
MSR CPSR_cf, R0
LDR R13, =IRQ_Stack
; Set up the SVC stack pointer last and return to SVC mode
MOV R0, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
MSR CPSR_cf, R0
LDR R13, =SVC_Stack
; --- Initialise memory system
; ...
; --- Initialise critical IO devices
; ...
; --- Initialise interrupt system variables here
LDR r0, =ICU_BASE
MVN r2, #0
STR r2, [r0,#FIQ_ENBC]
STR r2, [r0,#FIQ_CLEAR]
STR r2, [r0,#IRQ_ENBC]
STR r2, [r0,#IRQ_CLEAR]
; --- Initialise memory required by C code
; IMPORT |Load$$RO$$Base| ; End of ROM code (=start of ROM data)
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
IMPORT |Image$$RW$$Limit|
IMPORT |Image$$ZI$$Base| ; Base and length of ZI area
IMPORT |Image$$ZI$$Limit|
; IMPORT |Image$$ZI$$Length| ; (but RAM_Base - RAM_Limit is zeroed)
; --- set the ARM9 CP15 reg to use DTCM
MRC p15, 0, r0, c1, c0, 0 ;
ORR r0, r0, #0x0C ; W and D bit in CP15 c1 set (DTCM and ahb buffer enabled)
MCR p15, 0, r0, c1, c0, 0
; --- set ITCM order bit
MRC p15, 1, r0, c15, c1, 0 ; read cp15-c15
ORR r0, r0, #0x40000 ; set bit 18
MCR p15, 1, r0, c15, c1, 0 ; write back
; IMPORT |Image$$DTCM$$Base|
LDR r0, =|Image$$RW$$Base|
LDR r1, =RAM_Limit
MOV r2, #0
ZERORAM
CMP r0, r1
STRCC r2, [r0], #4
BCC ZERORAM
; LDR r0, =|Load$$RW$$Base| ; Get pointer to ROM data
LDR r0,=|Image$$RO$$Limit|;
LDR r1, =|Image$$RW$$Base| ; and RAM copy
LDR r3, =|Image$$ZI$$Base| ; Zero init base => end of RW init
CMP r0, r1 ; Check that they are different
BEQ RWDONE
RWINIT
CMP r1, r3 ; Copy init values for RW data
LDRCC r2, [r0], #4
STRCC r2, [r1], #4
BCC RWINIT
RWDONE
LDR r1, =|SSW_FirstUnusedRAM| ; Base of zero init segment
LDR r2, =0x55555555 ; pattern
LDR r3, =RAM_Limit
MARKSTACK
CMP r1, r3 ; mark stack
STRCC r2, [r1], #4
BCC MARKSTACK
MOV r2, r3 ; clear pattern to prevent beeing stacked
; --- Now change to user mode and set up user mode stack.
MOV R0, #Mode_USR ; IRQ and FIQ enabled
MSR CPSR_cf, R0
LDR sp, =USR_Stack
; --- Dummy access to stack check variables (checked by final link)
LDR R0, =|ROMLimit|
LDR R0, =|RAMLimit|
LDR R0, =|TotalUsedRAM|
; --- Now we enter the C code
IMPORT __main
LDR R0, =__main
BX R0
; IMPORT main_entry
; BL main_entry
; -------------------------------------------------------------------------
; SWI Exception Handler
; -------------------------------------------------------------------------
CODE32
EXPORT p_SWIHandler
p_SWIHandler
;----------------------------------------------------
; SWI 0 disable IRQs => set I_Bit
; SWI 1 enable IRQs => clear I_Bit
; SWI 2 disable FIQs => set F_Bit
; SWI 3 disable FIQs => clear F_Bit
; SWI 4..7 reserved
;----------------------------------------------------
; SWI 8 Go to sleep (Only VegaOne)
; SWI 9..16 reserved
;----------------------------------------------------
; SWI 16..23 Patch mechanism (Only VegaOne)
;----------------------------------------------------
; SWI 24..255 Undefined
;
; assumptions for implementation of p_SWIHandler:
; on entry: I_Bit set, mode=SVC
; SVC stack is not used => sp used as local variable
; only invoked from USR or IRQ application code => only thumb SWI to process
;----------------------------------------------------
GBLL SWI_TONLY
SWI_TONLY SETL {FALSE} ;; set to FALSE for VEGApro
;--- load the SWI number into sp
IF :LNOT:SWI_TONLY
MRS sp, spsr
TST sp, #T_Bit
LDRNEH sp, [lr,#-2]
BICNE sp, sp,#0xFF00
LDREQ sp, [lr,#-4]
BICEQ sp, sp, #0xFF000000
ELSE
LDRH sp, [lr,#-2]
BIC sp, sp,#0xFF00
ENDIF
IRQSwitch
CMP sp, #1
BHI FIQSwitch
MRS sp, spsr
ORRNE sp, sp,#I_Bit ; SWI 0: disable IRQs
ANDEQ sp, sp,#:NOT:I_Bit ; SWI 1: enable IRQs
B ENDSwitch
FIQSwitch
CMP sp, #3
; IF VEGA_ONE ; if needed, add to condition above!
BHI IdleSwitch
; ELSE
; BHI UnrecognisedSWILoop
; ENDIF
MRS sp, spsr
ORRNE sp, sp,#F_Bit ; SWI 2: disable FIQs
ANDEQ sp, sp,#:NOT:F_Bit ; SWI 3: enable FIQs
ENDSwitch
MSR spsr_cf, sp
MOVS pc,lr ; return from SWI
; IF VEGA_ONE ; if needed, add to condition above!
IdleSwitch ; Idle mode!!!!
CMP sp, #8
BHI PatchSwitch
MCR p15, 0, r0, c7, c0, 4
MOVS pc,lr ; return from SWI
PatchRamStart EQU 0x300000
PatchSwitch
AREA ArmAccess, CODE, READONLY
CODE32
;---------------------------------------------------------------------
; u32 p_bbc_getCPSR(void)
;---------------------------------------------------------------------
EXPORT p_bbc_getCPSR
p_bbc_getCPSR
MRS r0,cpsr
bx r14
;---------------------------------------------------------------------
; Dummy data area simulating stack to the linker to allow for memory
; underrun test.
; This area is never used by any program.
;---------------------------------------------------------------------
EXPORT SSW_FirstUnusedRAM
AREA DummyStack, DATA, NOINIT
SSW_FirstUnusedRAM
SPACE USR_StackLen+IRQ_StackLen+FIQ_StackLen
TotalUsedRAM
;---------------------------------------------------------------------
; DebugOnTBRAM data area placed to exactly after the end of the physical
; RAM of the VegaTB. It allows for RAM underrun check by the linker for
; debug builds for XS or Lite where the whole 22kB TB RAM can be used
;---------------------------------------------------------------------
AREA DebugOnTBRAM, DATA, NOINIT
RAMLimit
SPACE 1 ;dummy size of 1, otherwise area overlap is ignored
AREA StartOfRAM, DATA, NOINIT
EXPORT StartOfRAM
RAMStart
; END
AREA JustAfterROM, DATA, NOINIT
ROMLimit
; SPACE 1 ;dummy size of 1, otherwise area overlap is ignored
SPACE 0x80000 ; Due to the 4kB Gap between PROM and FW ROM in the 8001/10/11,
; the symbol to trap memory overlap has to be huge
END |
|