⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fw_utils.s

📁 ARM9基于WINDOWSCE的BSP源代码
💻 S
📖 第 1 页 / 共 3 页
字号:
;
;   The content of this file or document is CONFIDENTIAL and PROPRIETARY
;   to Jade Technologies Co., Ltd.  It is subjected to the terms of a
;   License Agreement between Licensee and Jade Technologies Co., Ltd.
;   restricting among other things, the use, reproduction, distribution
;   and transfer.  Each of the embodiments, including this information 
;   and any derivative work shall retain this copyright notice.
; 
;   Copyright (c) 2004 - 2005 Jade Technologies Co., Ltd. 
;   All rights reserved.
; ----------------------------------------------------------------
; File:     fw_utils.s,v
; Revision: 1.0
; ----------------------------------------------------------------
; $
;
; Module Name:
;
;    fw_utils.s
;
; Abstract:
;
;    This module implements the code necessary to initialize the HW and
;    Kernel interface routines.
;
;    oalfuncs.h contains the C function declarations.
;

;
; This one source file is used to provide Startup code both for the
; Ethernet Boot Loader, and for the WinCE kernel. The default is to
; build for the WinCE kernel
;
    IF :LNOT: :DEF: EBOOT
        GBLL    EBOOT
EBOOT   SETL    {FALSE}
    ENDIF
    IF :LNOT: :DEF: EXEFLASH
        GBLL    EXEFLASH
EXEFLASH SETL    {FALSE}
    ENDIF

        OPT     2       ; disable listing
        INCLUDE kxarm.h
        INCLUDE ssmc.inc
        INCLUDE mpmc.inc
        INCLUDE armmacros.inc
        INCLUDE platform.inc
        INCLUDE sp810.inc   ; System Controller
        INCLUDE sp804.inc   ; Timers
        INCLUDE pl011.inc   ; UARTs
        INCLUDE pl190.inc   ; VIC & SIC
        OPT     1       ; reenable listing

        TEXTAREA 

