target.s
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· S 代码 · 共 1,283 行 · 第 1/4 页
S
1,283 行
IF CACHE_SUPPORTED = 1
SET_ICACHE $tmp2
SET_WBUFFER $tmp2
; Cannot use Data Cache without MMU
IF ENABLE_MMU = 1
SET_DCACHE $tmp2
ENDIF
ENDIF ; CACHE_SUPPORTED
ORR $tmp1, $tmp1, $tmp2
IF {ENDIAN} = "big"
SET_BIGEND $tmp1
ENDIF ; BIG_ENDIAN
WRMMU_STATE $tmp1 ; Update MMU state
NOP
NOP
NOP
MOV $tmp1, #6 ; 110, RG-
DO_DEBUG $tmp1, $tmp2
MEND
; ---------------------------------------------------------------------
; INITTIMER
; ---------
; This macro is provided purely as a holder for any code that
; may be required to initialise a hardware timer as part of
; the reset sequence. Angel does not need this; it initialises
; any timer required in other ways.
; However, under exceptional circumstances
; special code may be required to ensure that Angel starts
; cleanly and that later application specific code can have
; full control of the timer.
;
MACRO
$label INITTIMER $w1, $w2
; Last access to LEDs is here, turn them all off..
MOV $w1, #0
SET_LEDS $w1, $w2
MEND
; ---------------------------------------------------------------------
; REVERSE
; -------
; Quick word byte-order reversal macro. Handy for endian stuff.
MACRO
$label REVERSE $w1, $w2 ; w1: D C B A
EOR $w2, $w1, $w1, ROR #16 ; w2: D^B, C^A, B^D, A^C
BIC $w2, $w2, #0xff0000 ; w2: D^B, 0 , B^D, A^C
MOV $w1, $w1, ROR #8 ; w1: A D C B
EOR $w1, $w1, $w2, LSR #8 ; w2>>8: 0 D^B 0 B^D
MEND ; w1: A B C D
; ---------------------------------------------------------------------
; GETSOURCE ** ANGEL SPECIFIC **
; ---------
; This macro is used to read the current interrupt source
; activity status for the Angel device driver interrupts.
;
; It can return (in $re):
;
; -1 - Ghost Interrupt (no Interrupt source active)
; DE_NUM_INT_HANDLERS - Int. source not recognised
; IH_<xxx> - IntHandlerID (from devconf.h) of Interrupt source
;
THREE_ARG_GETSOURCE EQU 1
MACRO
$label GETSOURCE $re, $w1, $w2
$label LDR $w1, =INTEGRATOR_HDR_BASE
LDR $w1, [$w1, #INTEGRATOR_HDR_STAT_OFFSET] ; Get contents of HDR_STAT
LDR $w2, =INTEGRATOR_IC_BASE ; Get base address of the interrupt controller
AND $w1, $w1, #3 ; Mask off header number from HDR_STAT
ADD $w2, $w2, $w1, LSL #6 ; Calculate address of interrupt controller
IF HANDLE_INTERRUPTS_ON_IRQ <> 0
; get the IRQ status from the interrupt controller
LDR $w1, [$w2, #IRQ_STATUS] ; Read IRQ status
; set result to -1, so if no other result is set (& so have a ghost int)
; we return -1 as required.
MVN $re, #0
; Now test for specific interrupts. Interrupts tested for
; later are given higher priority.
IF TIMER_SUPPORTED <> 0
TST $w1, #IRQMASK_TIMERINT2
MOVNE $re, #IH_TIMER
ENDIF
IF (PCI_SUPPORTED > 0)
TST $w1, #IRQMASK_PCIINT0
MOVNE $re, #IH_PCI0
TST $w1, #IRQMASK_PCIINT1
MOVNE $re, #IH_PCI1
TST $w1, #IRQMASK_PCIINT2
MOVNE $re, #IH_PCI2
TST $w1, #IRQMASK_PCIINT3
MOVNE $re, #IH_PCI3
ENDIF
IF ((AMBAUART_NUM_PORTS > 1) :LOR: (LOGTERM_DEBUGGING <> 0))
TST $w1, #IRQMASK_UARTINT1
MOVNE $re, #IH_AMBAUART_B
ENDIF
TST $w1, #IRQMASK_UARTINT0
MOVNE $re, #IH_AMBAUART_A
ENDIF ; HANDLE_INTERRUPTS_ON_IRQ
IF HANDLE_INTERRUPTS_ON_FIQ <> 0
; get the FIQ status from the interrupt controller, which is 0x400 above IRQ
LDR $w1, [$w2, #FIQ_STATUS]
; Now test for specific interrupts. Interrupts tested for
; later are given higher priority.
IF TIMER_SUPPORTED <> 0
TST $w1, #FIQMASK_TIMERINT2
MOVNE $re, #IH_TIMER
ENDIF
TST $w1, #FIQMASK_UARTINT0
MOVNE $re, #IH_AMBAUART_A
ENDIF ; HANDLE_INTERRUPTS_ON_FIQ <> 0
MEND
; ---------------------------------------------------------------------
; READ_INT
; --------
; uHAL macro to read which interrupt(s) is active (result in $w1)
MACRO
$label READ_INT $w1, $w2, $w3
;
; First we need to calculate the address of the
; interrupt controller for this header.
;
LDR $w1, =INTEGRATOR_HDR_BASE
LDR $w1, [$w1, #INTEGRATOR_HDR_STAT_OFFSET] ; Get contents of HDR_STAT
LDR $w2, =INTEGRATOR_IC_BASE ; Get base address of the interrupt controller
AND $w1, $w1, #3 ; Mask off header number from HDR_STAT
LDR $w1, [$w2, $w1, LSL #6] ; Read interrupts
BIC $w1, $w1, #((:NOT:IRQMASK_ALL) :AND: 0xFF000000) ; Clear non-valid bits
BIC $w1, $w1, #((:NOT:IRQMASK_ALL) :AND: 0x00FF0000) ; Clear non-valid bits
MEND
; ---------------------------------------------------------------------
; CACHE_IBR ** ANGEL SPECIFIC **
; ---------
; This macro implements an instruction barrier for a range of addresses
; (i.e. it makes instruction and data memory coherent for this range)
; w1 contains the start of the range , w2 the next address after the end
; Note that w1 will be corrupted
MACRO
$label CACHE_IBR $w1, $w2, $temp, $temp2
IF CACHE_SUPPORTED = 1
IMPORT Angel_EnterSVC
IMPORT Angel_ExitToUSR
ASSERT ( $w1 = r0 )
; Save old mode, protect lr from the SWI
STMFD sp!, {lr}
BL Angel_EnterSVC
; Clean the Dcache entries
L25
WRCACHE_CleanDCentry $w1
ADD $w1, $w1, #32
CMP $w1, $w2
BLT L25
; Drain the write buffer
WRCACHE_DrainWriteBuffer $w1
; Flush the Icache
MOV $w1, #0
WRCACHE_FlushIC $w1
; Clear the pipeline..
NOP
NOP
NOP
BL Angel_ExitToUSR
; Restore mode, lr
LDMFD sp!, {lr}
ENDIF
MEND
MACRO
$label DISABLE_INTS $w1, $w2
;
; First we need to calculate the address of the
; interrupt controller for this header.
;
LDR $w1, =INTEGRATOR_HDR_BASE
LDR $w1, [$w1, #INTEGRATOR_HDR_STAT_OFFSET] ; Get contents of HDR_STAT
LDR $w2, =INTEGRATOR_IC_BASE ; Get base address of the interrupt controller
AND $w1, $w1, #3 ; Mask off header number from HDR_STAT
ADD $w2, $w2, $w1, LSL #6 ; Calculate address of interrupt controller
LDR $w1, =0xFFFFFFFF
STR $w1, [$w2, #IRQ_ENABLE_CLEAR] ; Clear all IRQ bits
STR $w1, [$w2, #FIQ_ENABLE_CLEAR] ; Clear all FIQ bits
;
; Explicitly disable the UARTs (COM1 and COM2) from interrupting
; This code relies on the fact that all the UART registers are
; mapped into seperate dwords.
;
LDR $w1, =INTEGRATOR_UART0_BASE
LDR $w2, =0 ; disable interrupt
STRB $w2, [$w1, #AMBA_UARTCR]
LDR $w1, =INTEGRATOR_UART1_BASE
LDR $w2, =0 ; disable interrupt
STRB $w2, [$w1, #AMBA_UARTCR]
MEND
; ---------------------------------------------------------------------
; uHAL macro to initialise external interrupts when running standalone
MACRO
$label INIT_INTS $w1, $w2, $w3
IF :LNOT: :DEF: SEMIHOSTED
DISABLE_INTS $w1, $w2
ENDIF
MEND
; ---------------------------------------------------------------------
; ---------------------------------------------------------------------
; Macro used for debugging without having target-specific code in uHAL
MACRO
$label DO_DEBUG $w1, $w2, $w3
IF :DEF: DEBUG
SET_LEDS $w1, $w2 ; Simple LED lighting
ENDIF
MEND
; ---------------------------------------------------------------------
; macro to set the LEDs to the value given in $w1
; NOTE: this should be the same as SetLEDs in driver.s
MACRO
$label SET_LEDS $w1, $w2
;
; Mask off any invalid bits
;
AND $w1, $w1, #0xF
;
; Poll the scan in progress bit
;
; If the H/W is in the process of writing to the LED's then writing
; to the control register will screw things up
;
L26 LDR $w2, =INTEGRATOR_DBG_BASE
LDR $w2, [$w2, #INTEGRATOR_DBG_ALPHA_OFFSET]
TST $w2, #1
BNE L26
;
; Now write to the LED's
;
LDR $w2, =INTEGRATOR_DBG_BASE
STRB $w1, [$w2, #INTEGRATOR_DBG_LEDS_OFFSET]
MEND
; ---------------------------------------------------------------------
ENDIF ; INTEGRATOR_target_s
IF :DEF: OPT
OPT (old_opt) ; restore previous listing options
ENDIF
; ---------------------------------------------------------------------
END
; EOF target.s
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?