ArmPlatformPkg: Change the memory model for the ARM Platform components

In the former memory model, the UEFI firmware was expected to be located
at the top of the system memory. Stacks & Pi memory regions were set below
the firmware.
On some platform, the UEFI firmware could be shadowed by the ROM firmware
(case of the BeagleBoard) and in some cases the firmware is copied at the
beginning of the system memory.

With this new memory model, stack and Pi/DXE memory regions are set at the
top of the system memory wherever the UEFI firmware is located in the memory
map.
Because DXE core does not support shadowed firmwares, the system memory covered
by the UEFI firmware is marked as 'Non Present' to avoid to be overlapped by
DXE allocations.



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11992 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
oliviermartin 2011-07-06 16:27:21 +00:00
parent a6caee65ac
commit d269095b71
16 changed files with 413 additions and 359 deletions

View File

@ -51,6 +51,7 @@
# These PCDs should be FeaturePcds. But we used these PCDs as an '#if' in an ASM file.
# Using a FeaturePcd make a '(BOOLEAN) casting for its value which is not understood by the preprocessor.
gArmPlatformTokenSpaceGuid.PcdMPCoreSupport|0|UINT32|0x00000003
gArmPlatformTokenSpaceGuid.PcdMPCoreMaxCores|1|UINT32|0x0000002D
# Stack for CPU Cores in Secure Mode
gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0|UINT32|0x00000005
@ -67,9 +68,6 @@
# Size of the region used by UEFI in permanent memory (Reserved 128MB by default)
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x08000000|UINT32|0x00000015
# Size of the region reserved for fixed address allocations (Reserved 128MB by default)
gArmPlatformTokenSpaceGuid.PcdSystemMemoryFixRegionSize|0x08000000|UINT32|0x00000014
# Size to reserve in the primary core stack for PEI Global Variables
# = sizeof(UINTN) /* PcdPeiServicePtr or HobListPtr */
gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize|0x4|UINT32|0x00000016

View File

@ -348,6 +348,7 @@
gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0x00000000
gArmPlatformTokenSpaceGuid.PcdMPCoreSupport|1
gArmPlatformTokenSpaceGuid.PcdMPCoreMaxCores|2
# Stacks for MPCores in Secure World
gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x4B000000 # Top of SEC Stack for Secure World

View File

@ -384,6 +384,7 @@
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
gArmPlatformTokenSpaceGuid.PcdMPCoreSupport|1
gArmPlatformTokenSpaceGuid.PcdMPCoreMaxCores|4
gArmTokenSpaceGuid.PcdVFPEnabled|1
# Stacks for MPCores in Secure World

View File

