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