target.s

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· S 代码 · 共 1,283 行 · 第 1/4 页

S
1,283
字号
        ;
        ; Processor    Core    Memory Bus   System Bus   PCI Bus
        ; =========    ====    ==========   ==========   =======
        ; Unknown      40MHz      20MHz        20MHz      33MHz
        ; ARM720T      50MHz      40MHz        20MHz      33MHz
        ; ARM740T      50MHz      40MHz        20MHz      33MHz
        ; ARM920T     100MHz      40MHz        20MHz      33MHz
        ; ARM940T     100MHz      40MHz        20MHz      33MHz
        ;
        MACRO
        SETUP_DEFAULT_CLOCKS    $w1, $w2, $w3

        ;
        ; Read HDR_PROC register, if this is non zero then there is no
        ; coprocessor, in this case use the default settings.
        ;
        LDR     $w2, =(INTEGRATOR_HDR_OSC_CORE_40MHz :OR: INTEGRATOR_HDR_OSC_MEM_20MHz)
        LDR     $w1, =INTEGRATOR_HDR_BASE
        LDR     $w3, [$w1, #INTEGRATOR_HDR_PROC_OFFSET]
        CMP     $w3, #0
        BNE     L6

        ; Get the processor ID. The RDCPU_ID macro will always return
        ; something, even for CPUs without a coprocessor.
        ;
        ; If the processor type is not recognised then the default settings
        ; will be used.
        RDCPU_ID        $w1, $w3
        CMP     $w3, #0x720             ; Is this a 720
        CMPNE   $w3, #0x740             ; or a 740
        LDREQ   $w2, =(INTEGRATOR_HDR_OSC_CORE_50MHz :OR: INTEGRATOR_HDR_OSC_MEM_40MHz)
        BEQ     L6

        CMP     $w3, #0x920             ; Is this a 920
        CMPNE   $w3, #0x940             ; or a 940
        LDREQ   $w2, =(INTEGRATOR_HDR_OSC_CORE_100MHz :OR: INTEGRATOR_HDR_OSC_MEM_40MHz)
        BEQ     L6

        CMP     $w3, #0xa20             ; Is this a 1020
        LDREQ   $w2, =(INTEGRATOR_HDR_OSC_CORE_80MHz :OR: INTEGRATOR_HDR_OSC_MEM_40MHz)

;
; default value
;
        LDRNE   $w2, =(INTEGRATOR_HDR_OSC_CORE_30MHz :OR: INTEGRATOR_HDR_OSC_MEM_20MHz)

L6
        ;
        ; Write clock settings
        ;
        LDR     $w1, =INTEGRATOR_HDR_BASE
        LDR     $w3, =0xA05F
        STR     $w3, [$w1, #INTEGRATOR_HDR_LOCK_OFFSET]
        STR     $w2, [$w1, #INTEGRATOR_HDR_OSC_OFFSET]
        MOV     $w2, #0
        STR     $w2, [$w1, #INTEGRATOR_HDR_LOCK_OFFSET]

        ;
        ; Set up System BUS and PCI clocks
        ;
        LDR     $w1, =INTEGRATOR_SC_BASE
        STR     $w3, [$w1, #INTEGRATOR_SC_LOCK_OFFSET]
        LDR     $w2, =(INTEGRATOR_SC_OSC_SYS_20MHz :OR: INTEGRATOR_SC_OSC_PCI_33MHz)
        STR     $w2, [$w1, #INTEGRATOR_SC_OSC_OFFSET]
        MOV     $w2, #0
        STR     $w2, [$w1, #INTEGRATOR_SC_LOCK_OFFSET]

        MEND



        ; ---------------------------------------------------------------------
        ; INIT_STATIC_MEMORY
        ; ------------------
        ; Macro to initialise static memory (Flash, ROM and SRAM) on startup.
        ;
        MACRO
        INIT_STATIC_MEMORY      $w1, $w2, $w3

        ;
        ; Set up External Bus Interface (this is where the boot ROM and Flash live).
        ;
        LDR     $w1, =INTEGRATOR_EBI_BASE

        ;
        ; CS0 - ROM (Boot Flash)
        ;
        LDR     $w2, =(INTEGRATOR_EBI_8_BIT :OR: INTEGRATOR_EBI_WS_3)
        STR     $w2, [$w1, #INTEGRATOR_EBI_CSR0_OFFSET]

        ;
        ; CS1 - Flash (Application Flash)
        ;
        LDR     $w2, =(INTEGRATOR_EBI_32_BIT :OR: INTEGRATOR_EBI_WS_3)
        STR     $w2, [$w1, #INTEGRATOR_EBI_CSR1_OFFSET]
        
        ;
        ; CS2 - SSRAM (Not on Rev A Boards)
        ;
        LDR     $w2, =(INTEGRATOR_EBI_32_BIT :OR: INTEGRATOR_EBI_WRITE_ENABLE :OR: INTEGRATOR_EBI_SYNC :OR: INTEGRATOR_EBI_WS_2)
        STR     $w2, [$w1, #INTEGRATOR_EBI_CSR2_OFFSET]
        
        ;
        ; CS3 - Unused (Set up for debug)
        ;
        LDR     $w2, =(INTEGRATOR_EBI_8_BIT :OR: INTEGRATOR_EBI_WRITE_ENABLE)
        STR     $w2, [$w1, #INTEGRATOR_EBI_CSR3_OFFSET]

        MEND

        ; ---------------------------------------------------------------------
        ; INIT_RAM
        ; --------
        ; ANGEL and uHAL macro to initialise memory on startup.

        MACRO
        INIT_RAM        $w1, $w2, $w3

;;        VALIDATE_PROCESSOR      $w1, $w2, $w3

        SETUP_ASYNC_CLOCKS      $w1, $w2

        ;
        ; No longer try and set the clocks as it overridge the clock
        ; setting in the boot monitor/switcher.
        ;
        ; SETUP_DEFAULT_CLOCKS  $w1, $w2, $w3

        INIT_STATIC_MEMORY      $w1, $w2, $w3

        ;
        ; Size SDRAM 
        ;
        ; Check to see if the SPD data has been loaded.  If the load has 
        ; not completed we will loop upto 64K times before giving up.
        ;
        LDR     $w1, =INTEGRATOR_HDR_SDRAM      ; Load address of HDR_SDRAM
        MOV     $w2, #0x10000           ; Load count

L7      LDR     $w3, [$w1]              ; Load contents of HDR_SDRAM
        TST     $w3, #INTEGRATOR_HDR_SDRAM_SPD_OK ; Check to see if SPD data is loaded
        BNE     L8
        SUBS    $w2, $w2, #1            ; Decrement the count
        BGT     L7                      ; Try again     
        B       L10

        ;
        ; Verify the SPD checksum
        ;
L8      LDR     $w1, =INTEGRATOR_HDR_SPDBASE    ; Load address of the base of SPD data
        MOV     $w3, #0

L9      LDRB    $w2, [$w1], #1          ; Load byte
        ADD     $w3, $w3, $w2           ; Add to checksum
        LDR     $w2, =(INTEGRATOR_HDR_SPDBASE + 62) ; Have we got to byte 62
        CMP     $w1, $w2
        BLS     L9

        LDR     $w1, =INTEGRATOR_HDR_SPDBASE    ; Load address of the base of SPD data
        LDRB    $w2, [$w1, #63]         ; Get checksum from SPD
        AND     $w3, $w3, #0xFF         ; Mask out calculated checksum
        CMP     $w2, $w3                ; Are they the same

;
; We will no longer fail if the checksum calculation fails as we have
; found some DIMM's that do not have a valid checksum.
;
;       BNE     L10


        ;
        ; Calculate the memory size from the SPD data.
        ;
        LDRB    $w2, [$w1, #31]         ; Get Module Bank Density
        MOV     $w2, $w2, LSL #2        ; Multiply by 4
        LDRB    $w3, [$w1, #5]          ; Get Number of Banks
        MULS    $w2, $w3, $w2           ; Multiple together to get size in MBytes
        BEQ     L10                     ; If zero then something has gone wrong

        ;
        ; The maximum SDRAM DIMM supported is 256M
        ;
        CMP     $w2, #256
        BGT     L10

        ;
        ; We need to convert the size in MBytes to the value the value
        ; to write to the MEMSIZE field of HDR_SDRAM.  The formula to do
        ; this is as follows -
        ;
        ;       MEMSIZE = LOG2(SizeInMB) - 4
        ;
        ; All the sizes that are supported are powers of 2 so a simple
        ; algorithm to find LOG2 of number is to count the number of trailing
        ; zeros.
        ;
        MOV     $w1, #0                 ; Initialise the counter
L11     TST     $w2, #1                 ; Is the bottom bit set of the size varible
        MOVEQ   $w2, $w2, LSR #1        ; If not set then divide by 2
        ADDEQ   $w1, $w1, #1            ; If not set then increment the counter
        BEQ     L11                     ; If not set then loop

        CMP     $w2, #1                 ; $w2 should now contain 1
        BNE     L10                     ; If it doesn't then something has gone wrong

        LDR     $w2, =INTEGRATOR_HDR_BASE ; Load base address of header registers
        LDR     $w3, [$w2, #INTEGRATOR_HDR_SDRAM_OFFSET] ; Load contents of HDR_SDRAM
        AND     $w3, $w3, #3            ; Clear the everything expect CASLAT
        SUBS    $w1, $w1, #4            ; Subtract 4 from the number of trailing bits
        BMI     L10                     ; If negative then something has gone wrong
        ORR     $w3, $w3, $w1, LSL #2   ; Merge it into contents of HDR_SDRAM

        LDRB    $w1, [$w2, #(INTEGRATOR_HDR_SPDBASE_OFFSET + 3)] ; No. of Rows
        AND     $w1, $w1, #0xF          ; Only want bottom 4 bits
        ORR     $w3, $w3, $w1, LSL #8   ; Merge into HDR_SDRAM

        LDRB    $w1, [$w2, #(INTEGRATOR_HDR_SPDBASE_OFFSET + 4)] ; No. of Columns
        AND     $w1, $w1, #0xF          ; Only want bottom 4 bits
        ORR     $w3, $w3, $w1, LSL #12  ; Merge into HDR_SDRAM

        LDRB    $w1, [$w2, #(INTEGRATOR_HDR_SPDBASE_OFFSET + 5)] ; No. of Banks
        AND     $w1, $w1, #0xF          ; Only want bottom 4 bits
        ORR     $w3, $w3, $w1, LSL #16  ; Merge into HDR_SDRAM

        STR     $w3, [$w2, #INTEGRATOR_HDR_SDRAM_OFFSET] ; Write back to HDR_SDRAM

        ;
        ; Now calculate the size of memory in bytes, this is done by
        ; shifting 1 by MEMSIZE + 24.  The magic number 24 is the 4 we
        ; subtracted earlier plus 20 to get the value is bytes (2^20
        ; being 1 Mbyte).
        ;
        MOV     $w1, $w3, LSR #2        ; Need to extract MEMSIZE from the
        AND     $w1, $w1, #0x7          ;  the value we wrote to HDR_SDRAM

        MOV     $w2, #1                 ; Load 1
        ADD     $w1, $w1, #24           ; Add 24 to the MEMSIZE value
        MOV     $w1, $w2, LSL $w1       ; Shift 1 by (24 + MEMSIZE)
        B       L12

L10     MOV     $w1, #0                 ; Could not find any good DRAM
        
L12     CMP     $w1, #SZ_256K           ; We always have the 256K SSRAM
        MOVMI   $w1, #SZ_256K           ; So always return a minimum of 256K
        MOV     $w3, $w1                ; Need to return size in both these registers

        MEND


        ; ---------------------------------------------------------------------
        ; SETUP_PCI
        ; ---------
        ; Setup the PCI.  Assumes that we're running the V3 as host.
        ;
        ; The V3 PCI interface chip in Integrator provides several windows from
        ; local bus memory into the PCI memory areas.   Unfortunately, there
        ; are not really enough windows for our usage, therefore we reuse 
        ; one of the windows for access to PCI configuration space.  The
        ; memory map is as follows:
        ; 
        ;       Local Bus Memory         Usage
        ; 
        ;       80000000 - 8FFFFFFF      PCI memory.  256M non-prefetchable
        ;       90000000 - 9FFFFFFF      PCI memory.  256M prefetchable
        ;       B0000000 - B0FFFFFF      PCI IO.  16M
        ;       B8000000 - B8FFFFFF      PCI Configuration. 16M
        ; 
        ; There are three V3 windows, each described by a pair of V3 registers.
        ; These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2.
        ; Base0 and Base1 can be used for any type of PCI memory access.   Base2
        ; can be used either for PCI I/O or for I20 accesses.  By default, uHAL
        ; uses this only for PCI IO space.
        ; 
        ; PCI Memory is mapped so that assigned addresses in PCI Memory match
        ; local bus memory addresses.  In other words, if a PCI device is assigned
        ; address 80200000 then that address is a valid local bus address as well
        ; as a valid PCI Memory address.  PCI IO addresses are mapped to start
        ; at zero.  This means that local bus address B0000000 maps to PCI IO address
        ; 00000000 and so on.   Device driver writers need to be aware of this 
        ; distinction.
        ; 
        ; Normally these spaces are mapped using the following base registers:
        ; 
        ;       Usage Local Bus Memory         Base/Map registers used
        ; 
        ;       Mem   80000000 - 8FFFFFFF      LB_BASE0/LB_MAP0
        ;       Mem   90000000 - 9FFFFFFF      LB_BASE1/LB_MAP1
        ;             A0000000 - AFFFFFFF      
        ;       IO    B0000000 - B0FFFFFF      LB_BASE2/LB_MAP2
        ;       Cfg   B8000000 - B8FFFFFF      
        ; 
        ; This means that I20 and PCI configuration space accesses will fail.
        ; When PCI configuration accesses are needed (via the uHAL PCI 
        ; configuration space primitives) we must remap the spaces as follows:
        ; 
        ;       Usage Local Bus Memory         Base/Map registers used
        ; 
        ;       Mem   80000000 - 8FFFFFFF      LB_BASE0/LB_MAP0
        ;       Mem   90000000 - 9FFFFFFF      LB_BASE0/LB_MAP0
        ;             A0000000 - AFFFFFFF      
        ;       IO    B0000000 - B0FFFFFF      LB_BASE2/LB_MAP2
        ;       Cfg   B8000000 - B8FFFFFF      LB_BASE1/LB_MAP1
        ; 
        ; To make this work, the code depends on overlapping windows working.
        ; The V3 chip translates an address by checking its range within 
        ; each of the BASE/MAP pairs in turn (in ascending register number
        ; order).  It will use the first matching pair.   So, for example,
        ; if the same address is mapped by both LB_BASE0/LB_MAP0 and
        ; LB_BASE1/LB_MAP1, the V3 will use the translation from 
        ; LB_BASE0/LB_MAP0.
        ; 
        ; To allow PCI Configuration space access, the code enlarges the
        ; window mapped by LB_BASE0/LB_MAP0 from 256M to 512M.  This occludes
        ; the windows currently mapped by LB_BASE1/LB_MAP1 so that it can
        ; be remapped for use by configuration cycles.
        ; 
        ; At the end of the PCI Configuration space accesses, 
        ; LB_BASE1/LB_MAP1 is reset to map PCI Memory.  Finally the window
        ; mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to
        ; reveal the now restored LB_BASE1/LB_MAP1 window.
        ; 

⌨️ 快捷键说明

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