@ -67,21 +67,21 @@ MemoryPeim (
IN UINT64 UefiMemorySize
)
{
EFI_STATUS Status;
EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR* EfiMemoryMap;
UINTN Index;
EFI_PHYSICAL_ADDRESS SystemMemoryTop;
EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
UINT64 ResourceLength;
EFI_PEI_HOB_POINTERS NextHob;
EFI_PHYSICAL_ADDRESS FdTop;
EFI_PHYSICAL_ADDRESS SystemMemoryTop;
EFI_PHYSICAL_ADDRESS ResourceTop;
BOOLEAN Found;
// Ensure PcdSystemMemorySize has been set
ASSERT (PcdGet32 (PcdSystemMemorySize) != 0);
SystemMemoryTop = (EFI_PHYSICAL_ADDRESS)((UINT32)PcdGet32 (PcdSystemMemoryBase) + (UINT32)PcdGet32 (PcdSystemMemorySize));
//
// Now, the permanent memory has been installed, we can call AllocatePages()
//
Attributes = (
ResourceAttributes = (
EFI_RESOURCE_ATTRIBUTE_PRESENT |
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
@ -91,70 +91,73 @@ MemoryPeim (
EFI_RESOURCE_ATTRIBUTE_TESTED
);
// If it is not a standalone build we must reserved the space above the base address of the firmware volume
if (!PcdGet32(PcdStandalone)) {
// Check if firmware volume has not be copied at the top of DRAM then we must reserve the extra space
// between the firmware and the top
if (SystemMemoryTop != PcdGet32 (PcdNormalFdBaseAddress) + PcdGet32 (PcdNormalFdSize)) {
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
Attributes & (~EFI_RESOURCE_ATTRIBUTE_TESTED),
PcdGet32 (PcdNormalFdBaseAddress) + PcdGet32 (PcdNormalFdSize),
SystemMemoryTop - (PcdGet32 (PcdNormalFdBaseAddress) + PcdGet32 (PcdNormalFdSize))
);
}
// Reserved the memory space occupied by the firmware volume
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
Attributes & (~EFI_RESOURCE_ATTRIBUTE_PRESENT),
(UINT32)PcdGet32 (PcdNormalFdBaseAddress),
(UINT32)PcdGet32 (PcdNormalFdSize)
);
}
// Check there is no overlap between UEFI and Fix Address Regions
ASSERT (PcdGet32 (PcdSystemMemoryBase) + PcdGet32 (PcdSystemMemoryFixRegionSize) <= UefiMemoryBase);
// Reserved the UEFI Memory Region
// Reserved the memory space occupied by the firmware volume
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
Attributes,
UefiMemoryBase,
UefiMemorySize
);
// Reserved the Fix Address Region
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
Attributes,
ResourceAttributes,
PcdGet32 (PcdSystemMemoryBase),
PcdGet32 (PcdSystemMemoryFixRegionSize)
PcdGet32 (PcdSystemMemorySize)
);
// Reserved the memory between UEFI and Fix Address regions
if (PcdGet32 (PcdSystemMemoryBase) + PcdGet32 (PcdSystemMemoryFixRegionSize) != UefiMemoryBase) {
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
Attributes & (~EFI_RESOURCE_ATTRIBUTE_TESTED),
PcdGet32 (PcdSystemMemoryBase) + PcdGet32 (PcdSystemMemoryFixRegionSize),
UefiMemoryBase - (PcdGet32 (PcdSystemMemoryBase) + PcdGet32 (PcdSystemMemoryFixRegionSize))
);
}
SystemMemoryTop = PcdGet32 (PcdSystemMemoryBase) + PcdGet32 (PcdSystemMemorySize);
FdTop = PcdGet32(PcdNormalFdBaseAddress) + PcdGet32(PcdNormalFdSize);
// If a platform has system memory extensions, it can declare those in this function
Status = ArmPlatformGetAdditionalSystemMemory (&EfiMemoryMap);
if (!EFI_ERROR(Status)) {
// Install the EFI Memory Map
for (Index = 0; EfiMemoryMap[Index].ResourceAttribute != 0; Index++) {
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
EfiMemoryMap[Index].ResourceAttribute,
EfiMemoryMap[Index].PhysicalStart,
EfiMemoryMap[Index].NumberOfBytes
);
// EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE
// core to overwrite this area we must mark the region with the attribute non-present
if ((PcdGet32 (PcdNormalFdBaseAddress) >= PcdGet32 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) {
Found = FALSE;
// Search for System Memory Hob that contains the firmware
NextHob.Raw = GetHobList ();
while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
(PcdGet32(PcdNormalFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) &&
(FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
{
ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
if (PcdGet32(PcdNormalFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) {
if (SystemMemoryTop == FdTop) {
NextHob.ResourceDescriptor->ResourceAttribute = ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT;
} else {
// Create the System Memory HOB for the firmware with the non-present attribute
BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
PcdGet32(PcdNormalFdBaseAddress),
PcdGet32(PcdNormalFdSize));
// Top of the FD is system memory available for UEFI
NextHob.ResourceDescriptor->PhysicalStart += PcdGet32(PcdNormalFdSize);
NextHob.ResourceDescriptor->ResourceLength -= PcdGet32(PcdNormalFdSize);
}
} else {
// Create the System Memory HOB for the firmware with the non-present attribute
BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
PcdGet32(PcdNormalFdBaseAddress),
PcdGet32(PcdNormalFdSize));
// Update the HOB
NextHob.ResourceDescriptor->ResourceLength = PcdGet32(PcdNormalFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart;
// If there is some memory available on the top of the FD then create a HOB
if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) {
// Create the System Memory HOB for the remaining region (top of the FD)
BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
ResourceAttributes,
FdTop,
ResourceTop - FdTop);
}
}
Found = TRUE;
break;
}
NextHob.Raw = GET_NEXT_HOB (NextHob);
}
FreePool (EfiMemoryMap);
ASSERT(Found);
}
// Build Memory Allocation Hob

View File

@ -45,14 +45,11 @@
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdStandalone
gArmTokenSpaceGuid.PcdNormalFdBaseAddress
gArmTokenSpaceGuid.PcdNormalFdSize
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryFixRegionSize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory

View File

@ -95,7 +95,10 @@ InitializeMemory (
)
{
EFI_STATUS Status;
UINTN SystemMemoryBase;
UINTN SystemMemoryTop;
UINTN FdBase;
UINTN FdTop;
UINTN UefiMemoryBase;
DEBUG ((EFI_D_ERROR, "Memory Init PEIM Loaded\n"));
@ -103,27 +106,44 @@ InitializeMemory (
// Ensure PcdSystemMemorySize has been set
ASSERT (FixedPcdGet32 (PcdSystemMemorySize) != 0);
SystemMemoryTop = (UINTN)FixedPcdGet32 (PcdSystemMemoryBase) + (UINTN)FixedPcdGet32 (PcdSystemMemorySize);
SystemMemoryBase = (UINTN)FixedPcdGet32 (PcdSystemMemoryBase);
SystemMemoryTop = SystemMemoryBase + (UINTN)FixedPcdGet32 (PcdSystemMemorySize);
FdBase = (UINTN)PcdGet32 (PcdNormalFdBaseAddress);
FdTop = FdBase + (UINTN)PcdGet32 (PcdNormalFdSize);
//
// Initialize the System Memory (DRAM)
//
if (PcdGet32 (PcdStandalone)) {
// In case of a standalone version, the DRAM is already initialized
ArmPlatformInitializeSystemMemory();
if (!FeaturePcdGet (PcdSystemMemoryInitializeInSec)) {
// In case the DRAM has not been initialized by the secure firmware
ArmPlatformInitializeSystemMemory ();
}
//
// Declare the UEFI memory to PEI
//
if (PcdGet32 (PcdStandalone)) {
// In case of standalone UEFI, we set the UEFI memory region at the top of the DRAM
UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
// In case the firmware has been shadowed in the System Memory
if ((FdBase >= SystemMemoryBase) && (FdTop <= SystemMemoryTop)) {
// Check if there is enough space between the top of the system memory and the top of the
// firmware to place the UEFI memory (for PEI & DXE phases)
if (SystemMemoryTop - FdTop >= FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) {
UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
} else {
// Check there is enough space for the UEFI memory
ASSERT (SystemMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) <= FdBase);
UefiMemoryBase = FdBase - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
}
} else {
// In case of a non standalone UEFI, we set the UEFI memory below the Firmware Volume
UefiMemoryBase = FixedPcdGet32 (PcdNormalFdBaseAddress) - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
// Check the Firmware does not overlapped with the system memory
ASSERT ((FdBase < SystemMemoryBase) || (FdBase >= SystemMemoryTop));
ASSERT ((FdTop <= SystemMemoryBase) || (FdTop > SystemMemoryTop));
UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
}
Status = PeiServicesInstallPeiMemory (UefiMemoryBase,FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
Status = PeiServicesInstallPeiMemory (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
ASSERT_EFI_ERROR (Status);
// Initialize MMU and Memory HOBs (Resource Descriptor HOBs)

View File

@ -49,16 +49,14 @@
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdStandalone
gArmTokenSpaceGuid.PcdNormalFdBaseAddress
gArmTokenSpaceGuid.PcdNormalFdSize
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryFixRegionSize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory

View File

@ -1,101 +1,101 @@
//
// Copyright (c) 2011, ARM Limited. All rights reserved.
//
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
#include <AsmMacroIoLib.h>
#include <Base.h>
#include <AutoGen.h>
#start of the code section
.text
.align 5
# IMPORT
GCC_ASM_IMPORT(PrePiCommonExceptionEntry)
# EXPORT
GCC_ASM_EXPORT(PrePiVectorTable)
//============================================================
//Default Exception Handlers
//============================================================
ASM_PFX(PrePiVectorTable):
b _DefaultResetHandler
b _DefaultUndefined
b _DefaultSWI
b _DefaultPrefetchAbort
b _DefaultDataAbort
b _DefaultReserved
b _DefaultIrq
b _DefaultFiq
//
// Default Exception handlers: There is no plan to return from any of these exceptions.
// No context saving at all.
//
_DefaultResetHandler:
mov r1, lr
# Switch to SVC for common stack
cps #0x13
mov r0, #0
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultUndefined:
sub r1, LR, #4
# Switch to SVC for common stack
cps #0x13
mov r0, #1
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultSWI:
sub r1, LR, #4
# Switch to SVC for common stack
cps #0x13
mov r0, #2
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultPrefetchAbort:
sub r1, LR, #4
# Switch to SVC for common stack
cps #0x13
mov r0, #3
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultDataAbort:
sub r1, LR, #8
# Switch to SVC for common stack
cps #0x13
mov r0, #4
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultReserved:
mov r1, lr
# Switch to SVC for common stack
cps #0x13
mov r0, #5
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultIrq:
sub r1, LR, #4
# Switch to SVC for common stack
cps #0x13
mov r0, #6
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultFiq:
sub r1, LR, #4
# Switch to SVC for common stack
cps #0x13
mov r0, #7
blx ASM_PFX(PrePiCommonExceptionEntry)
//
// Copyright (c) 2011, ARM Limited. All rights reserved.
//
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
#include <AsmMacroIoLib.h>
#include <Base.h>
#include <AutoGen.h>
#start of the code section
.text
.align 5
# IMPORT
GCC_ASM_IMPORT(PrePiCommonExceptionEntry)
# EXPORT
GCC_ASM_EXPORT(PrePiVectorTable)
//============================================================
//Default Exception Handlers
//============================================================
ASM_PFX(PrePiVectorTable):
b _DefaultResetHandler
b _DefaultUndefined
b _DefaultSWI
b _DefaultPrefetchAbort
b _DefaultDataAbort
b _DefaultReserved
b _DefaultIrq
b _DefaultFiq
//
// Default Exception handlers: There is no plan to return from any of these exceptions.
// No context saving at all.
//
_DefaultResetHandler:
mov r1, lr
# Switch to SVC for common stack
cps #0x13
mov r0, #0
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultUndefined:
sub r1, LR, #4
# Switch to SVC for common stack
cps #0x13
mov r0, #1
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultSWI:
sub r1, LR, #4
# Switch to SVC for common stack
cps #0x13
mov r0, #2
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultPrefetchAbort:
sub r1, LR, #4
# Switch to SVC for common stack
cps #0x13
mov r0, #3
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultDataAbort:
sub r1, LR, #8
# Switch to SVC for common stack
cps #0x13
mov r0, #4
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultReserved:
mov r1, lr
# Switch to SVC for common stack
cps #0x13
mov r0, #5
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultIrq:
sub r1, LR, #4
# Switch to SVC for common stack
cps #0x13
mov r0, #6
blx ASM_PFX(PrePiCommonExceptionEntry)
_DefaultFiq:
sub r1, LR, #4
# Switch to SVC for common stack
cps #0x13
mov r0, #7
blx ASM_PFX(PrePiCommonExceptionEntry)

View File

@ -21,20 +21,19 @@
VOID
PrimaryMain (
IN UINTN UefiMemoryBase,
IN UINTN StackBase,
IN UINT64 StartTimeStamp
)
{
//Enable the GIC Distributor
PL390GicEnableDistributor(PcdGet32(PcdGicDistributorBase));
// If ArmVe has not been built as Standalone then we need to wake up the secondary cores
if (!FixedPcdGet32(PcdStandalone)) {
// In some cases, the secondary cores are waiting for an SGI from the next stage boot loader toresume their initialization
if (!FixedPcdGet32(PcdSendSgiToBringUpSecondaryCores)) {
// Sending SGI to all the Secondary CPU interfaces
PL390GicSendSgiTo (PcdGet32(PcdGicDistributorBase), GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E);
}
PrePiMain (UefiMemoryBase, StackBase, StartTimeStamp);
PrePiMain (UefiMemoryBase, StartTimeStamp);
// We must never return
ASSERT(FALSE);

View File

@ -17,11 +17,10 @@
VOID
PrimaryMain (
IN UINTN UefiMemoryBase,
IN UINTN StackBase,
IN UINT64 StartTimeStamp
)
{
PrePiMain (UefiMemoryBase, StackBase, StartTimeStamp);
PrePiMain (UefiMemoryBase, StartTimeStamp);
// We must never return
ASSERT(FALSE);

View File

@ -16,50 +16,70 @@
#include <Library/PcdLib.h>
#include <AutoGen.h>
#start of the code section
.text
.align 3
#global symbols referenced by this module
# Global symbols referenced by this module
GCC_ASM_IMPORT(CEntryPoint)
GCC_ASM_EXPORT(_ModuleEntryPoint)
StartupAddr: .word CEntryPoint
#make _ModuleEntryPoint as global
GCC_ASM_EXPORT(_ModuleEntryPoint)
ASM_PFX(_ModuleEntryPoint):
// Identify CPU ID
mrc p15, 0, r0, c0, c0, 5
and r0, #0xf
_UefiMemoryBase:
#if FixedPcdGet32(PcdStandalone)
_SetSVCMode:
// Enter SVC mode
mov r1, #0x13|0x80|0x40
msr CPSR_c, r1
// Check if we can install the size at the top of the System Memory or if we need
// to install the stacks at the bottom of the Firmware Device (case the FD is located
// at the top of the DRAM)
_SetupStackPosition:
// Compute Top of System Memory
LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryBase), r1)
LoadConstantToReg (FixedPcdGet32(PcdSystemMemorySize), r2)
add r1, r1, r2 // r1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize
#else
// If it is not a Standalone, we must compute the top of the UEFI memory with the base of the FD
LoadConstantToReg (FixedPcdGet32(PcdNormalFdBaseAddress), r1)
#endif
// Compute Base of UEFI Memory
LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), r2)
sub r1, r1, r2 // r1 = SystemMemoryTop - PcdSystemMemoryUefiRegionSize = UefiMemoryBase
// Calculate Top of the Firmware Device
LoadConstantToReg (FixedPcdGet32(PcdNormalFdBaseAddress), r2)
LoadConstantToReg (FixedPcdGet32(PcdNormalFdSize), r3)
add r3, r3, r2 // r4 = FdTop = PcdNormalFdBaseAddress + PcdNormalFdSize
// UEFI Memory Size (stacks are allocated in this region)
LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), r4)
//
// Reserve the memory for the UEFI region (contain stacks on its top)
//
// Calculate how much space there is between the top of the Firmware and the Top of the System Memory
subs r5, r1, r3 // r5 = SystemMemoryTop - FdTop
bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop)
cmp r5, r4
bge _SetupStack
// Case the top of stacks is the FdBaseAddress
mov r1, r2
_SetupStack:
// Compute Base of Normal stacks for CPU Cores
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r2)
mul r3, r0, r2 // r3 = core_id * stack_size = offset from the stack base
sub sp, r1, r3 // r3 = UefiMemoryBase - StackOffset = TopOfStack
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r5)
mul r3, r0, r5 // r3 = core_id * stack_size = offset from the stack base
sub sp, r1, r3 // r3 = (SystemMemoryTop|FdBaseAddress) - StackOffset = TopOfStack
// Only allocate memory in top of the primary core stack
// Calculate the Base of the UEFI Memory
sub r1, r1, r4
// Only allocate memory for global variables at top of the primary core stack
cmp r0, #0
bne _PrepareArguments
_AllocateGlobalPeiVariables:
_AllocateGlobalPrePiVariables:
// Reserve top of the stack for Global PEI Variables (eg: PeiServicesTablePointer)
LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r4)
// The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack
@ -69,16 +89,12 @@ _AllocateGlobalPeiVariables:
sub sp, sp, r4
_PrepareArguments:
// Pass the StackBase to the C Entrypoint (UefiMemoryBase - StackSize - StackOffset)
sub r2, r1, r2
sub r2, r3
// Move sec startup address into a data register
// Ensure we're jumping to FV version of the code (not boot remapped alias)
ldr r3, StartupAddr
ldr r2, StartupAddr
// jump to PrePiCore C code
// Jump to PrePiCore C code
// r0 = core_id
// r1 = UefiMemoryBase
// r2 = StackBase
blx r3
blx r2

