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