📄 startup.s
字号:
;
; Copyright (c) Microsoft Corporation. All rights reserved.
;
;
; Use of this sample source code is subject to the terms of the Microsoft
; license agreement under which you licensed this sample source code. If
; you did not accept the terms of the license agreement, you are not
; authorized to use this sample source code. For the terms of the license,
; please see the license agreement between you and Microsoft or, if applicable,
; see the LICENSE.RTF on your install media or the root of your tools installation.
; THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
;
INCLUDE kxarm.h
INCLUDE bulverde.inc
INCLUDE plato.inc
INCLUDE image_cfg.inc
INCLUDE xlli_Bulverde_defs.inc
INCLUDE xlli_plato_defs.inc
TEXTAREA
IMPORT main
IMPORT OALVAtoPA
IMPORT OALPAtoVA
; Included within the text section in order that a relative offset can be
; computed in the code below.
;
INCLUDE oemaddrtab_cfg.inc
;-------------------------------------------------------------------------------
;
; OALStartUp: OEM bootloader startup code. This routine will:
;
; * Set up the MMU and Dcache for the bootloader.
;
; * Initialize the first-level page table based up the contents
; of the MemoryMap array and enable the MMU and caches.
;
; Inputs: None.
;
; On return: N/A.
;
; Register used:
;
;-------------------------------------------------------------------------------
;
ALIGN
LEAF_ENTRY OALStartUp
; Construct the first-level Section descriptors to create 1MB mapped regions from the
; addresses defined in the OEMAddressTable.
; This will allow us to enable the MMU and use a virtual address space that matches
; the mapping used by the OS image.
;
; We'll create two different mappings from the addresses specified:
; [8000 0000 --> 9FFF FFFF] = Cacheable, Bufferable
; [A800 0000 --> BFFF FFFF] = NonCacheable, nonBufferable
;
BUILDTTB
add r11, pc, #g_oalAddressTable - (. + 8) ; Pointer to OEMAddressTable.
; Set the TTB.
;
ldr r9, =PLATO_BASE_PA_SDRAM ; Physical address of the first-level table (base of SDRAM).
ldr r0, =0xFFFFC000 ;
and r9, r9, r0 ; Mask off TTB[31:0] (must be 0's).
mcr p15, 0, r9, c2, c0, 0 ; Set the TTB.
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; ~~~~~~~~~~ MAP CACHED and BUFFERED SECTION DESCRIPTORS ~~~~~~~~~~~~~~~~~~
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mov r0, #0x0E ; Section (1MB) descriptor; (C=B=1: write-back, read-allocate).
orr r0, r0, #0x400 ; Set AP.
20 mov r1, r11 ; Pointer to OEMAddressTable.
; 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 ; Virtual (cached) address to map physical address to.
ldr r3, [r1], #4 ; Physical address to map from.
ldr r4, [r1], #4 ; Number of MB to map.
cmp r4, #0 ; End of table?
beq %F29
; r2 holds the descriptor address (virtual address)
; 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 and the 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 (physical) address
;
28 str r0, [r2], #4
add r0, r0, #0x00100000 ; Section descriptor for the next 1MB mapping (just add 1MB).
sub r4, r4, #1 ; Decrement number of MB left.
cmp r4, #0 ; Done?
bne %B28 ; No - 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 the next OEMAddressTable element.
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; ~~~~~~~~~~ MAP UNCACHED and UNBUFFERED SECTION DESCRIPTORS ~~~~~~~~~~~~~~
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
29 tst r0, #8 ; Test for 'C' bit set (means we just used
; above loop structure to map cached and buffered space).
bic r0, r0, #0x0C ; Clear cached and buffered bits in the descriptor (clear C&B bits).
add r9, r9, #0x0800 ; Pointer to the first PTE for "unmapped uncached space" (0x2000 0000 + V_U_Adx).
bne %B20 ; Repeat the descriptor setup 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 ; Set up access to domain 0.
mcr p15, 0, r0, c8, c7, 0 ; Flush the instruction and data TLBs.
mcr p15, 0, r1, c7, c10, 4 ; Drain the 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 IC.
orr r1, r1, #0x0800 ; Enable BTB.
orr r1, r1, #0x4 ; Enable DC.
ldr r2, =VirtualStart ; Get virtual address of 'VirtualStart' label.
cmp r2, #0 ; Make sure no stall on "mov pc,r2" below.
; Enable the MMU.
;
mcr p15, 0, r1, c1, c0, 0 ; MMU ON: All memory accesses are now virtual.
; Jump to the virtual address of the 'VirtualStart' label.
;
mov pc, r2 ;
nop
nop
nop
; *************************************************************************
; *************************************************************************
; The MMU and caches are now enabled and we're running in a virtual
; address space.
;
ALIGN
VirtualStart
; Set up a supervisor mode stack.
;
; NOTE: These values must match the OEMAddressTable and .bib file entries for
; the bootloader.
;
ldr sp, =IMAGE_BOOT_STACK_RAM_UA_START
; Jump to the C entrypoint.
;
bl main ; Jump to main.c::main(), never to return...
nop
nop
nop
STALL2
b STALL2
;-------------------------------------------------------------------------------
;
; void Launch(UINT32 pFunc): This function launches the program at pFunc (pFunc
; is a physical address). The MMU is disabled just
; before jumping to specified address.
;
; Inputs: pFunc (r0) - Physical address of program to Launch.
;
; On return: None - the launched program never returns.
;
; Register used:
;
;-------------------------------------------------------------------------------
;
ALIGN
LEAF_ENTRY Launch
; r3 now contains the physical launch address.
;
mov r3, r0
; Compute the physical address of the PhysicalStart tag. We'll jump to this
; address once we've turned the MMU and caches off.
;
stmdb sp!, {r3}
ldr r0, =PhysicalStart
bl OALVAtoPA
nop
ldmia sp!, {r3}
; r0 now contains the physical address of 'PhysicalStart'.
; r3 now contains the physical launch address.
; Next, we disable the MMU, and I&D caches.
;
mov r1, #0x0078
mcr p15, 0, r1, c1, c0, 0
; Jump to 'PhysicalStart'.
;
mov pc, r0
nop
nop
nop
nop
PhysicalStart
; Flush the I&D TLBs.
;
mcr p15, 0, r2, c8, c7, 0 ; Flush the I&D TLBs
; Jump to the physical launch address. This should never return...
;
mov pc, r3
nop
nop
nop
nop
nop
nop
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -