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 <AutoGen.h> 15#include <Chipset/ArmV7.h> 16 17 INCLUDE AsmMacroIoLib.inc 18 19 IMPORT CEntryPoint 20 IMPORT ArmPlatformIsPrimaryCore 21 IMPORT ArmReadMpidr 22 IMPORT ArmPlatformPeiBootAction 23 IMPORT ArmPlatformStackSet 24 IMPORT mSystemMemoryEnd 25 26 EXPORT _ModuleEntryPoint 27 28 PRESERVE8 29 AREA PrePiCoreEntryPoint, CODE, READONLY 30 31StartupAddr DCD CEntryPoint 32 33_ModuleEntryPoint 34 // Do early platform specific actions 35 bl ArmPlatformPeiBootAction 36 37 // Get ID of this CPU in Multicore system 38 bl ArmReadMpidr 39 // Keep a copy of the MpId register value 40 mov r8, r0 41 42_SetSVCMode 43 // Enter SVC mode, Disable FIQ and IRQ 44 mov r1, #(CPSR_MODE_SVC :OR: CPSR_IRQ :OR: CPSR_FIQ) 45 msr CPSR_c, r1 46 47// Check if we can install the stack at the top of the System Memory or if we need 48// to install the stacks at the bottom of the Firmware Device (case the FD is located 49// at the top of the DRAM) 50_SystemMemoryEndInit 51 adrll r1, mSystemMemoryEnd 52 ldrd r2, r3, [r1] 53 teq r3, #0 54 moveq r1, r2 55 mvnne r1, #0 56 57_SetupStackPosition 58 // r1 = SystemMemoryTop 59 60 // Calculate Top of the Firmware Device 61 mov32 r2, FixedPcdGet32(PcdFdBaseAddress) 62 mov32 r3, FixedPcdGet32(PcdFdSize) 63 sub r3, r3, #1 64 add r3, r3, r2 // r3 = FdTop = PcdFdBaseAddress + PcdFdSize 65 66 // UEFI Memory Size (stacks are allocated in this region) 67 mov32 r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize) 68 69 // 70 // Reserve the memory for the UEFI region (contain stacks on its top) 71 // 72 73 // Calculate how much space there is between the top of the Firmware and the Top of the System Memory 74 subs r0, r1, r3 // r0 = SystemMemoryTop - FdTop 75 bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM 76 cmp r0, r4 77 bge _SetupStack 78 79 // Case the top of stacks is the FdBaseAddress 80 mov r1, r2 81 82_SetupStack 83 // r1 contains the top of the stack (and the UEFI Memory) 84 85 // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment 86 // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the 87 // top of the memory space) 88 adds r9, r1, #1 89 bcs _SetupOverflowStack 90 91_SetupAlignedStack 92 mov r1, r9 93 b _GetBaseUefiMemory 94 95_SetupOverflowStack 96 // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE 97 // aligned (4KB) 98 mov32 r9, EFI_PAGE_MASK 99 and r9, r9, r1 100 sub r1, r1, r9 101 102_GetBaseUefiMemory 103 // Calculate the Base of the UEFI Memory 104 sub r9, r1, r4 105 106_GetStackBase 107 // r1 = The top of the Mpcore Stacks 108 // Stack for the primary core = PrimaryCoreStack 109 mov32 r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize) 110 sub r10, r1, r2 111 112 // Stack for the secondary core = Number of Cores - 1 113 mov32 r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize) 114 sub r10, r10, r1 115 116 // r10 = The base of the MpCore Stacks (primary stack & secondary stacks) 117 mov r0, r10 118 mov r1, r8 119 //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize) 120 mov32 r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize) 121 mov32 r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize) 122 bl ArmPlatformStackSet 123 124 // Is it the Primary Core ? 125 mov r0, r8 126 bl ArmPlatformIsPrimaryCore 127 cmp r0, #1 128 bne _PrepareArguments 129 130_PrepareArguments 131 mov r0, r8 132 mov r1, r9 133 mov r2, r10 134 135 // Move sec startup address into a data register 136 // Ensure we're jumping to FV version of the code (not boot remapped alias) 137 ldr r4, StartupAddr 138 139 // Jump to PrePiCore C code 140 // r0 = MpId 141 // r1 = UefiMemoryBase 142 // r2 = StacksBase 143 blx r4 144 145_NeverReturn 146 b _NeverReturn 147 148 END 149