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 + -
显示快捷键?