target.s
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· S 代码 · 共 1,283 行 · 第 1/4 页
S
1,283 行
; NOTE: We do not set up I20 mapping. I suspect that this is only
; for an intelligent (target) device. Using I2O disables most of
; the mappings into PCI memory.
;
; NOTE: we load $w1 with the base address of the V3's register set
; at the start of the macro and expect it not to change!
MACRO
$label SETUP_PCI $w1, $w2, $w3, $w4
; We must first turn on PCI
LDR $w1, =INTEGRATOR_SC_PCIENABLE
LDR $w2, =0x1
STR $w2, [$w1]
; Load up the base address of the V3 register set
LDR $w1, =PHYS_PCI_V3_BASE
; we can NOT try ANY reads from the V3 bridge chip until LB_IO_BASE is written
; we ASSUME that we've already waited for >=230us (@PCLK 25MHz) since reset
; so that this write WILL have an effect on the V3 chip
; Set up where the V3 registers appear in the memory map (PCI_V3_BASE)
LDR $w2, =PHYS_PCI_V3_BASE
MOV $w2, $w2, LSR #16
STRH $w2, [$w1, #V3_LB_IO_BASE]
; Wait for the V3 to realise that there is no SROM
LDR $w2, =0xAA
LDR $w3, =0x55
L13 STRB $w2, [$w1, #V3_MAIL_DATA]
STRB $w3, [$w1, #V3_MAIL_DATA + 4]
LDRB $w4, [$w1, #V3_MAIL_DATA]
CMP $w4, #0xAA
BNE L13
LDRB $w4, [$w1, #V3_MAIL_DATA + 4]
CMP $w4, #0x55
BNE L13
; Make sure that V3 register access is not locked, if it is, unlock it.
LDRH $w2, [$w1, #V3_SYSTEM]
AND $w2, $w2, #V3_SYSTEM_M_LOCK
CMP $w2, #V3_SYSTEM_M_LOCK
LDREQ $w2, =0xA05F
STREQH $w2, [$w1, #V3_SYSTEM]
; ensure that slave accesses from PCI are DISabled while we set up windows
LDRH $w2, [$w1, #V3_PCI_CMD] ; get current CMD register
BIC $w2, $w2, #(V3_COMMAND_M_MEM_EN :OR: V3_COMMAND_M_IO_EN)
STRH $w2, [$w1, #V3_PCI_CMD] ; MEM & IO now BOTH bounce
; Clear RST_OUT to 0: keep the PCI bus in reset until we're finished
LDRH $w2, [$w1, #V3_SYSTEM]
BIC $w2, $w2, #V3_SYSTEM_M_RST_OUT
STRH $w2, [$w1, #V3_SYSTEM]
; Make all accesses from PCI space retry until we're ready for them
LDRH $w2, [$w1, #V3_PCI_CFG]
ORR $w2, $w2, #V3_PCI_CFG_M_RETRY_EN
STRH $w2, [$w1, #V3_PCI_CFG]
; Set up any V3 PCI Configuration Registers that we absolutely have to
; LB_CFG controls Local Bus protocol.
; enable LocalBus byte strobes for READ accesses too
; ###### need to set up timeout bits as well
LDRH $w2, [$w1, #V3_LB_CFG]
ORR $w2, $w2, #0x0C0 ; set bit7 BE_IMODE & bit6 BE_OMODE
STRH $w2, [$w1, #V3_LB_CFG]
; PCI_CMD controls overall PCI operation
; ###### possibly need to set up FBB_EN, SERR_EN, PAR_EN bits as well
; enable PCI bus master;
; ###### eventually need to set bit1 MEM_EN to enable PCI slave for memory but NOT I/O
LDRH $w2, [$w1, #V3_PCI_CMD]
ORR $w2, $w2, #0x04 ; set bit2 MASTER_EN
STRH $w2, [$w1, #V3_PCI_CMD]
; PCI_HDR_CFG controls PCI master timeouts etc.
; ###### probably want to set bits 15-11 (latency timer) to non-zero
; PCI_SUB_VENDOR contains an info field for other masters
; ###### REQUIRED by PCIspec2.1 & Win95 (WinCE?) ... BUT what value?
; PCI_SUB_ID contains an info field for other masters
; ###### REQUIRED by PCIspec2.1 & Win95 (WinCE?) ... BUT what value?
; PCI_MAP0 controls where the PCI to CPU memory window is on the Local Bus
LDR $w2, =INTEGRATOR_BOOT_ROM_BASE ; start of EBI memory
MOV $w2, $w2, LSR #20 ; clip to 12-bit field
MOV $w2, $w2, LSL #20 ; at top of word wide reg
; aperture size is 512M
ORR $w2, $w2, #V3_PCI_MAP_M_ADR_SIZE_512M
; PCI_BASE0 reg MUST be enabled before writing it
; aperture itself enabled too
ORR $w2, $w2, #V3_PCI_MAP_M_REG_EN :OR: V3_PCI_MAP_M_ENABLE
STR $w2, [$w1, #V3_PCI_MAP0] ; finally write the reg
; PCI_BASE0 is the PCI address of the start of the window
LDR $w2, =INTEGRATOR_PCI_BASE0_ADDR ; PCI base memory address
MOV $w2, $w2, LSR #20 ; clip to 12-bit field
MOV $w2, $w2, LSL #20 ; at top of word wide reg
; read may NOT be prefetched for this aperture (MAY change for later FPGA)
; BIC $w2, $w2, #V3_PCI_BASE_M_PREFETCH bit already 0 => NO pre-fetch
STR $w2, [$w1, #V3_PCI_BASE0]
; ###### do we inhibit PCI read posting? (bit15)
; PCI_MAP1 is LOCAL address of the start of the window
LDR $w2, =INTEGRATOR_HDR0_SDRAM_BASE; start of aliassed header memory
MOV $w2, $w2, LSR #20 ; clip to 12-bit field
MOV $w2, $w2, LSL #20 ; at top of word wide reg
; aperture size is 1024M
ORR $w2, $w2, #V3_PCI_MAP_M_ADR_SIZE_1024M
; PCI_BASE1 reg MUST be enabled before writing it
; aperture itself enabled too
ORR $w2, $w2, #(V3_PCI_MAP_M_REG_EN :OR: V3_PCI_MAP_M_ENABLE)
STR $w2, [$w1, #V3_PCI_MAP1] ; finally write the reg
; PCI_BASE1 is the PCI address of the start of the window
LDR $w2, =INTEGRATOR_PCI_BASE1_ADDR ; PCI base memory address
MOV $w2, $w2, LSR #20 ; clip to 12-bit field
MOV $w2, $w2, LSL #20 ; at top of word wide reg
; read may NOT be prefetched for this aperture (MAY change for later FPGA)
; BIC $w2, $w2, #V3_PCI_BASE_M_PREFETCH ;### bit already 0
STR $w2, [$w1, #V3_PCI_BASE1]
; PCI_INT_CFG controls PCI interrupt pins
; ###### need to route 1 or 2 of INTx to INTy (but what are x and y on SDB?)
; FIFO_CFG controls V3 FIFOs in both directions
; ###### need to think about e.g. LBurstMax in conjunction with FPGA bridge
; FIFO_PRIORITY controls V3 FIFOs in both directions
; ###### need to think about e.g. read-flush strategies
; Set up the windows from local bus memory into PCI configuration, I/O
; and Memory
; ...PCI I/O, LB_BASE2 and LB_MAP2 are used exclusively for this
LDR $w2, =PHYS_PCI_IO_BASE
MOV $w2, $w2, LSR #24 ; clip to 8-bit field
MOV $w2, $w2, LSL #8 ; at top of half-word reg
ORR $w2, $w2, #V3_LB_BASE_M_ENABLE
STRH $w2, [$w1, #V3_LB_BASE2]
LDR $w2, =0 ; map to I/0 address 0 and above
STRH $w2, [$w1, #V3_LB_MAP2]
; ...PCI Configuration, use LB_BASE1/LB_MAP1. Set up on the fly by
; the PCI Configuration access code in board.c
; ...PCI Memory, use LB_BASE0/LB_MAP0 and LB_BASE1/LB_MAP1
; Map first 256Mbytes as non-prefetchable via BASE0/MAP0
LDR $w2, =PHYS_PCI_MEM_BASE
MOV $w2, $w2, LSR #20 ; clip to 12-bit field
MOV $w2, $w2, LSL #20 ; at top of word wide reg
ORR $w2, $w2, #0x80 ; Window size is 256 Mbytes (7:4 = 1000)
ORR $w2, $w2, #V3_LB_BASE_M_ENABLE
STR $w2, [$w1, #V3_LB_BASE0]
LDR $w2, =PHYS_PCI_MEM_BASE ; PCI_MEM_BASE maps to PCI MEM address at PCI_MEM_BASE
MOV $w2, $w2, LSR #20 ; clip to 12-bit field
MOV $w2, $w2, LSL #4 ; at top of half-word reg
ORR $w2, $w2, #0x0006 ; 3:0 = 0110 = PCI Memory read/write
STRH $w2, [$w1, #V3_LB_MAP0]
; Map second 256Mbytes as prefetchable via BASE1/MAP1
LDR $w2, =PHYS_PCI_MEM_BASE+SZ_256M
MOV $w2, $w2, LSR #20 ; clip to 12-bit field
MOV $w2, $w2, LSL #20 ; at top of word wide reg
ORR $w2, $w2, #0x84 ; Window size is 256 Mbytes (7:4 = 1000), prefetchable
ORR $w2, $w2, #V3_LB_BASE_M_ENABLE
STR $w2, [$w1, #V3_LB_BASE1]
LDR $w2, =PHYS_PCI_MEM_BASE+SZ_256M
MOV $w2, $w2, LSR #20 ; clip to 12-bit field
MOV $w2, $w2, LSL #4 ; at top of half-word reg
LDR $w2, =0x0006 ; 3:0 = 0110 = PCI Memory read/write
STRH $w2, [$w1, #V3_LB_MAP1]
; Allow accesses to PCI Configuration space
; and set up A1,A0 for type 1 config cycles
LDRH $w2, [$w1, #V3_PCI_CFG]
BIC $w2, $w2, #V3_PCI_CFG_M_RETRY_EN
BIC $w2, $w2, #V3_PCI_CFG_M_AD_LOW1 ; force A1=0 and
ORR $w2, $w2, #V3_PCI_CFG_M_AD_LOW0 ; A0=1 for config type 1
STRH $w2, [$w1, #V3_PCI_CFG]
;now we can allow in PCI MEMORY accesses
LDRH $w2, [$w1, #V3_PCI_CMD] ; get current CMD register
ORR $w2, $w2, #V3_COMMAND_M_MEM_EN
STRH $w2, [$w1, #V3_PCI_CMD] ; MEM now accepted (IO still bounced)
; Set RST_OUT to take the PCI bus is out of reset, PCI devices can initialise
; ... and lock the V3 system register so that no one else can play with it
LDRH $w2, [$w1, #V3_SYSTEM]
ORR $w2, $w2, #V3_SYSTEM_M_RST_OUT
STRH $w2, [$w1, #V3_SYSTEM]
ORR $w2, $w2, #V3_SYSTEM_M_LOCK
STRH $w2, [$w1, #V3_SYSTEM]
MEND
; ---------------------------------------------------------------------
; SETUPMMU
; -------
; Setup the memory map world for the target. This macro is called by
; INITMMU from ANGEL if required; or by uHAL when a standalone
; program uses the mmu.
; Level 1 entries always address 1MB each. The CPU takes the MB
; portion of the required address and uses it as an offset
; into the table. If the entry has bit 0 == 1, it looks in
; the level 2 table.
; Level 2 entries can address 4KB or 1KB each. If using 64KB level 2
; entries, each page table entry must be duplicated 16 times
; (in consecutive memory locations) in a Large level 2 table.
; In this implementation, Fine tables _must_ be 1KB entries and Large
; tables _only_ support 64KB entries.
MACRO
$label SETUPMMU $tmp1, $size, $tmp2, $tmp3, $tmp4, $tmp5, $offset
IF :LNOT: :DEF: uHAL_AddressTable
IMPORT uHAL_AddressTable
ENDIF
IF :LNOT: :DEF: uHAL_MappingTable
IMPORT uHAL_MappingTable
ENDIF
MOV $tmp1, #4 ; DEBUG: 100, R--
DO_DEBUG $tmp1, $tmp3
; Scan for MPU and set up if found
CHECK_FOR_MPU $tmp1
BEQ %F79
; ----------------------------------------------------
; Here lies the MPU memory map for this board. Use it
; with the offset between physical & virtual TTBs to
; build a valid page table.
; To use default memory size, pass in RAM size of zero
; ----------------------------------------------------
ldr $tmp5, =uHAL_MappingTable
LDR $offset, =0
SETUP_MPU $tmp1, $size, $tmp2, $tmp3, $tmp4, $tmp5, $offset
79
; Scan for MMU and set up if found
CHECK_FOR_MMU $tmp1
BEQ %F91
; ----------------------------------------------------
; Here lies the MMU memory map for this board. Use it
; with the offset between physical & virtual TTBs to
; build a valid page table.
; To use default memory size, pass in RAM size of zero
; ----------------------------------------------------
ldr $tmp5, =uHAL_AddressTable
LDR $offset, =0
BUILD_PGTABLE $tmp1, $size, $tmp2, $tmp3, $tmp4, $tmp5, $offset
LDR $tmp1, =Level1tab ;TTB address is 2**14 aligned
WRMMU_TTBase $tmp1 ;Initialise Translation Table Base reg.
LDR $tmp1, =1
WRMMU_DAControl $tmp1 ;Initialise Domain Access Control
; ----------------------------------------------------
; Flush everything and get ready to turn on the MMU
; ----------------------------------------------------
WRMMU_FlushTB $tmp1 ; Flush TB
WRCACHE_FlushIDC $tmp1 ; Flush the Caches
NOP ; make sure that the pipe is empty
NOP
NOP
91
MOV $tmp1, #5 ; DEBUG: 101, R-Y
DO_DEBUG $tmp1, $tmp3
MEND
; ----------------------------------------------------
;
; ANGEL and uHAL INITMMU macro, calls the core SETUPMMU macro if
; the MMU is enabled and then sets ICache, DCache & WBuffer as
; required. On certain system where the target does not have a MMU,
; then this macro is almost (but not quite) a NOP: It is good to know
; the MMU/cache register has been written and just using the ICache &
; WBuffer on their own is still a useful gain.
;
; ----------------------------------------------------
MACRO
$label INITMMU $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $tmp6
IntegratorInitMMU
IF :LNOT: :DEF: ENABLE_MMU
ENABLE_MMU EQU 1 ; Angel flags not defined in uHAL
ENDIF
IF :LNOT: :DEF: CACHE_SUPPORTED
CACHE_SUPPORTED EQU 1
ENDIF
IF ENABLE_MMU = 1
LDR $tmp2, =uHAL_MEMORY_SIZE ; Pass the top of memory
SETUPMMU $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $tmp6, r7
LDR $tmp2, =0
SET_MMU $tmp2
ELSE
LDR $tmp2, =0 ; No MMU - running out of flash @ 0
ENDIF ; ENABLE_MMU
; May or may not enable the caches
MOV $tmp1, #0
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?