📄 fw_arm.s
字号:
;
; 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_arm.s,v
; Revision: 1.0
; ----------------------------------------------------------------
; $
;
;
; Module Name:
;
; fw_arm.s
;
; Abstract:
;
; This module implements the code necessary to initialize the HW and
; Kernel interface routines.
;
;
; 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 in fw_arm.lst
INCLUDE kxarm.h
INCLUDE armmacros.inc
INCLUDE sizes.inc
INCLUDE bits.inc
INCLUDE platform.inc
INCLUDE cpumodes.inc
INCLUDE target.inc
INCLUDE sp810.inc
;zq add
INCLUDE mpmcinit.inc
OPT 1 ; enable listing in fw_arm.lst
IMPORT ARMInitSerial
IMPORT ARMPutHex
IMPORT ARMWriteString
IF EBOOT
IMPORT EbootMain
ELSE
IMPORT KernelStart
ENDIF
IF EBOOT :LOR: :LNOT:EXEFLASH
IMPORT EverythingRelocate
ENDIF
IF :DEF: EXAMPLE_MEMCONFIG
IMPORT ARMConfigMemory
ENDIF
CP15ControlInit EQU 0xc0001078 ; Async. Bus mode
; I-Cache enabled
; Little-Endian
; MMU Disabled
STARTUPTEXT
LEAF_ENTRY StartUp
; There are two ways into StartUp: from the bootmonitor/reset or from
; wake up. In either case, the processor should be in a privileged mode
; (e.g. SVC) with the MMU disabled. If the MMU might be active, there
; needs to be code to ensure that the executable is still at the next
; address when the MMU is turned off.
;
; disable all interrupts, set SVC mode
mov r0, #(SVC32Mode :OR: NoINTS)
msr cpsr_c, r0
;**************************************
;zq add
IF EBOOT
;remap
; MOV r0, #PHYS_SC_BASE ; r0 -> System Controller
; MOV r1, #2
; STR r1, [r0, #BOOTMAPCLR] ;REMAPSTATIC=0
; MOV r1, #1
; STR r1, [r0, #MAPMOVE] ;remaped to SDRAM
;sdram init
; BL mpmcinit
ENDIF
;**************************************
;
; Here is a good place to do any speed (CPU, memory etc) setup
; We do not do any here as the boot monitor is used to do this for now
;
;zq we use 32k ref_clk
; Set all the timers to 1MHz
ldr r0, =PHYS_SC_BASE
ldr r1, [r0, #ARM_SCCtrl]
orr r1, r1, #(SCCtrlTimer0EnSel :OR: SCCtrlTimer1EnSel :OR: SCCtrlTimer2EnSel :OR: SCCtrlTimer3EnSel)
str r1, [r0, #ARM_SCCtrl]
ContinueSetup
; Only used temporarily, but setup a stack for use by 'C' routines;
; Use only the first 32KB of the area. Remember this is a full descending
; based stack.
ldr sp, =TEMP_STACK_BASE
IF :DEF: EXAMPLE_MEMCONFIG
BL ARMConfigMemory
ENDIF
; Now reset all CP15 features
ldr r0, =CP15ControlInit
WRMMU_STATE r0
mov r0, #0x0
WRMMU_FlushTB r0 ; flush TLBs
WRCACHE_FlushIDC r0 ; flush caches
; Example code to support remapping to flash after a reset
IF :DEF: EXAMPLE_FLASHREMAP
; Make sure we're running from the physical memory address and
; not an address mapped to 0 (the normal reset state).
GOTO_ROM r0, r1
ENDIF
DISABLE_INTS r0, r1 ; Ints -> IRQ; LEDs
IF EBOOT :LOR: :LNOT:EXEFLASH
;
; Relocate code from Flash to RAM if necessary. This step is required
; for EBOOT as it's code runs from physical, not virtual, addresses. It
; is optional for Win CE, though running from RAM increases performance
;
; Returns with r0 = linked address for Startup, -1 if currently
; executing in the correct place
;
; NOTE: Since the eboot/nk image is built to execute from RAM but we're
; currently executing out of flash, make sure this call is a relative
; branch. Once the code is relocated to RAM, absolute address references
; are fine.
;
; The branch with link instruction will do a relative branch and since we
; don't care about Thumb/ARM mode switching, it works fine here.
;
bl EverythingRelocate
; branch to final execution address if necessary
cmp r0, #-1
addne r0, r0, #(RealStartup - StartUp)
movne pc, r0
ENDIF
RealStartup
; init the debug serial port and say "hello".
bl ARMInitSerial
adr r0, HelloMsg
bl ARMWriteString
adr r0, StackMsg
bl ARMWriteString
mov r0, sp
bl ARMPutHex
adr r0, EndMsg
bl ARMWriteString
IF EBOOT
CALL EbootMain
ELSE
; (r0) = physical address of OEMMemoryMap
adr r0, OEMAddressTable
bl KernelStart
ENDIF
; control should never return to this routine; if it does, output
; some debug & spin
adr r0, ByeMsg
bl ARMWriteString
spin b spin
IF EBOOT
HelloMsg DCB 13, 10, "Z228 Ethernet Boot Loader", 13, 10, 0
ByeMsg DCB 13, 10, "ARMVPB_Eboot returned!", 13, 10, 0
ELSE
HelloMsg DCB 13, 10, "WindowsCE on Z228", 13, 10, 0
ByeMsg DCB 13, 10, "KernelStart returned!", 13, 10, 0
ENDIF
StackMsg DCB " Stack Pointer: ", 0
EndMsg DCB 13, 10, 0
ENTRY_END StartUp
ALIGN 4
IF :LNOT: EBOOT
INCLUDE mapx20t.inc
ENDIF
;****************************************************************
mpmcinit PROC
mov r2, lr
; prepare to initialize MPMC
LDR r6, =MPMC_Base
; Set AHB Timeouts // use default values
; -----------------------------------------------------------------------------
; Set Clocking scheme //0x111
; -----------------------------------------------------------------------------
MOV r0, #0xFF
ADD r0, r0, #0x12
STR r0, [r6, #MPMCDynamicReadConfig - MPMC_Base]
; Set SDRAM Initialisation Value (I) to NOP (MPMCDynamicControl [8:7] to 2'b11)
; -----------------------------------------------------------------------------
ADD r7, r6, #1
ADD r7, r7, #0xFF ; MPMC_Base_Plus_256
MOV r0, #0x0
ADD r0, r0,#0xFF
ADD r0,r0, #0x84 ; 0x183
STR r0, [r6, #MPMCDynamicControl - MPMC_Base]
; Set SDRAM Initialisation Value (I) to PALL (MPMCDynamicControl [8:7] to 2'b10)
; -----------------------------------------------------------------------------
SUB r0, r0, #0x80 ; 0x103
STR r0, [r6, #MPMCDynamicControl - MPMC_Base]
; Write a small value (1) into the refresh register (MPMCDynamicRefresh)
; -----------------------------------------------------------------------------
; 0x1 (x16) = 16 cycles between refreshes
MOV r0, #1
STR r0, [r6, #MPMCDynamicRefresh - MPMC_Base]
; Perform refresh cycles
; -----------------------------------------------------------------------------
MOV r0, #0x30 ; Set required number of loop cycles to allow enough refreshes
w SUB r0, r0, #1
CMP r0, #1
BNE w
; Write operational value into refresh reg (MPMCDynamicRefresh)
; -----------------------------------------------------------------------------
;default : CPU CLOCK = 133MHz; HCLK = 66MHz
; For 15.625us refresh rate, with 66MHz clock = (15.625 * 66)/16 = 60 freq = 100 , 15.625 *100/16 = 99
MOV r0, #0x3C
STR r0, [r6, #MPMCDynamicRefresh - MPMC_Base]
; Program RAS/CAS latency (MPMCDynamicRASCAS[0,1,2,3])
; -----------------------------------------------------------------------------
; MPMCDynamicRASCASn [10:7] -> CAS latency in half cycle increments
; MPMCDynamicRASCASn [3:0] -> RAS latency in one cycle increments
; 32'h0000 0202 => RAS = 2 cycles, CAS = 2 cycles ;CAS = 2 RAS= 3, 0203
; 32'h0000 0182 => RAS = 2 cycles, CAS = 1.5 cycles
MOV r0, #0xFF
ADD r0, r0, #0x84 ; 0x183
ADD r0,r0, #0x80 ; 0x203
STR r0, [r7, #MPMCDynamicRasCas0 - MPMC_Base_Plus_256]
STR r0, [r7, #MPMCDynamicRasCas1 - MPMC_Base_Plus_256]
; Write operational value into Config reg (MpmcDynamicConfig n)
; -----------------------------------------------------------------------------
; For RBC : 32'h 0000 4880 ;4680
; For BRC : 32'h 0000 5880
MOV r0, #0x8D
MOV r0,r0, lsl #7 ;0x4680
STR r0, [r7, #MPMCDynamicConfig0 - MPMC_Base_Plus_256]
STR r0, [r7, #MPMCDynamicConfig1 - MPMC_Base_Plus_256]
; Set DynamicRP Register rp = 15ns/clk #02
; -----------------------------------------------------------------------------
MOV r0, #0x2
STR r0, [r6, #MPMCDynamictRP - MPMC_Base]
; Set DynamicRAS Register tRAS = 37ns /CLK = 5
; -----------------------------------------------------------------------------
MOV r0, #0x5
STR r0, [r6, #MPMCDynamictRAS - MPMC_Base]
; Set DynamicSREX Register tXSR = 67 /clk = 9
; -----------------------------------------------------------------------------
MOV r0, #0x9
STR r0, [r6, #MPMCDynamictSREX - MPMC_Base]
; Set DynamicWR Register tWR = ( clk+ 7) /clk = 2
; -----------------------------------------------------------------------------
MOV r1, #0x2
STR r1, [r6, #MPMCDynamictWR - MPMC_Base]
; Set DynamicRC Register tRC = 60 /clk = 8
; -----------------------------------------------------------------------------
MOV r0, #0x8
STR r0, [r6, #MPMCDynamictRC - MPMC_Base]
; Set DynamicRFC Register tREC = 66/clk = 9
; -----------------------------------------------------------------------------
MOV r0, #0x9
STR r0, [r6, #MPMCDynamictRFC - MPMC_Base]
; Set DynamicXSR Register tXSR = 67 /clk = 9
; -----------------------------------------------------------------------------
STR r0, [r6, #MPMCDynamictXSR - MPMC_Base]
; Set DynamicRRD Register tRRD = 14 /clk =2
; -----------------------------------------------------------------------------
MOV r0, #2
STR r0, [r6, #MPMCDynamictRRD - MPMC_Base]
; Set DynamicMRD Register tMRD = 2clk
; -----------------------------------------------------------------------------
STR r0, [r6, #MPMCDynamictMRD - MPMC_Base]
; Set DynamicCDLR Register tCDL = 1 clk
; -----------------------------------------------------------------------------
MOV r1, #1
STR r0, [r6, #MPMCDynamictCDLR - MPMC_Base]
; Set SDRAM Initialisation Value (I) to MODE (MPMCDynamicControl [8:7] to 2'b01)
; -----------------------------------------------------------------------------
MOV r0, #0x83
STR r0, [r6, #MPMCDynamicControl - MPMC_Base]
; Program the Mode Registers. SDRAM Addr[5] = 1'b1, all others 0
; -----------------------------------------------------------------------------
; SDRAM Addr[11:0] = 12'h020
; For RBC : SDRAM Addr[11:0] translates to HADDR [25:13] = 0x40000 RBC = 0x40000
; For BRC : SDRAM Addr[11:0] translates to HADDR [23:11] = 0x10000
; To program the register, do a read from the memory base addr + the value above
LDR r5, =SDRAM4ModeRegAddr ;0x00040000
LDR r0, [r5]
LDR r5, =SDRAM5ModeRegAddr ;0x08040000
LDR r0, [r5]
; Set SDRAM Initialisation Value (I) to PALL
; -----------------------------------------------------------------------------
; MOV r0, #0x83
; ADD r0, r0, #0x80
; STR r0, [r6, #MPMCDynamicControl - MPMC_Base]
; Set SDRAM Initialisation Value (I) to NORMAL (MPMCDynamicControl [8:7] to 2'b00)
; -----------------------------------------------------------------------------
MOV r0, #3
STR r0, [r6, #MPMCDynamicControl - MPMC_Base]
; Mpmc Dynamic Memory Config complete
; -----------------------------------------------------------------------------
mov pc, r2
ENDP
END
; EOF fw_arm.s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -