fwxsc1.s
来自「PXA255 WINCE 4.2 BSP ,该BSP是商用的。」· S 代码 · 共 830 行 · 第 1/2 页
S
830 行
; check for wake up from sleep
tst r10, #RCSR_SLEEP_RESET
bne try2wakeup
initperif
; enable peripherial clocks
ldr r1, =(CLOCK_BASE | CLOCK_CKEN)
ldr r2, =0x17def
str r2, [r1]
; initialize UART controler
UART_CTRL_IEN EQU 0x4
UART_CTRL_FCTL EQU 0x8
UART_CTRL_LCTL EQU 0xc
UART_CTRL_MCTL EQU 0x10
UART_CTRL_BDLO EQU 0x0
UART_CTRL_BDHI EQU 0x4
ldr r1, =UART_CTRL_BASE
mov r2, #0x80
strb r2, [r1, #UART_CTRL_LCTL] ; DLAB on
mov r2, #0x18 ; clock = 14.7456MHz, [BDLO,BDHI]=14745600/16/baud_rate
strb r2, [r1, #UART_CTRL_BDLO]
mov r0, #0
strb r0, [r1, #UART_CTRL_BDHI]
mov r2, #0x3
strb r2, [r1, #UART_CTRL_LCTL] ; DLAB off, 8-1-N
sub r2, r2, #0x2
strb r2, [r1, #UART_CTRL_MCTL] ; DTR on
mov r2, #0x40
strb r2, [r1, #UART_CTRL_IEN] ; disable interupts, enable UART
strb r0, [r1, #UART_CTRL_FCTL] ; clear and turn on FIFOs
; *****************************************************************
; Load RVA of OEMAddressTable[]
INITMMU
add r0, pc, #OEMAddressTable-(.+8) ; (r0) = OEMAddressTable phys addr
mov r11, r0 ; (r11) = &MemoryMap (save pointer)
; read cp15, reg1's current settings
ldr r1, =0
mrc p15,0,r1,c1,c0,0 ; read cp15, reg1... 1st=0x78
IF :LNOT: :DEF: ETHBOOT
mov r0, #0x0d
bl putc_ttys0
mov r0, #0x0a
bl putc_ttys0
mov r0, #0x2b
bl putc_ttys0
mov r0, #0x2b
bl putc_ttys0
mov r0, #0x2b
bl putc_ttys0
mov r0, r11
bl KernelStart ; Branch to coreos\armtrap.s::KernelStart()
nop
nop
nop
b HANG
ELSE
b CONTINUE ; branch around Include (do not move)
ENDIF ; :LNOT: :DEF: ETHBOOT
INCLUDE MemMap.inc ; **NOTE: DO NOT move this! Must be in this section
CONTINUE
; *****************************************************************
; Copy Flash-based Eboot image into RAM. This will be placed
; in our EBOOT_PARTITION plus an offset. (EbootOffset)
;
;
; The bootloader is linked to run from RAM but is initially installed in "FLASH" Ram
; at the reset/boot address. Now that memory has been configured, copy the
; entire bootloader image to RAM.
;
; *Note: The bootloader's region size must agree with boot.bib's declaration of
; it.
;
ldr r8, =BOOT_FLASH_BASE_PHYSICAL ; Phy Base of our EBOOT PARTITION
ldr r1, =(EBOOT_PARTITION_PHY_BASE + EbootOffset) ; **Defined in BOOT.BIB. Is the offset into the EBOOT PARTITION.
; This (and next) values must match BOOT.BIB!
ldr r2, =(EBootImageLen/16) ; Setup Loop control. We are block-copying 16-bytes per iteration.
; **EBootImageLen From BOOT.BIB, size field.
; Do 4x32-bit Block Copies from Flash->SDRAM (corrupts r4-r7)
10 ldmia r8!, {r4-r7} ; Loads from BOOT_FLASH_BASE_PHYSICAL, post increment
stmia r1!, {r4-r7} ; Stores to (EBOOT_PARTITION_PHY_BASE+EbootOffset), post increment
subs r2, r2, #1
bne %B10
; Now that we have copied ourselves into RAM, jump to RAM's 'CodeInRAM' Label and start there
add r2, pc, #CodeInRAM-(.+8) ; Calc. PC-relative address of 'CodeInRAM'
ldr r1, =(EBOOT_PARTITION_PHY_BASE + EbootOffset) ; Load Phy Adx of where we started our copy above
add r1, r1, r2 ; Calc. Phy Adx of 'CodeInRAM' tag
mov pc, r1
nop
nop
nop
CodeInRAM
BUILDTTB
; *****************************************************************
; Fill in first-level Section descriptors to create 1MB mapped regions
; from the contents of the MemoryMap array. (OEMAddressTable[])
;
; (r9) = TTB
; (r11) = ptr to MemoryMap array
;
;
; We split the mappings: [8000 0000 --> 9FFF FFFF] = Cacheable, Bufferable
; [A000 0000 --> BFFF FFFF] = NonCacheable, nonBufferable
; First, make copy of r9 (CPUId)
mrc p15, 0, r9, c0, c0, 0 ; Grab CPU ID again for banners
mov r7, r9
ldr r3, =B2_STEPPING ; Load the B2 Stepping value
and r7, r7, #0xF ; Grab only the lowest nibble as it's all we care about
; Set TTB
ldr r9, =EBOOT_PARTITION_PHY_BASE ; (r9) = physical address of 1st level table (EBOOT partition base) 0xA000 0000
ldr r0, =0xFFFFC000
and r9, r9, r0 ; mask off TTB[31:0] (must be 0's)
mcr p15, 0, r9, c2, c0, 0 ; set TTB
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; ~~~~~~~~~~ MAP CACHEABLE. BUFFERABLE SECTION DESCRIPTORS ~~~~~~~~~~~~~~~~
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Workaround for De Soto Core Errata Part I: Configure cacheable sections as Write-Through for cores <=B1.
; *NOTE: Once we know what Sabinal.B1's CPUID looks like, we need to ensure this workaround happens for De Soto Sabinals.
;
cmp r7, r3 ; what stepping of CPU? If <=B2, need to ensure _all_ descriptors are marked Write-Through, Read-Allocate (C=1, B=0).
movle r0, #0x0A ; (r0) = Section (1MB) Descriptor; C=1, B=0. Write-Through, Read-Allocate
movgt r0, #0x0E ; (r0) = Section (1MB) Descriptor; C=B=1. Write-Back, Read-Allocate
orr r0, r0, #0x400 ; set AP
20 mov r1, r11 ; (r1) = ptr to MemoryMap array
; Start Crunching through the OEMAddressTable[]
;
; r2 temporarily holds OEMAddressTable[VA]
; r3 temporarily holds OEMAddressTable[PHY]
; r4 temporarily holds OEMAddressTable[#MB]
;
25
ldr r2, [r1], #4 ; (r2) = virtual, Cached address to map Bank at
ldr r3, [r1], #4 ; (r3) = physical address to map from
ldr r4, [r1], #4 ; (r4) = num MB to map
cmp r4, #0 ; End of table?
beq %F29
;****************************************************************************************************************************************************************
; (r2) holds the &descriptor
; (r0) holds the actual section descriptor
;
; Create Descriptor Address
;
ldr r6, =0xFFF00000
and r2, r2, r6 ; only VA[31:20] are valid
orr r2, r9, r2, LSR #18 ; build the descriptor address: r2 = (TTB[31:14} | VA[31:20] >> 18)
; Create the Descriptor
;
ldr r6, =0xFFF00000
and r3, r3, r6 ; only PA[31:20] are valid for the descriptor; rest will be static
orr r0, r3, r0 ; build the descriptor: r0 = (PA[31:20] | the rest of the descriptor)
; Store the descriptor at the proper (phy) address
;
28 str r0, [r2], #4
add r0, r0, #0x00100000 ; (r0) = THE Section descriptor for the next 1MB mapping (just add 1MB)
sub r4, r4, #1 ; Decrement number of MB left
cmp r4, #0
bne %B28 ; Map next MB
bic r0, r0, #0xF0000000 ; Clear Section Base Address Field
bic r0, r0, #0x0FF00000 ; Clear Section Base Address Field
b %B25 ; Get and process next table element
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Next, go through the above loop construct again.
; This time, we will map C=B=0 space (i.e. uncached, nonbuffered)
;
29
tst r0, #8 ; Test for 'C' bit set (means we just used above loop structure to map Cacheable,Bufferable space)
bic r0, r0, #0x0C ; clear cachable & bufferable bits in Descriptor (clear C&B bits)
add r9, r9, #0x0800 ; (r9) = ptr to 1st PTE for "unmapped uncached space" (0x2000 0000 + V_U_Adx)
bne %B20 ; go setup Descriptors for uncached space (map C=B=0 space)
ACTIVATEMMU
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; The 1st Level Section Descriptors are setup. Initialize the MMU and turn it on.
;
mov r1, #1
mcr p15, 0, r1, c3, c0, 0 ; setup access to domain 0
mcr p15, 0, r0, c8, c7, 0 ; flush I+D TLBs
mcr p15, 0, r1, c7, c10, 4 ; drain write and fill buffers
mov r1, #0x78 ; bits [6:3] must be written as 1's
orr r1, r1, #0x1 ; Enable: MMU
orr r1, r1, #0x1000 ; Enable icache
orr r1, r1, #0x0800 ; Enable BTB
orr r1, r1, #0x4 ; Enable Data Cache
ldr r2, =VirtualStart ; RVA
cmp r2, #0 ; make sure no stall on "mov pc,r2" below
;
; *Flip the MMU ON*
;
mcr p15, 0, r1, c1, c0, 0 ; MMU ON: All mem accesses now ~Virtual~
ldr r3, =B2_STEPPING ; Load the B2 Stepping value
cmp r7, r3 ; r7 still contains the cpuid
bgt GOVIRTUAL ; workaround not needed for >B2
;
; Provide workaround for DeSoto Core Errata CKT20
; Must populate DCache with WT data (assumes no C=B=1 descriptors are created above).
;
; Begin Cache fill Routine
;
CPWAIT ; (corrupts r0)
mcr p15, 0, r1, c7, c6, 0 ; invalidate entire DCache and MiniD
; Next, we will fill the Dcache with write-through lines
;
mov r1, #1024 ; cache-line counter
ldr r3, =0x80000000 ; C=1, B=0 section (assumes mapping is correct)
FILLD
ldr r8, [r3], #32 ; allocate a cache-line (read-allocate)
subs r1, r1, #1
bne FILLD
mcr p15, 0, r1, c7, c6, 0 ; invalidate entire DCache again to allow this range's use for Mini D.
; Next, we will fill the mini-DCache with write-through lines
;
mov r1, #8
mcr p15, 0, r1, c15, c15, 3 ; enable undoc'd test bit to force all fills to the mini-D
; Now, do our fill, mapping to the Mini-D instead of the main-d.
;
mov r1, #64
ldr r3, =0x80000000 ; C=1, B=0 section (assumes mapped this way above)
FILLMD
ldr r8, [r3], #32 ; allocate a cache-line (read-allocate)
subs r1, r1, #1
bne FILLMD
; Now, we will turn off the test bit. Read allocations will once again map to the main DCache.
;
mov r1, #0
mcr p15, 0, r1, c15, c15, 3 ; disable undoc'd test bit to force all fills to the mini-D (will now fill the main-d)
mcr p15, 0, r1, c7, c6, 0 ; invalidate entire DCache and MiniD
GOVIRTUAL
mov pc, r2
nop
nop
nop
; **********************************
; MMU & caches now enabled.
;
; (r9) = physcial=virtual (direct mapped) address of 1st level page table
VirtualStart
;
; Set up a SVC mode stack
;
ldr sp, =EBOOT_PARTITION_VIR_C_BASE ; cached, virtual ram. Set Stack Pointer
add sp, sp, #StackOffset ; Space reserved for stack in the BOOT.BIB file
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Now that we have set up the MMU descriptors, are executing virtually, and
; have set up a stack, it is time to launch EBOOT.
;
IF :DEF: ETHBOOT
bl main ; **Jump to Main.c::main(), never to return.**
nop
nop
nop
ENDIF ; // if :DEF: ETHBOOT
HANG
b HANG
; void Launch2(unsigned long pFunc)
;
; Routine Description:
;
; This function launches the program at pFunc. The expectation is that
; the launched program never returns. We disable the MMU right
; before we jump to [r0].
;
; Arguments:
;
; pFunc (r0) - Supplies the Virtual, Cached address of the program to launch.
;
; Return Value:
;
; None; the launched program never returns.
;
; Called From:
;
; Main.c::main()
;
; PreConditions:
;
; It is assumed that the MMU and Caches are ON upon entry
;
LEAF_ENTRY Launch2
ldr r2, =PhysicalStart2 ; *This is the Relative Virtual Address (RVA). It is simply an offset.
;
; First, we need to find the Offset that will get us from Virtual->Phyiscal for
; the EBOOT Partition
;
ldr r3, =(EBOOT_PARTITION_PHY_BASE - SDRAM_VIR_C_EBOOT_PARTITION)
;
; Next, we add the above found Offset to PhysicalStart's RVA.
; (R2 now points to the Physical address of PhysicalStart (below).)
;
add r2, r2, r3
;
; Now, we calculate the Offset that will get us from Virtual->Physical for
; the WinCE Partition
;
ldr r3, =(SDRAM_PHY_WINCE_PARTITION - SDRAM_VIR_C_WINCE_PARTITION)
;
; ...then add the above Offset to the Virtual/Cached Address passed to us in R0
;
;add r0, r0, r3 ; r0 = (Virtual Address of Program to Launch) + Virtual->Physical Offset
; Support soft reset with Eboot running as boot code.
ldr r4, =(SLEEPDATA_BASE_PHYSICAL+Reset_LaunchAddr) ; get pointer to SLEEPDATA
;
; Next, we disable the MMU, I&D Caches and the Write Buffer.
;
mov r1, #0x0078
mcr p15, 0, r1, c1, c0, 0
str r3, [r4] ; Store launch address for soft reset use
mov pc, r2 ; Jump to PhysicalStart
nop ; These NOPs are used to flush the Pipeline
nop
nop
nop
PhysicalStart2
mov r2, #0
mcr p15, 0, r2, c8, c7, 0 ; Flush the I&D TLBs
mov pc, r0 ; Jump to program we are launching!! No return.
b HANG
END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?