View File

@ -31,28 +31,51 @@ _ModuleEntryPoint
mrc p15, 0, r0, c0, c0, 5
and r0, #0xf
_UefiMemoryBase
#if FixedPcdGet32(PcdStandalone)
_SetSVCMode
// Enter SVC mode
mov r1, #0x13|0x80|0x40
msr CPSR_c, r1
// Check if we can install the size at the top of the System Memory or if we need
// to install the stacks at the bottom of the Firmware Device (case the FD is located
// at the top of the DRAM)
_SetupStackPosition
// Compute Top of System Memory
LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryBase), r1)
LoadConstantToReg (FixedPcdGet32(PcdSystemMemorySize), r2)
add r1, r1, r2 // r1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize
#else
// If it is not a Standalone, we must compute the top of the UEFI memory with the base of the FD
LoadConstantToReg (FixedPcdGet32(PcdNormalFdBaseAddress), r1)
#endif
// Compute Base of UEFI Memory
LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), r2)
sub r1, r1, r2 // r1 = SystemMemoryTop - PcdSystemMemoryUefiRegionSize = UefiMemoryBase
// Calculate Top of the Firmware Device
LoadConstantToReg (FixedPcdGet32(PcdNormalFdBaseAddress), r2)
LoadConstantToReg (FixedPcdGet32(PcdNormalFdSize), r3)
add r3, r3, r2 // r4 = FdTop = PcdNormalFdBaseAddress + PcdNormalFdSize
// UEFI Memory Size (stacks are allocated in this region)
LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), r4)
//
// Reserve the memory for the UEFI region (contain stacks on its top)
//
// Calculate how much space there is between the top of the Firmware and the Top of the System Memory
subs r5, r1, r3 // r5 = SystemMemoryTop - FdTop
bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop)
cmp r5, r4
bge _SetupStack
// Case the top of stacks is the FdBaseAddress
mov r1, r2
_SetupStack
// Compute Base of Normal stacks for CPU Cores
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r2)
mul r3, r0, r2 // r3 = core_id * stack_size = offset from the stack base
sub sp, r1, r3 // r3 = UefiMemoryBase - StackOffset = TopOfStack
LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r5)
mul r3, r0, r5 // r3 = core_id * stack_size = offset from the stack base
sub sp, r1, r3 // r3 = (SystemMemoryTop|FdBaseAddress) - StackOffset = TopOfStack
// Only allocate memory in top of the primary core stack
// Calculate the Base of the UEFI Memory
sub r1, r1, r4
// Only allocate memory for global variables at top of the primary core stack
cmp r0, #0
bne _PrepareArguments
@ -66,17 +89,13 @@ _AllocateGlobalPrePiVariables
sub sp, sp, r4
_PrepareArguments
// Pass the StackBase to the C Entrypoint (UefiMemoryBase - StackSize - StackOffset)
sub r2, r1, r2
sub r2, r3
// Move sec startup address into a data register
// Ensure we're jumping to FV version of the code (not boot remapped alias)
ldr r3, StartupAddr
ldr r2, StartupAddr
// jump to PrePiCore C code
// Jump to PrePiCore C code
// r0 = core_id
// r1 = UefiMemoryBase
// r2 = StackBase
blx r3
blx r2
END

View File

@ -81,9 +81,9 @@
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryFixRegionSize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
gArmPlatformTokenSpaceGuid.PcdMPCoreMaxCores
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize

View File

@ -1,93 +1,93 @@
#/** @file
#
# Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ArmPlatformPrePiUniCore
FILE_GUID = d959e387-7b91-452c-90e0-a1dbac90ddb8
MODULE_TYPE = SEC
VERSION_STRING = 1.0
[Sources.ARM]
PrePi.c
ModuleEntryPoint.S | GCC
ModuleEntryPoint.asm | RVCT
Exception.asm | RVCT
Exception.S | GCC
MainUniCore.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
[LibraryClasses]
BaseLib
DebugLib
DebugAgentLib
ArmLib
IoLib
TimerLib
SerialPortLib
ExtractGuidedSectionLib
LzmaDecompressLib
PeCoffGetEntryPointLib
DebugAgentLib
PrePiLib
ArmPlatformLib
MemoryAllocationLib
HobLib
PrePiHobListPointerLib
PlatformPeiLib
MemoryInitPeiLib
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdCacheEnable
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
[FixedPcd]
gArmTokenSpaceGuid.PcdVFPEnabled
gArmTokenSpaceGuid.PcdNormalFdBaseAddress
gArmTokenSpaceGuid.PcdNormalFdSize
gArmTokenSpaceGuid.PcdNormalFvBaseAddress
gArmTokenSpaceGuid.PcdNormalFvSize
gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase
gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize
gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize
gArmPlatformTokenSpaceGuid.PcdHobListPtrGlobalOffset
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryFixRegionSize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
#/** @file
#
# Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ArmPlatformPrePiUniCore
FILE_GUID = d959e387-7b91-452c-90e0-a1dbac90ddb8
MODULE_TYPE = SEC
VERSION_STRING = 1.0
[Sources.ARM]
PrePi.c
ModuleEntryPoint.S | GCC
ModuleEntryPoint.asm | RVCT
Exception.asm | RVCT
Exception.S | GCC
MainUniCore.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
EmbeddedPkg/EmbeddedPkg.dec
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
[LibraryClasses]
BaseLib
DebugLib
DebugAgentLib
ArmLib
IoLib
TimerLib
SerialPortLib
ExtractGuidedSectionLib
LzmaDecompressLib
PeCoffGetEntryPointLib
DebugAgentLib
PrePiLib
ArmPlatformLib
MemoryAllocationLib
HobLib
PrePiHobListPointerLib
PlatformPeiLib
MemoryInitPeiLib
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdCacheEnable
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
[FixedPcd]
gArmTokenSpaceGuid.PcdVFPEnabled
gArmTokenSpaceGuid.PcdNormalFdBaseAddress
gArmTokenSpaceGuid.PcdNormalFdSize
gArmTokenSpaceGuid.PcdNormalFvBaseAddress
gArmTokenSpaceGuid.PcdNormalFvSize
gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase
gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize
gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize
gArmPlatformTokenSpaceGuid.PcdHobListPtrGlobalOffset
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
gArmPlatformTokenSpaceGuid.PcdMPCoreMaxCores
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData

View File

@ -49,14 +49,16 @@ LzmaDecompressLibConstructor (
VOID
PrePiMain (
IN UINTN UefiMemoryBase,
IN UINTN StackBase,
IN UINT64 StartTimeStamp
)
{
EFI_HOB_HANDOFF_INFO_TABLE** PrePiHobBase;
EFI_HOB_HANDOFF_INFO_TABLE** PrePiHobBase;
EFI_STATUS Status;
CHAR8 Buffer[100];
UINTN CharCount;
UINTN UefiMemoryTop;
UINTN StacksSize;
UINTN StacksBase;
// Enable program flow prediction, if supported.
ArmEnableBranchPrediction ();
@ -76,19 +78,24 @@ PrePiMain (
PrePiHobBase = (EFI_HOB_HANDOFF_INFO_TABLE**)(PcdGet32 (PcdCPUCoresNonSecStackBase) + (PcdGet32 (PcdCPUCoresNonSecStackSize) / 2) - PcdGet32 (PcdHobListPtrGlobalOffset));
// We leave UINT32 at the top of UEFI memory for PcdPrePiHobBase
UefiMemoryTop = UefiMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
StacksSize = PcdGet32 (PcdCPUCoresNonSecStackSize) * PcdGet32 (PcdMPCoreMaxCores);
StacksBase = UefiMemoryTop - StacksSize;
// Declare the PI/UEFI memory region
*PrePiHobBase = HobConstructor (
(VOID*)UefiMemoryBase,
FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),
(VOID*)UefiMemoryBase,
(VOID*)(UefiMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) - sizeof(UINT32)));
(VOID*)StacksBase // The top of the UEFI Memory is reserved for the stacks
);
// Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
ASSERT_EFI_ERROR (Status);
// Create the Stack HOB
BuildStackHob (StackBase, FixedPcdGet32(PcdCPUCoresNonSecStackSize));
// Create the Stacks HOB (reserve the memory for all stacks)
BuildStackHob (StacksBase, StacksSize);
// Set the Boot Mode
SetBootMode (ArmPlatformGetBootMode ());
@ -99,8 +106,8 @@ PrePiMain (
BuildMemoryTypeInformationHob ();
//InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL);
//SaveAndSetDebugTimerInterrupt (TRUE);
InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL);
SaveAndSetDebugTimerInterrupt (TRUE);
// Now, the HOB List has been initialized, we can register performance information
PERF_START (NULL, "PEI", NULL, StartTimeStamp);
@ -129,41 +136,38 @@ PrePiMain (
VOID
CEntryPoint (
IN UINTN CoreId,
IN UINTN UefiMemoryBase,
IN UINTN StackBase
IN UINTN UefiMemoryBase
)
{
UINT64 StartTimeStamp;
StartTimeStamp = 0;
if ((CoreId == 0) && PerformanceMeasurementEnabled ()) {
if ((CoreId == ARM_PRIMARY_CORE) && PerformanceMeasurementEnabled ()) {
// Initialize the Timer Library to setup the Timer HW controller
TimerConstructor ();
// We cannot call yet the PerformanceLib because the HOB List has not been initialized
StartTimeStamp = GetPerformanceCounter ();
}
//Clean Data cache
ArmCleanInvalidateDataCache();
// Clean Data cache
ArmCleanInvalidateDataCache ();
//Invalidate instruction cache
ArmInvalidateInstructionCache();
// Invalidate instruction cache
ArmInvalidateInstructionCache ();
//TODO:Drain Write Buffer
// Enable Instruction & Data caches
ArmEnableDataCache();
ArmEnableInstructionCache();
ArmEnableDataCache ();
ArmEnableInstructionCache ();
// Write VBAR - The Vector table must be 32-byte aligned
ASSERT(((UINT32)PrePiVectorTable & ((1 << 5)-1)) == 0);
ArmWriteVBar((UINT32)PrePiVectorTable);
ASSERT (((UINT32)PrePiVectorTable & ((1 << 5)-1)) == 0);
ArmWriteVBar ((UINT32)PrePiVectorTable);
//If not primary Jump to Secondary Main
if(0 == CoreId) {
// If not primary Jump to Secondary Main
if (CoreId == ARM_PRIMARY_CORE) {
// Goto primary Main.
PrimaryMain (UefiMemoryBase, StackBase, StartTimeStamp);
PrimaryMain (UefiMemoryBase, StartTimeStamp);
} else {
SecondaryMain (CoreId);
}

View File

@ -27,6 +27,7 @@
#include <Chipset/ArmV7.h>
#define ARM_PRIMARY_CORE 0
#define SerialPrint(txt) SerialPortWrite (txt, AsciiStrLen(txt)+1);
// Vector Table for PrePi Phase
@ -44,15 +45,14 @@ TimerConstructor (
VOID
PrePiMain (
IN UINTN UefiMemoryBase,
IN UINTN StackBase,
IN UINT64 StartTimeStamp
);
EFI_STATUS
EFIAPI
MemoryPeim (
IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
IN UINT64 UefiMemorySize
IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
IN UINT64 UefiMemorySize
);
EFI_STATUS
@ -64,7 +64,6 @@ PlatformPeim (
VOID
PrimaryMain (
IN UINTN UefiMemoryBase,
IN UINTN StackBase,
IN UINT64 StartTimeStamp
);