1// 2// Copyright (c) 2011-2015, ARM Limited. All rights reserved. 3// 4// This program and the accompanying materials 5// are licensed and made available under the terms and conditions of the BSD License 6// which accompanies this distribution. The full text of the license may be found at 7// http://opensource.org/licenses/bsd-license.php 8// 9// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11// 12// 13 14#include <AsmMacroIoLib.h> 15 16#include <Chipset/ArmV7.h> 17 18ASM_FUNC(_ModuleEntryPoint) 19 // Do early platform specific actions 20 bl ASM_PFX(ArmPlatformPeiBootAction) 21 22 // Get ID of this CPU in Multicore system 23 bl ASM_PFX(ArmReadMpidr) 24 // Keep a copy of the MpId register value 25 mov r8, r0 26 27_SetSVCMode: 28 // Enter SVC mode, Disable FIQ and IRQ 29 mov r1, #(CPSR_MODE_SVC | CPSR_IRQ | CPSR_FIQ) 30 msr CPSR_c, r1 31 32// Check if we can install the stack at the top of the System Memory or if we need 33// to install the stacks at the bottom of the Firmware Device (case the FD is located 34// at the top of the DRAM) 35_SystemMemoryEndInit: 36 ADRL (r1, mSystemMemoryEnd) 37 ldrd r2, r3, [r1] 38 teq r3, #0 39 moveq r1, r2 40 mvnne r1, #0 41 42_SetupStackPosition: 43 // r1 = SystemMemoryTop 44 45 // Calculate Top of the Firmware Device 46 MOV32 (r2, FixedPcdGet32(PcdFdBaseAddress)) 47 MOV32 (r3, FixedPcdGet32(PcdFdSize) - 1) 48 add r3, r3, r2 // r3 = FdTop = PcdFdBaseAddress + PcdFdSize 49 50 // UEFI Memory Size (stacks are allocated in this region) 51 MOV32 (r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize)) 52 53 // 54 // Reserve the memory for the UEFI region (contain stacks on its top) 55 // 56 57 // Calculate how much space there is between the top of the Firmware and the Top of the System Memory 58 subs r0, r1, r3 // r0 = SystemMemoryTop - FdTop 59 bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM 60 cmp r0, r4 61 bge _SetupStack 62 63 // Case the top of stacks is the FdBaseAddress 64 mov r1, r2 65 66_SetupStack: 67 // r1 contains the top of the stack (and the UEFI Memory) 68 69 // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment 70 // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the 71 // top of the memory space) 72 adds r9, r1, #1 73 bcs _SetupOverflowStack 74 75_SetupAlignedStack: 76 mov r1, r9 77 b _GetBaseUefiMemory 78 79_SetupOverflowStack: 80 // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE 81 // aligned (4KB) 82 MOV32 (r9, ~EFI_PAGE_MASK & 0xFFFFFFFF) 83 and r1, r1, r9 84 85_GetBaseUefiMemory: 86 // Calculate the Base of the UEFI Memory 87 sub r9, r1, r4 88 89_GetStackBase: 90 // r1 = The top of the Mpcore Stacks 91 // Stack for the primary core = PrimaryCoreStack 92 MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) 93 sub r10, r1, r2 94 95 // Stack for the secondary core = Number of Cores - 1 96 MOV32 (r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize)) 97 sub r10, r10, r1 98 99 // r10 = The base of the MpCore Stacks (primary stack & secondary stacks) 100 mov r0, r10 101 mov r1, r8 102 //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize) 103 MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) 104 MOV32 (r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize)) 105 bl ASM_PFX(ArmPlatformStackSet) 106 107 // Is it the Primary Core ? 108 mov r0, r8 109 bl ASM_PFX(ArmPlatformIsPrimaryCore) 110 cmp r0, #1 111 bne _PrepareArguments 112 113_PrepareArguments: 114 mov r0, r8 115 mov r1, r9 116 mov r2, r10 117 mov r3, sp 118 119 // Move sec startup address into a data register 120 // Ensure we're jumping to FV version of the code (not boot remapped alias) 121 ldr r4, =ASM_PFX(CEntryPoint) 122 123 // Jump to PrePiCore C code 124 // r0 = MpId 125 // r1 = UefiMemoryBase 126 // r2 = StacksBase 127 blx r4 128 129_NeverReturn: 130 b _NeverReturn 131