📄 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.
;
INCLUDE kxarm.h
INCLUDE bulverde.inc
INCLUDE mainstoneii.inc
INCLUDE image_cfg.inc
INCLUDE xlli_Bulverde_defs.inc
; INCLUDE xlli_Mainstone_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:
;
; * Copy the image to RAM if it's not already running there.
;
; * 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
; Initialize the hex LEDs on the Mainstone II board. These use GPIOs which were
; configured in the OALXScaleSetFrequencies callback during clock initialization.
;
; bl Init_HexLEDs
; Copy the bootloader image from flash to RAM. The image is configured
; to run in RAM, but is stored in flash. Absolute address references
; should be avoided until the image has been relocated and the MMU enabled.
;
; TODO - check to see if the PC is already in RAM.
;
; NOTE: The destination (RAM) address must match the address in the
; bootloader's .bib file. The latter dictates the code fix-up addresses.
;
ldr r8, =IMAGE_BOOT_BLDRIMAGE_FLASH_PA_START ; Bootloader is stored at the base of the boot flash.
; Bootloader is fixed up to run in SDRAM (this value
; must match the NK start address in the .bib file).
ldr r1, =IMAGE_BOOT_BLDRIMAGE_RAM_PA_START
ldr r2, =(IMAGE_BOOT_BLDRIMAGE_RAM_SIZE / 16) ; Bootloader image length (this must be <= the NK
; length in the .bib file). We are block-copying
; 16-bytes per iteration.
; Do 4x32-bit block copies from flash->RAM (corrupts r4-r7).
;
10 ldmia r8!, {r4-r7} ; Loads from flash (post increment).
stmia r1!, {r4-r7} ; Stores to RAM (post increment).
subs r2, r2, #1 ;
bne %B10 ; Done?
; Verify that the copy succeeded by comparing the flash and RAM contents.
;
ldr r0, =IMAGE_BOOT_BLDRIMAGE_RAM_SIZE
ldr r1, =IMAGE_BOOT_BLDRIMAGE_RAM_PA_START
ldr r2, =IMAGE_BOOT_BLDRIMAGE_FLASH_PA_START
VERIFY_LOOP
ldr r3, [r1], #4 ; Read longword from DRAM.
ldr r4, [r2], #4 ; Read longword from flash.
cmp r3, r4 ; Compare.
bne VERIFY_FAILURE ; Not the same? Fail.
subs r0, r0, #4 ;
bne VERIFY_LOOP ; Continue?
b VERIFY_DONE ; Done (success).
VERIFY_FAILURE
; ldr r0, =MAINSTONEII_BASE_REG_PA_FPGA
; sub r1, r1, #4 ; Bad RAM address.
; setHexLED r0, r1 ; Display address.
STALL1
b STALL1 ; Spin forever.
VERIFY_DONE
; Now that we've copied ourselves to RAM, jump to the RAM image. Use the "CodeInRAM" label
; to determine the RAM-based code address to which we should jump.
;
add r2, pc, #CODEINRAM-(.+8) ; Calculate the relative offset to the 'CodeInRAM' label.
sub r2, r2, #IMAGE_BOOT_BLDRIMAGE_FLASH_OFFSET
ldr r1, =IMAGE_BOOT_BLDRIMAGE_RAM_PA_START ; Get the RAM address to which we copied ourself.
add r1, r1, r2 ; Calculate the RAM address of the 'CodeInRAM' label.
mov pc, r1 ;
nop
nop
nop
CODEINRAM
; We're now running out of RAM.
;
; ldr r0, =MAINSTONEII_BASE_REG_PA_FPGA
; mov r1, pc ; Get the RAM-based PC.
; setHexLED r0, r1 ; Display it.
; Now that we're running out of RAM, 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
; [A000 0000 --> BFFF FFFF] = NonCacheable, nonBufferable
;
BUILDTTB
add r11, pc, #g_oalAddressTable - (. + 8) ; Pointer to OEMAddressTable.
; Set the TTB.
;
ldr r9, =MAINSTONEII_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.
; Display status on the LEDs.
;
; ldr r5, =MAINSTONEII_BASE_REG_PA_FPGA
; ldr r8, =0x000c0de9
; setHexLED r5, r8
; 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.
; Place it in cached SDRAM; especially important for performance of the
; MinCryptXXX() functions in secure_eboot.
;
; NOTE: These values must match the OEMAddressTable and .bib file entries for
; the bootloader.
;
ldr sp, =IMAGE_BOOT_STACK_RAM_CA_START
; Jump to the C entrypoint.
;
bl main ; Jump to main.c::main(), never to return...
nop
nop
nop
STALL2
b STALL2
;-------------------------------------------------------------------------------
;
; Init_HexLEDs: Initializes the Mainstone II board logic to enable the hex LEDs.
;
; Inputs: None.
;
; On return: N/A.
;
; Register used: r0-r3
;
;-------------------------------------------------------------------------------
;
; ALIGN
;Init_HexLEDs
;
; ldr r3, =BULVERDE_BASE_REG_PA_MEMC
; ldr r2, =xlli_MSC1_value
; str r2, [r3, #xlli_MSC1_offset] ; Need to set MSC1 before trying to write to the HEX LEDs
; ldr r2, [r3, #xlli_MSC1_offset] ; Need to read it back to make sure the value latches (see MSC section of manual)
;
; ldr r1, =MAINSTONEII_BASE_REG_PA_FPGA
; mov r0, #0x0
; str r0, [r1, #LEDCTL_OFFSET] ; Blank hex & discrete leds
; setHexLED r1, r0
;
; IF Interworking :LOR: Thumbing
; bx lr
; ELSE
; mov pc, lr ; Return to caller.
; ENDIF
;
;-------------------------------------------------------------------------------
;
; 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 + -