; **********************************************************************
; *
; * uSecsWait - uses timer2 to wait for a given number of microseconds
; *
; * NOTE: This routine takes no care to preserve current timer state
; *
; * void uSecsWait(unsigned int usecs, unsigned int virtoffset);
; *
; ****************************************************************************

        LEAF_ENTRY uSecsWait
      
        ; check that we are being asked to wait
        cmp     r0, #0

        RETURN_EQ
 
        ; point r1 at timer 2 control registers
        ldr     r2, =PHYS_TIMER2_BASE
        add     r1, r1, r2

        ldr     r2, [r1, #TIMER_Control]
        and     r2, r2, #TIMER_RESERVED_MASK        ; may not modify these bits.

        ; Timer mode: disabled, 32 bit, one-shot, free-running, no int
        orr     r2, r2,  #TIMER_MODE_ONESHOT | TIMER_MODE_32BIT       
        str     r2, [r1, #TIMER_Control]

        ; 
        str     r0, [r1, #TIMER_Load]

        orr     r2, r2,  #TIMER_ENABLE
        str     r2, [r1, #TIMER_Control]

        ; read the current timer register value, and check whether it reached 
        ;  zero
msloop
        ldr     r2, [r1, #TIMER_Value]
        cmp     r2, #0
        bne     msloop
        
        ; OK - turn counter off and return
        ldr     r2, [r1, #TIMER_Control]
        and     r2, r2, #TIMER_RESERVED_MASK        ; may not modify these bits.
        str     r2, [r1, #TIMER_Control]

        RETURN

        ENTRY_END   uSecsWait

; ****************************************************************************


; ****************************************************************************
; * GetPC
; *
; * Used to obtain the current PC value 
; *
; ****************************************************************************

    IF EBOOT :LOR: :LNOT: EXEFLASH
        LEAF_ENTRY GetPC
        mov     r0, pc
        RETURN
        ENTRY_END GetPC   
    ENDIF 


; ****************************************************************************
; * WFI
; *
; * Called by OEMIdle when we are idle.  Stops core until next interrupt
; * This imlementation includes workarounds for cacheable code. 
; * See ARM926EJ-S Rev0.3 Errata List. CP023-PRDC-001555 5.0.
;
; * If the WFI instruction is run from non-cacheable region, and located at an 
; * offset of between 0x3E8 and 0x3F4 (inclusive) from the previous 1KB 
; * boundary, then the WFI will execute with the prefetch buffer in a non-full 
; * state, and low-power state will not be entered correctly.

; * For the workaround to operate correctly, the instruction which disables 
; * the cache, must be offset from the previous 1KB boundary by less then 0x3E4.
; *
; ****************************************************************************

        LEAF_ENTRY WFI

        mov     r0, #0
        mcr     p15, 0, r0, c7, c10, 4      ; Drain write buffer
        mrs     r2, CPSR                    ; Grab CPSR contents
        orr     r3, r2, #3 :SHL: 6          ; Turn off IRQ and FIQ inputs
        mrc     p15, 0, r0, c1, c0, 0       ; Read control register
        bic     r1, r0, #1<<12              ; Clear the Enable I Cache bit
        msr     CPSR_c, r3                  ; Disable interrupts

        ldr     r3, =TestMemoryLocationLabel; If this is >996 bytes or <1020, then  
                                            ; WFI will not function correctly
        and     r3, r3, #0x3FC              
        cmp     r3, #0x3E0                  ; 

; Branch to the second code set if the first one is near the bottom of 1kb
; boundary. This guarantees that WFI instruction will be issued at the proper 
; offset and the processor will be fully switched into core stop mode.
 
        bge     WaitForInterruptOffset      ; Branch if greater than
    
; Put the system into low-power state by issuing Disable I Cache and WFI instructions.

        mov     r3, #0                      ; This needs to be 0 (SBZ) see ARM926EJ-S TRM

TestMemoryLocationLabel
        mcr     p15, 0, r1, c1, c0, 0       ; Disable ICache
        mcr     p15, 0, r3, c7, c0, 4       ; WFI

        b       EndOfWFI
        nop                                 ; Make some space in the code 
        nop                                 ; to bridge the 1024 byte boundary
        nop
        nop

WaitForInterruptOffset                      ; This label is 10 words after the cmp instruction
                                            ; which satisfies the requiremnt of a worst-case
                                            ; alignment where it is 996>WFI<1020 bytes from.
    
        mov     r3, #0                      ; This needs to be 0 (SBZ) see ARM926EJ-S TRM
        mcr     p15, 0, r1, c1, c0, 0       ; Disable I cache
        mcr     p15, 0, r3, c7, c0, 4       ; Wait for Interrupt

EndOfWFI

        mcr     p15, 0, r0, c1, c0, 0       ; Re-enable ICache
        msr     CPSR_c, r2                  ; Re-enable previous interrupt state
        RETURN
        
        ENTRY_END WFI

; ****************************************************************************


  IF :DEF: EXAMPLE_MEMCONFIG

; **** NOTE: ****
; The following is example code for configuring different memory systems it
;  has not been fully tested and is for reference only. 
; You will need to alter and test the following code on your system.
; The Z228 platform has memory already configured on boot-up so we do not
;  perform this.
; ***************

;/* 
; * Configure the MPMC if Multi Port Memory Controller (MPMC) is present
; */
        LEAF_ENTRY ARMConfigMemory
    STR     lr, [sp, #-4]!
    LDR     r0, =PHYS_MPMC_CNTL_BASE
    LDR     r1, [r0, #MPMCPeriphID0]            
    AND     r1, r1,#MPMCPeriphID0_Mask          
    CMP     r1, #MPMCPeriphID0PartNumber0

    LDREQ   r1, [r0, #MPMCPeriphID1]
    ANDEQ   r1, r1,#MPMCPeriphID1_Mask          
    LDREQ   r2, =(MPMCPeriphID1PartNumber1 :OR: MPMCPeriphID1Designer0) 
    CMPEQ   r1, r2

    LDREQ   r1, [r0, #MPMCPeriphID2]
    ANDEQ   r1, r1,#MPMCPeriphID2_Mask          
    LDREQ   r2, =(MPMCPeriphID2Revision :OR: MPMCPeriphID2Designer1)    
    CMPEQ   r1, r2

    LDREQ   r1, [r0, #MPMCPeriphID3]
    ANDEQ   r1, r1,#MPMCPeriphID3_Mask          
    LDREQ   r2, =(MPMCPeriphID3ConfigAHB:OR:MPMCPeriphID3ConfigTIC:OR:MPMCPeriphID3ConfigDataBuf:OR:MPMCPeriphID3ConfigDataBuf) 
    CMPEQ   r1, r2

    BLEQ    MPMCConfigMemory

;/* 
; * Configure the SSMC if Synchronous Static Memory Controller (SSMC) is present
; * This section can be removed if the SSMC is not present
; */
    LDR     r0, =PHYS_SSMC_CNTL_BASE
    LDR     r1, [r0, #SSMCPeriphID0]
    CMP     r1, #SSMC_PL093_PID0
    BLEQ    SSMCConfigMemory

;/* Address remapping example */
 IF :DEF: EXAMPLE_REMAP

;/* Upon power reset, the bootcode is run from address 0x0, due to address 
; * remapping functionality. This aliases the SSMC memory bank 7 to address 
; * 0x0 and the bootloader image is run from this address. As the hardware 
; * does not support remapping we must manually return the PC back to the base 
; * address of bank 7 ie PHYS_FLASH_BASE and execute the boot image from there. 
; */
    BL      RemapSSMC

;/*
; * Switch the remap off in the system controller 
; */
    LDR     r0, =PHYS_SC_BASE    ;load the base address of the System Controller
    LDR     r1, [r0,#0]         ;load contents of SCCTRL register
    LDR     r2, =SSMCRmapClr     ;flag to clear the remap functionality
    ORR     r1, r1,r2           
    STR     r1, [r0,#0]         ;store the value back in SCCTRL register 


;/* Manually copy the bootloader and kernel image into the address 0x0, which 
; * is now the RAM because the remap function has been switched off.
; * 
; * Purely for testing purposes, 10 Mb (0x00A00000) chunk is copied 
; */
CTR EQU     0x00A00000          ;stores the amount of memory that needs to be copied, 10 Mb for now
SRC EQU     PHYS_FLASH_BASE     ;starting address of source block
DST EQU     0x0                 ;starting address of destination block

    LDR     r0, =CTR            
    LDR     r1, =SRC
    LDR     r2, =DST

    MOV     sp, #0x00C00000     ;temporarily set up stack pointer 
    STMFD   sp!, {r3-r10}       ;save the contents of the registers 3-10
    
LOOPMULT                        ;this loop copies memory from SRC location to DST location
    LDMIA   r1!, {r3-r10}       ;load 8 words from source
    STMIA   r2!, {r3-r10}       ;put them at the destination
    SUB     r0, r0, #1          ;decrement the loop counter
    CMP     r0, #0
    BNE     LOOPMULT
                                ;memory copying completed
    LDMFD   sp!, {r3-r10}       ;restore the contents of the registers 3-10


;/* Run image from RAM to allow faster execution */

    BL      RemapRAM

 ENDIF      ;EXAMPLE_REMAP
 
    LDR     lr, [sp], #4
    mov     pc, lr
 
        ENTRY_END   

; ****************************************************************************
; * MPMCConfigMemory
; *
; * Configures the parameters for the Multi-Port Memory Controller, Memory 
; * Bank 0
; * This currently initialises a generic 64Mb SDRAM with address mirroring 
; * disabled and write-protection disabled.
; *
; ****************************************************************************

        LEAF_ENTRY MPMCConfigMemory
 
        STR     lr, [sp, #-4]!
    ;/* Configures the parameters for the MPMC */

    LDR     r0, =PHYS_MPMC_CNTL_BASE    ;/* Load the MPMC physical base address */      
       
    
    ;/* Before starting initialisation force basic configuration*/
    LDR     r1, =( MPMCControl_L_NormalPower :OR: MPMCControl_E_Enable );/* on POR MPMC is enabled */
    STR     r1, [r0,#MPMCControl]                   ;/* r1=0x1 */

    ;/* Ensure that MPMC is idle */
    LDR     r1,=( MPMCStatus_B_Busy )

wait
    LDR     r2,[r0,#MPMCStatus]                 ;/* read MPMC status register */ 
    AND     r2,r2,r1                            ;/* mask */
    CMP     r2,r1                               ;/* keep polling until MPMC is idle */
    BNE     wait                                ;/* branch if result of AND is not zero */

    ;/*
    ; * Now the MPMC can be disabled 
    ; * The MPMC is no longer busy which informs us the buffers are flushed, 
    ; * we can now carry on with initialization
    ; */    
    LDR     r1, =( MPMCControl_L_NormalPower :OR:  MPMCControl_E_Disable )
    STR     r1, [r0,#MPMCControl]               ;/* r1=0x0 */

    ;/* Wait 100ms to ensure clocks have stabilised */
    LDR     r0, =100000
    MOV     r1, #0
    BL      uSecsWait
    LDR     r0, =PHYS_MPMC_CNTL_BASE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -