PI_SPECIFICATION_VERSION = 0x00010032\r
ENTRY_POINT = StandaloneMmMain\r
\r
-# VALID_ARCHITECTURES = IA32 X64 AARCH64\r
+# VALID_ARCHITECTURES = IA32 X64 AARCH64 ARM\r
\r
[Sources]\r
StandaloneMmCore.c\r
+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2016 HP Development Company, L.P.\r
- Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.\r
-\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <Base.h>\r
-#include <Pi/PiMmCis.h>\r
-\r
-\r
-#include <Library/ArmSvcLib.h>\r
-#include <Library/ArmLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/HobLib.h>\r
-\r
-#include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT\r
-\r
-#include <Guid/ZeroGuid.h>\r
-#include <Guid/MmramMemoryReserve.h>\r
-\r
-#include <IndustryStandard/ArmFfaSvc.h>\r
-#include <IndustryStandard/ArmStdSmc.h>\r
-\r
-#include "StandaloneMmCpu.h"\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-MmFoundationEntryRegister (\r
- IN CONST EFI_MM_CONFIGURATION_PROTOCOL *This,\r
- IN EFI_MM_ENTRY_POINT MmEntryPoint\r
- );\r
-\r
-//\r
-// On ARM platforms every event is expected to have a GUID associated with\r
-// it. It will be used by the MM Entry point to find the handler for the\r
-// event. It will either be populated in a EFI_MM_COMMUNICATE_HEADER by the\r
-// caller of the event (e.g. MM_COMMUNICATE SMC) or by the CPU driver\r
-// (e.g. during an asynchronous event). In either case, this context is\r
-// maintained in an array which has an entry for each CPU. The pointer to this\r
-// array is held in PerCpuGuidedEventContext. Memory is allocated once the\r
-// number of CPUs in the system are made known through the\r
-// MP_INFORMATION_HOB_DATA.\r
-//\r
-EFI_MM_COMMUNICATE_HEADER **PerCpuGuidedEventContext = NULL;\r
-\r
-// Descriptor with whereabouts of memory used for communication with the normal world\r
-EFI_MMRAM_DESCRIPTOR mNsCommBuffer;\r
-\r
-MP_INFORMATION_HOB_DATA *mMpInformationHobData;\r
-\r
-EFI_MM_CONFIGURATION_PROTOCOL mMmConfig = {\r
- 0,\r
- MmFoundationEntryRegister\r
-};\r
-\r
-STATIC EFI_MM_ENTRY_POINT mMmEntryPoint = NULL;\r
-\r
-/**\r
- The PI Standalone MM entry point for the TF-A CPU driver.\r
-\r
- @param [in] EventId The event Id.\r
- @param [in] CpuNumber The CPU number.\r
- @param [in] NsCommBufferAddr Address of the NS common buffer.\r
-\r
- @retval EFI_SUCCESS Success.\r
- @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
- @retval EFI_ACCESS_DENIED Access not permitted.\r
- @retval EFI_OUT_OF_RESOURCES Out of resources.\r
- @retval EFI_UNSUPPORTED Operation not supported.\r
-**/\r
-EFI_STATUS\r
-PiMmStandaloneArmTfCpuDriverEntry (\r
- IN UINTN EventId,\r
- IN UINTN CpuNumber,\r
- IN UINTN NsCommBufferAddr\r
- )\r
-{\r
- EFI_MM_COMMUNICATE_HEADER *GuidedEventContext;\r
- EFI_MM_ENTRY_CONTEXT MmEntryPointContext;\r
- EFI_STATUS Status;\r
- UINTN NsCommBufferSize;\r
-\r
- DEBUG ((DEBUG_INFO, "Received event - 0x%x on cpu %d\n", EventId, CpuNumber));\r
-\r
- Status = EFI_SUCCESS;\r
- //\r
- // ARM TF passes SMC FID of the MM_COMMUNICATE interface as the Event ID upon\r
- // receipt of a synchronous MM request. Use the Event ID to distinguish\r
- // between synchronous and asynchronous events.\r
- //\r
- if ((ARM_SMC_ID_MM_COMMUNICATE_AARCH64 != EventId) &&\r
- (ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ_AARCH64 != EventId)) {\r
- DEBUG ((DEBUG_INFO, "UnRecognized Event - 0x%x\n", EventId));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // Perform parameter validation of NsCommBufferAddr\r
- if (NsCommBufferAddr == (UINTN)NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (NsCommBufferAddr < mNsCommBuffer.PhysicalStart) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- if ((NsCommBufferAddr + sizeof (EFI_MM_COMMUNICATE_HEADER)) >=\r
- (mNsCommBuffer.PhysicalStart + mNsCommBuffer.PhysicalSize)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // Find out the size of the buffer passed\r
- NsCommBufferSize = ((EFI_MM_COMMUNICATE_HEADER *) NsCommBufferAddr)->MessageLength +\r
- sizeof (EFI_MM_COMMUNICATE_HEADER);\r
-\r
- // perform bounds check.\r
- if (NsCommBufferAddr + NsCommBufferSize >=\r
- mNsCommBuffer.PhysicalStart + mNsCommBuffer.PhysicalSize) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- GuidedEventContext = NULL;\r
- // Now that the secure world can see the normal world buffer, allocate\r
- // memory to copy the communication buffer to the secure world.\r
- Status = mMmst->MmAllocatePool (\r
- EfiRuntimeServicesData,\r
- NsCommBufferSize,\r
- (VOID **) &GuidedEventContext\r
- );\r
-\r
- if (Status != EFI_SUCCESS) {\r
- DEBUG ((DEBUG_INFO, "Mem alloc failed - 0x%x\n", EventId));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- // X1 contains the VA of the normal world memory accessible from\r
- // S-EL0\r
- CopyMem (GuidedEventContext, (CONST VOID *) NsCommBufferAddr, NsCommBufferSize);\r
-\r
- // Stash the pointer to the allocated Event Context for this CPU\r
- PerCpuGuidedEventContext[CpuNumber] = GuidedEventContext;\r
-\r
- ZeroMem (&MmEntryPointContext, sizeof (EFI_MM_ENTRY_CONTEXT));\r
-\r
- MmEntryPointContext.CurrentlyExecutingCpu = CpuNumber;\r
- MmEntryPointContext.NumberOfCpus = mMpInformationHobData->NumberOfProcessors;\r
-\r
- // Populate the MM system table with MP and state information\r
- mMmst->CurrentlyExecutingCpu = CpuNumber;\r
- mMmst->NumberOfCpus = mMpInformationHobData->NumberOfProcessors;\r
- mMmst->CpuSaveStateSize = 0;\r
- mMmst->CpuSaveState = NULL;\r
-\r
- if (mMmEntryPoint == NULL) {\r
- DEBUG ((DEBUG_INFO, "Mm Entry point Not Found\n"));\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- mMmEntryPoint (&MmEntryPointContext);\r
-\r
- // Free the memory allocation done earlier and reset the per-cpu context\r
- ASSERT (GuidedEventContext);\r
- CopyMem ((VOID *)NsCommBufferAddr, (CONST VOID *) GuidedEventContext, NsCommBufferSize);\r
-\r
- Status = mMmst->MmFreePool ((VOID *) GuidedEventContext);\r
- if (Status != EFI_SUCCESS) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- PerCpuGuidedEventContext[CpuNumber] = NULL;\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Registers the MM foundation entry point.\r
-\r
- @param [in] This Pointer to the MM Configuration protocol.\r
- @param [in] MmEntryPoint Function pointer to the MM Entry point.\r
-\r
- @retval EFI_SUCCESS Success.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-MmFoundationEntryRegister (\r
- IN CONST EFI_MM_CONFIGURATION_PROTOCOL *This,\r
- IN EFI_MM_ENTRY_POINT MmEntryPoint\r
- )\r
-{\r
- // store the entry point in a global\r
- mMmEntryPoint = MmEntryPoint;\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function is the main entry point for an MM handler dispatch\r
- or communicate-based callback.\r
-\r
- @param DispatchHandle The unique handle assigned to this handler by\r
- MmiHandlerRegister().\r
- @param Context Points to an optional handler context which was\r
- specified when the handler was registered.\r
- @param CommBuffer A pointer to a collection of data in memory that will\r
- be conveyed from a non-MM environment into an\r
- MM environment.\r
- @param CommBufferSize The size of the CommBuffer.\r
-\r
- @return Status Code\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PiMmCpuTpFwRootMmiHandler (\r
- IN EFI_HANDLE DispatchHandle,\r
- IN CONST VOID *Context, OPTIONAL\r
- IN OUT VOID *CommBuffer, OPTIONAL\r
- IN OUT UINTN *CommBufferSize OPTIONAL\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN CpuNumber;\r
-\r
- ASSERT (Context == NULL);\r
- ASSERT (CommBuffer == NULL);\r
- ASSERT (CommBufferSize == NULL);\r
-\r
- CpuNumber = mMmst->CurrentlyExecutingCpu;\r
- if (PerCpuGuidedEventContext[CpuNumber] == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- DEBUG ((DEBUG_INFO, "CommBuffer - 0x%x, CommBufferSize - 0x%x\n",\r
- PerCpuGuidedEventContext[CpuNumber],\r
- PerCpuGuidedEventContext[CpuNumber]->MessageLength));\r
-\r
- Status = mMmst->MmiManage (\r
- &PerCpuGuidedEventContext[CpuNumber]->HeaderGuid,\r
- NULL,\r
- PerCpuGuidedEventContext[CpuNumber]->Data,\r
- &PerCpuGuidedEventContext[CpuNumber]->MessageLength\r
- );\r
-\r
- if (Status != EFI_SUCCESS) {\r
- DEBUG ((DEBUG_WARN, "Unable to manage Guided Event - %d\n", Status));\r
- }\r
-\r
- return Status;\r
-}\r
+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
- Copyright (c) 2016 HP Development Company, L.P.\r
- Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.\r
-\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <Base.h>\r
-#include <Pi/PiMmCis.h>\r
-#include <Library/AArch64/StandaloneMmCoreEntryPoint.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/ArmSvcLib.h>\r
-#include <Library/ArmLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/HobLib.h>\r
-\r
-#include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT\r
-\r
-#include <Guid/ZeroGuid.h>\r
-#include <Guid/MmramMemoryReserve.h>\r
-\r
-\r
-#include "StandaloneMmCpu.h"\r
-\r
-// GUID to identify HOB with whereabouts of communication buffer with Normal\r
-// World\r
-extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;\r
-\r
-// GUID to identify HOB where the entry point of this CPU driver will be\r
-// populated to allow the entry point driver to invoke it upon receipt of an\r
-// event\r
-extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;\r
-\r
-//\r
-// Private copy of the MM system table for future use\r
-//\r
-EFI_MM_SYSTEM_TABLE *mMmst = NULL;\r
-\r
-//\r
-// Globals used to initialize the protocol\r
-//\r
-STATIC EFI_HANDLE mMmCpuHandle = NULL;\r
-\r
-/** Returns the HOB data for the matching HOB GUID.\r
-\r
- @param [in] HobList Pointer to the HOB list.\r
- @param [in] HobGuid The GUID for the HOB.\r
- @param [out] HobData Pointer to the HOB data.\r
-\r
- @retval EFI_SUCCESS The function completed successfully.\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
- @retval EFI_NOT_FOUND Could not find HOB with matching GUID.\r
-**/\r
-EFI_STATUS\r
-GetGuidedHobData (\r
- IN VOID *HobList,\r
- IN CONST EFI_GUID *HobGuid,\r
- OUT VOID **HobData\r
- )\r
-{\r
- EFI_HOB_GUID_TYPE *Hob;\r
-\r
- if ((HobList == NULL) || (HobGuid == NULL) || (HobData == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Hob = GetNextGuidHob (HobGuid, HobList);\r
- if (Hob == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- *HobData = GET_GUID_HOB_DATA (Hob);\r
- if (*HobData == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/** Entry point for the Standalone MM CPU driver.\r
-\r
- @param [in] ImageHandle Unused. Not actual image handle.\r
- @param [in] SystemTable Pointer to MM System table.\r
-\r
- @retval EFI_SUCCESS The function completed successfully.\r
- @retval EFI_INVALID_PARAMETER Invalid parameter.\r
- @retval EFI_OUT_OF_RESOURCES Out of resources.\r
- @retval EFI_NOT_FOUND Failed to find the HOB for the CPU\r
- driver endpoint descriptor.\r
-**/\r
-EFI_STATUS\r
-StandaloneMmCpuInitialize (\r
- IN EFI_HANDLE ImageHandle, // not actual imagehandle\r
- IN EFI_MM_SYSTEM_TABLE *SystemTable // not actual systemtable\r
- )\r
-{\r
- ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;\r
- EFI_CONFIGURATION_TABLE *ConfigurationTable;\r
- MP_INFORMATION_HOB_DATA *MpInformationHobData;\r
- EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;\r
- EFI_STATUS Status;\r
- EFI_HANDLE DispatchHandle;\r
- UINT32 MpInfoSize;\r
- UINTN Index;\r
- UINTN ArraySize;\r
- VOID *HobStart;\r
-\r
- ASSERT (SystemTable != NULL);\r
- mMmst = SystemTable;\r
-\r
- // publish the MM config protocol so the MM core can register its entry point\r
- Status = mMmst->MmInstallProtocolInterface (\r
- &mMmCpuHandle,\r
- &gEfiMmConfigurationProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &mMmConfig\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- // register the root MMI handler\r
- Status = mMmst->MmiHandlerRegister (\r
- PiMmCpuTpFwRootMmiHandler,\r
- NULL,\r
- &DispatchHandle\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- // Retrieve the Hoblist from the MMST to extract the details of the NS\r
- // communication buffer that has been reserved by S-EL1/EL3\r
- ConfigurationTable = mMmst->MmConfigurationTable;\r
- for (Index = 0; Index < mMmst->NumberOfTableEntries; Index++) {\r
- if (CompareGuid (&gEfiHobListGuid, &(ConfigurationTable[Index].VendorGuid))) {\r
- break;\r
- }\r
- }\r
-\r
- // Bail out if the Hoblist could not be found\r
- if (Index >= mMmst->NumberOfTableEntries) {\r
- DEBUG ((DEBUG_INFO, "Hoblist not found - 0x%x\n", Index));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- HobStart = ConfigurationTable[Index].VendorTable;\r
-\r
- //\r
- // Locate the HOB with the buffer to populate the entry point of this driver\r
- //\r
- Status = GetGuidedHobData (\r
- HobStart,\r
- &gEfiArmTfCpuDriverEpDescriptorGuid,\r
- (VOID **) &CpuDriverEntryPointDesc\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_INFO, "ArmTfCpuDriverEpDesc HOB data extraction failed - 0x%x\n", Status));\r
- return Status;\r
- }\r
-\r
- // Share the entry point of the CPU driver\r
- DEBUG ((DEBUG_INFO, "Sharing Cpu Driver EP *0x%lx = 0x%lx\n",\r
- (UINTN) CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr,\r
- (UINTN) PiMmStandaloneArmTfCpuDriverEntry));\r
- *(CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr) = PiMmStandaloneArmTfCpuDriverEntry;\r
-\r
- // Find the descriptor that contains the whereabouts of the buffer for\r
- // communication with the Normal world.\r
- Status = GetGuidedHobData (\r
- HobStart,\r
- &gEfiStandaloneMmNonSecureBufferGuid,\r
- (VOID **) &NsCommBufMmramRange\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_INFO, "NsCommBufMmramRange HOB data extraction failed - 0x%x\n", Status));\r
- return Status;\r
- }\r
-\r
- DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINTN) NsCommBufMmramRange->PhysicalStart));\r
- DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINTN) NsCommBufMmramRange->PhysicalSize));\r
-\r
- CopyMem (&mNsCommBuffer, NsCommBufMmramRange, sizeof(EFI_MMRAM_DESCRIPTOR));\r
- DEBUG ((DEBUG_INFO, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer.CpuStart, mNsCommBuffer.PhysicalSize));\r
-\r
- //\r
- // Extract the MP information from the Hoblist\r
- //\r
- Status = GetGuidedHobData (\r
- HobStart,\r
- &gMpInformationHobGuid,\r
- (VOID **) &MpInformationHobData\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_INFO, "MpInformationHob extraction failed - 0x%x\n", Status));\r
- return Status;\r
- }\r
-\r
- //\r
- // Allocate memory for the MP information and copy over the MP information\r
- // passed by Trusted Firmware. Use the number of processors passed in the HOB\r
- // to copy the processor information\r
- //\r
- MpInfoSize = sizeof (MP_INFORMATION_HOB_DATA) +\r
- (sizeof (EFI_PROCESSOR_INFORMATION) *\r
- MpInformationHobData->NumberOfProcessors);\r
- Status = mMmst->MmAllocatePool (\r
- EfiRuntimeServicesData,\r
- MpInfoSize,\r
- (VOID **) &mMpInformationHobData\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_INFO, "mMpInformationHobData mem alloc failed - 0x%x\n", Status));\r
- return Status;\r
- }\r
-\r
- CopyMem (mMpInformationHobData, MpInformationHobData, MpInfoSize);\r
-\r
- // Print MP information\r
- DEBUG ((DEBUG_INFO, "mMpInformationHobData: 0x%016lx - 0x%lx\n",\r
- mMpInformationHobData->NumberOfProcessors,\r
- mMpInformationHobData->NumberOfEnabledProcessors));\r
- for (Index = 0; Index < mMpInformationHobData->NumberOfProcessors; Index++) {\r
- DEBUG ((DEBUG_INFO, "mMpInformationHobData[0x%lx]: %d, %d, %d\n",\r
- mMpInformationHobData->ProcessorInfoBuffer[Index].ProcessorId,\r
- mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Package,\r
- mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Core,\r
- mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Thread));\r
- }\r
-\r
- //\r
- // Allocate memory for a table to hold pointers to a\r
- // EFI_MM_COMMUNICATE_HEADER for each CPU\r
- //\r
- ArraySize = sizeof (EFI_MM_COMMUNICATE_HEADER *) *\r
- mMpInformationHobData->NumberOfEnabledProcessors;\r
- Status = mMmst->MmAllocatePool (\r
- EfiRuntimeServicesData,\r
- ArraySize,\r
- (VOID **) &PerCpuGuidedEventContext\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_INFO, "PerCpuGuidedEventContext mem alloc failed - 0x%x\n", Status));\r
- return Status;\r
- }\r
- return Status;\r
-}\r
+++ /dev/null
-/** @file\r
- Private header with declarations and definitions specific to the MM Standalone\r
- CPU driver\r
-\r
- Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef _ARM_TF_CPU_DRIVER_H_\r
-#define _ARM_TF_CPU_DRIVER_H_\r
-\r
-#include <Protocol/MmCommunication2.h>\r
-#include <Protocol/MmConfiguration.h>\r
-#include <Protocol/MmCpu.h>\r
-#include <Guid/MpInformation.h>\r
-\r
-//\r
-// CPU driver initialization specific declarations\r
-//\r
-extern EFI_MM_SYSTEM_TABLE *mMmst;\r
-\r
-//\r
-// CPU State Save protocol specific declarations\r
-//\r
-extern EFI_MM_CPU_PROTOCOL mMmCpuState;\r
-\r
-//\r
-// MM event handling specific declarations\r
-//\r
-extern EFI_MM_COMMUNICATE_HEADER **PerCpuGuidedEventContext;\r
-extern EFI_MMRAM_DESCRIPTOR mNsCommBuffer;\r
-extern MP_INFORMATION_HOB_DATA *mMpInformationHobData;\r
-extern EFI_MM_CONFIGURATION_PROTOCOL mMmConfig;\r
-\r
-/**\r
- The PI Standalone MM entry point for the TF-A CPU driver.\r
-\r
- @param [in] EventId The event Id.\r
- @param [in] CpuNumber The CPU number.\r
- @param [in] NsCommBufferAddr Address of the NS common buffer.\r
-\r
- @retval EFI_SUCCESS Success.\r
- @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
- @retval EFI_ACCESS_DENIED Access not permitted.\r
- @retval EFI_OUT_OF_RESOURCES Out of resources.\r
- @retval EFI_UNSUPPORTED Operation not supported.\r
-**/\r
-EFI_STATUS\r
-PiMmStandaloneArmTfCpuDriverEntry (\r
- IN UINTN EventId,\r
- IN UINTN CpuNumber,\r
- IN UINTN NsCommBufferAddr\r
- );\r
-\r
-/**\r
- This function is the main entry point for an MM handler dispatch\r
- or communicate-based callback.\r
-\r
- @param DispatchHandle The unique handle assigned to this handler by\r
- MmiHandlerRegister().\r
- @param Context Points to an optional handler context which was\r
- specified when the handler was registered.\r
- @param CommBuffer A pointer to a collection of data in memory that will\r
- be conveyed from a non-MM environment into an\r
- MM environment.\r
- @param CommBufferSize The size of the CommBuffer.\r
-\r
- @return Status Code\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PiMmCpuTpFwRootMmiHandler (\r
- IN EFI_HANDLE DispatchHandle,\r
- IN CONST VOID *Context, OPTIONAL\r
- IN OUT VOID *CommBuffer, OPTIONAL\r
- IN OUT UINTN *CommBufferSize OPTIONAL\r
- );\r
-\r
-#endif\r
+++ /dev/null
-## @file\r
-# Standalone MM CPU driver for ARM Standard Platforms\r
-#\r
-# Copyright (c) 2009, Apple Inc. All rights reserved.<BR>\r
-# Copyright (c) 2016 HP Development Company, L.P.\r
-# Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.\r
-#\r
-# SPDX-License-Identifier: BSD-2-Clause-Patent\r
-##\r
-\r
-[Defines]\r
- INF_VERSION = 0x0001001A\r
- BASE_NAME = StandaloneMmCpu\r
- FILE_GUID = 58F7A62B-6280-42A7-BC38-10535A64A92C\r
- MODULE_TYPE = MM_STANDALONE\r
- VERSION_STRING = 1.0\r
- PI_SPECIFICATION_VERSION = 0x00010032\r
- ENTRY_POINT = StandaloneMmCpuInitialize\r
-\r
-[Sources]\r
- StandaloneMmCpu.c\r
- StandaloneMmCpu.h\r
- EventHandle.c\r
-\r
-[Packages]\r
- ArmPkg/ArmPkg.dec\r
- MdePkg/MdePkg.dec\r
- MdeModulePkg/MdeModulePkg.dec\r
- StandaloneMmPkg/StandaloneMmPkg.dec\r
-\r
-[LibraryClasses]\r
- ArmLib\r
- ArmSvcLib\r
- BaseMemoryLib\r
- DebugLib\r
- HobLib\r
- StandaloneMmDriverEntryPoint\r
-\r
-[Protocols]\r
- gEfiMmConfigurationProtocolGuid # PROTOCOL ALWAYS_PRODUCED\r
- gEfiMmCpuProtocolGuid # PROTOCOL ALWAYS_PRODUCED\r
-\r
-[Guids]\r
- gEfiHobListGuid\r
- gEfiMmPeiMmramMemoryReserveGuid\r
- gZeroGuid\r
- gMpInformationHobGuid\r
- gEfiStandaloneMmNonSecureBufferGuid\r
- gEfiArmTfCpuDriverEpDescriptorGuid\r
-\r
-[Depex]\r
- TRUE\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2016 HP Development Company, L.P.\r
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.\r
+ Copyright (c) 2021, Linaro Limited\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Pi/PiMmCis.h>\r
+\r
+\r
+#include <Library/ArmSvcLib.h>\r
+#include <Library/ArmLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+\r
+#include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT\r
+\r
+#include <Guid/ZeroGuid.h>\r
+#include <Guid/MmramMemoryReserve.h>\r
+\r
+#include <IndustryStandard/ArmFfaSvc.h>\r
+#include <IndustryStandard/ArmStdSmc.h>\r
+\r
+#include "StandaloneMmCpu.h"\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MmFoundationEntryRegister (\r
+ IN CONST EFI_MM_CONFIGURATION_PROTOCOL *This,\r
+ IN EFI_MM_ENTRY_POINT MmEntryPoint\r
+ );\r
+\r
+//\r
+// On ARM platforms every event is expected to have a GUID associated with\r
+// it. It will be used by the MM Entry point to find the handler for the\r
+// event. It will either be populated in a EFI_MM_COMMUNICATE_HEADER by the\r
+// caller of the event (e.g. MM_COMMUNICATE SMC) or by the CPU driver\r
+// (e.g. during an asynchronous event). In either case, this context is\r
+// maintained in an array which has an entry for each CPU. The pointer to this\r
+// array is held in PerCpuGuidedEventContext. Memory is allocated once the\r
+// number of CPUs in the system are made known through the\r
+// MP_INFORMATION_HOB_DATA.\r
+//\r
+EFI_MM_COMMUNICATE_HEADER **PerCpuGuidedEventContext = NULL;\r
+\r
+// Descriptor with whereabouts of memory used for communication with the normal world\r
+EFI_MMRAM_DESCRIPTOR mNsCommBuffer;\r
+\r
+MP_INFORMATION_HOB_DATA *mMpInformationHobData;\r
+\r
+EFI_MM_CONFIGURATION_PROTOCOL mMmConfig = {\r
+ 0,\r
+ MmFoundationEntryRegister\r
+};\r
+\r
+STATIC EFI_MM_ENTRY_POINT mMmEntryPoint = NULL;\r
+\r
+/**\r
+ The PI Standalone MM entry point for the TF-A CPU driver.\r
+\r
+ @param [in] EventId The event Id.\r
+ @param [in] CpuNumber The CPU number.\r
+ @param [in] NsCommBufferAddr Address of the NS common buffer.\r
+\r
+ @retval EFI_SUCCESS Success.\r
+ @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
+ @retval EFI_ACCESS_DENIED Access not permitted.\r
+ @retval EFI_OUT_OF_RESOURCES Out of resources.\r
+ @retval EFI_UNSUPPORTED Operation not supported.\r
+**/\r
+EFI_STATUS\r
+PiMmStandaloneArmTfCpuDriverEntry (\r
+ IN UINTN EventId,\r
+ IN UINTN CpuNumber,\r
+ IN UINTN NsCommBufferAddr\r
+ )\r
+{\r
+ EFI_MM_COMMUNICATE_HEADER *GuidedEventContext;\r
+ EFI_MM_ENTRY_CONTEXT MmEntryPointContext;\r
+ EFI_STATUS Status;\r
+ UINTN NsCommBufferSize;\r
+\r
+ DEBUG ((DEBUG_INFO, "Received event - 0x%x on cpu %d\n", EventId, CpuNumber));\r
+\r
+ Status = EFI_SUCCESS;\r
+ //\r
+ // ARM TF passes SMC FID of the MM_COMMUNICATE interface as the Event ID upon\r
+ // receipt of a synchronous MM request. Use the Event ID to distinguish\r
+ // between synchronous and asynchronous events.\r
+ //\r
+ if ((ARM_SMC_ID_MM_COMMUNICATE != EventId) &&\r
+ (ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ != EventId)) {\r
+ DEBUG ((DEBUG_INFO, "UnRecognized Event - 0x%x\n", EventId));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ // Perform parameter validation of NsCommBufferAddr\r
+ if (NsCommBufferAddr == (UINTN)NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (NsCommBufferAddr < mNsCommBuffer.PhysicalStart) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ if ((NsCommBufferAddr + sizeof (EFI_MM_COMMUNICATE_HEADER)) >=\r
+ (mNsCommBuffer.PhysicalStart + mNsCommBuffer.PhysicalSize)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ // Find out the size of the buffer passed\r
+ NsCommBufferSize = ((EFI_MM_COMMUNICATE_HEADER *) NsCommBufferAddr)->MessageLength +\r
+ sizeof (EFI_MM_COMMUNICATE_HEADER);\r
+\r
+ // perform bounds check.\r
+ if (NsCommBufferAddr + NsCommBufferSize >=\r
+ mNsCommBuffer.PhysicalStart + mNsCommBuffer.PhysicalSize) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ GuidedEventContext = NULL;\r
+ // Now that the secure world can see the normal world buffer, allocate\r
+ // memory to copy the communication buffer to the secure world.\r
+ Status = mMmst->MmAllocatePool (\r
+ EfiRuntimeServicesData,\r
+ NsCommBufferSize,\r
+ (VOID **) &GuidedEventContext\r
+ );\r
+\r
+ if (Status != EFI_SUCCESS) {\r
+ DEBUG ((DEBUG_INFO, "Mem alloc failed - 0x%x\n", EventId));\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ // X1 contains the VA of the normal world memory accessible from\r
+ // S-EL0\r
+ CopyMem (GuidedEventContext, (CONST VOID *) NsCommBufferAddr, NsCommBufferSize);\r
+\r
+ // Stash the pointer to the allocated Event Context for this CPU\r
+ PerCpuGuidedEventContext[CpuNumber] = GuidedEventContext;\r
+\r
+ ZeroMem (&MmEntryPointContext, sizeof (EFI_MM_ENTRY_CONTEXT));\r
+\r
+ MmEntryPointContext.CurrentlyExecutingCpu = CpuNumber;\r
+ MmEntryPointContext.NumberOfCpus = mMpInformationHobData->NumberOfProcessors;\r
+\r
+ // Populate the MM system table with MP and state information\r
+ mMmst->CurrentlyExecutingCpu = CpuNumber;\r
+ mMmst->NumberOfCpus = mMpInformationHobData->NumberOfProcessors;\r
+ mMmst->CpuSaveStateSize = 0;\r
+ mMmst->CpuSaveState = NULL;\r
+\r
+ if (mMmEntryPoint == NULL) {\r
+ DEBUG ((DEBUG_INFO, "Mm Entry point Not Found\n"));\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ mMmEntryPoint (&MmEntryPointContext);\r
+\r
+ // Free the memory allocation done earlier and reset the per-cpu context\r
+ ASSERT (GuidedEventContext);\r
+ CopyMem ((VOID *)NsCommBufferAddr, (CONST VOID *) GuidedEventContext, NsCommBufferSize);\r
+\r
+ Status = mMmst->MmFreePool ((VOID *) GuidedEventContext);\r
+ if (Status != EFI_SUCCESS) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ PerCpuGuidedEventContext[CpuNumber] = NULL;\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Registers the MM foundation entry point.\r
+\r
+ @param [in] This Pointer to the MM Configuration protocol.\r
+ @param [in] MmEntryPoint Function pointer to the MM Entry point.\r
+\r
+ @retval EFI_SUCCESS Success.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MmFoundationEntryRegister (\r
+ IN CONST EFI_MM_CONFIGURATION_PROTOCOL *This,\r
+ IN EFI_MM_ENTRY_POINT MmEntryPoint\r
+ )\r
+{\r
+ // store the entry point in a global\r
+ mMmEntryPoint = MmEntryPoint;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function is the main entry point for an MM handler dispatch\r
+ or communicate-based callback.\r
+\r
+ @param DispatchHandle The unique handle assigned to this handler by\r
+ MmiHandlerRegister().\r
+ @param Context Points to an optional handler context which was\r
+ specified when the handler was registered.\r
+ @param CommBuffer A pointer to a collection of data in memory that will\r
+ be conveyed from a non-MM environment into an\r
+ MM environment.\r
+ @param CommBufferSize The size of the CommBuffer.\r
+\r
+ @return Status Code\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PiMmCpuTpFwRootMmiHandler (\r
+ IN EFI_HANDLE DispatchHandle,\r
+ IN CONST VOID *Context, OPTIONAL\r
+ IN OUT VOID *CommBuffer, OPTIONAL\r
+ IN OUT UINTN *CommBufferSize OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN CpuNumber;\r
+\r
+ ASSERT (Context == NULL);\r
+ ASSERT (CommBuffer == NULL);\r
+ ASSERT (CommBufferSize == NULL);\r
+\r
+ CpuNumber = mMmst->CurrentlyExecutingCpu;\r
+ if (PerCpuGuidedEventContext[CpuNumber] == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "CommBuffer - 0x%x, CommBufferSize - 0x%x\n",\r
+ PerCpuGuidedEventContext[CpuNumber],\r
+ PerCpuGuidedEventContext[CpuNumber]->MessageLength));\r
+\r
+ Status = mMmst->MmiManage (\r
+ &PerCpuGuidedEventContext[CpuNumber]->HeaderGuid,\r
+ NULL,\r
+ PerCpuGuidedEventContext[CpuNumber]->Data,\r
+ &PerCpuGuidedEventContext[CpuNumber]->MessageLength\r
+ );\r
+\r
+ if (Status != EFI_SUCCESS) {\r
+ DEBUG ((DEBUG_WARN, "Unable to manage Guided Event - %d\n", Status));\r
+ }\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+ Copyright (c) 2016 HP Development Company, L.P.\r
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Pi/PiMmCis.h>\r
+#include <Library/Arm/StandaloneMmCoreEntryPoint.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/ArmSvcLib.h>\r
+#include <Library/ArmLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/HobLib.h>\r
+\r
+#include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT\r
+\r
+#include <Guid/ZeroGuid.h>\r
+#include <Guid/MmramMemoryReserve.h>\r
+\r
+\r
+#include "StandaloneMmCpu.h"\r
+\r
+// GUID to identify HOB with whereabouts of communication buffer with Normal\r
+// World\r
+extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;\r
+\r
+// GUID to identify HOB where the entry point of this CPU driver will be\r
+// populated to allow the entry point driver to invoke it upon receipt of an\r
+// event\r
+extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;\r
+\r
+//\r
+// Private copy of the MM system table for future use\r
+//\r
+EFI_MM_SYSTEM_TABLE *mMmst = NULL;\r
+\r
+//\r
+// Globals used to initialize the protocol\r
+//\r
+STATIC EFI_HANDLE mMmCpuHandle = NULL;\r
+\r
+/** Returns the HOB data for the matching HOB GUID.\r
+\r
+ @param [in] HobList Pointer to the HOB list.\r
+ @param [in] HobGuid The GUID for the HOB.\r
+ @param [out] HobData Pointer to the HOB data.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+ @retval EFI_NOT_FOUND Could not find HOB with matching GUID.\r
+**/\r
+EFI_STATUS\r
+GetGuidedHobData (\r
+ IN VOID *HobList,\r
+ IN CONST EFI_GUID *HobGuid,\r
+ OUT VOID **HobData\r
+ )\r
+{\r
+ EFI_HOB_GUID_TYPE *Hob;\r
+\r
+ if ((HobList == NULL) || (HobGuid == NULL) || (HobData == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Hob = GetNextGuidHob (HobGuid, HobList);\r
+ if (Hob == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ *HobData = GET_GUID_HOB_DATA (Hob);\r
+ if (*HobData == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/** Entry point for the Standalone MM CPU driver.\r
+\r
+ @param [in] ImageHandle Unused. Not actual image handle.\r
+ @param [in] SystemTable Pointer to MM System table.\r
+\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter.\r
+ @retval EFI_OUT_OF_RESOURCES Out of resources.\r
+ @retval EFI_NOT_FOUND Failed to find the HOB for the CPU\r
+ driver endpoint descriptor.\r
+**/\r
+EFI_STATUS\r
+StandaloneMmCpuInitialize (\r
+ IN EFI_HANDLE ImageHandle, // not actual imagehandle\r
+ IN EFI_MM_SYSTEM_TABLE *SystemTable // not actual systemtable\r
+ )\r
+{\r
+ ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;\r
+ EFI_CONFIGURATION_TABLE *ConfigurationTable;\r
+ MP_INFORMATION_HOB_DATA *MpInformationHobData;\r
+ EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE DispatchHandle;\r
+ UINT32 MpInfoSize;\r
+ UINTN Index;\r
+ UINTN ArraySize;\r
+ VOID *HobStart;\r
+\r
+ ASSERT (SystemTable != NULL);\r
+ mMmst = SystemTable;\r
+\r
+ // publish the MM config protocol so the MM core can register its entry point\r
+ Status = mMmst->MmInstallProtocolInterface (\r
+ &mMmCpuHandle,\r
+ &gEfiMmConfigurationProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ &mMmConfig\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // register the root MMI handler\r
+ Status = mMmst->MmiHandlerRegister (\r
+ PiMmCpuTpFwRootMmiHandler,\r
+ NULL,\r
+ &DispatchHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Retrieve the Hoblist from the MMST to extract the details of the NS\r
+ // communication buffer that has been reserved by S-EL1/EL3\r
+ ConfigurationTable = mMmst->MmConfigurationTable;\r
+ for (Index = 0; Index < mMmst->NumberOfTableEntries; Index++) {\r
+ if (CompareGuid (&gEfiHobListGuid, &(ConfigurationTable[Index].VendorGuid))) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ // Bail out if the Hoblist could not be found\r
+ if (Index >= mMmst->NumberOfTableEntries) {\r
+ DEBUG ((DEBUG_INFO, "Hoblist not found - 0x%x\n", Index));\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ HobStart = ConfigurationTable[Index].VendorTable;\r
+\r
+ //\r
+ // Locate the HOB with the buffer to populate the entry point of this driver\r
+ //\r
+ Status = GetGuidedHobData (\r
+ HobStart,\r
+ &gEfiArmTfCpuDriverEpDescriptorGuid,\r
+ (VOID **) &CpuDriverEntryPointDesc\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_INFO, "ArmTfCpuDriverEpDesc HOB data extraction failed - 0x%x\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ // Share the entry point of the CPU driver\r
+ DEBUG ((DEBUG_INFO, "Sharing Cpu Driver EP *0x%lx = 0x%lx\n",\r
+ (UINTN) CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr,\r
+ (UINTN) PiMmStandaloneArmTfCpuDriverEntry));\r
+ *(CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr) = PiMmStandaloneArmTfCpuDriverEntry;\r
+\r
+ // Find the descriptor that contains the whereabouts of the buffer for\r
+ // communication with the Normal world.\r
+ Status = GetGuidedHobData (\r
+ HobStart,\r
+ &gEfiStandaloneMmNonSecureBufferGuid,\r
+ (VOID **) &NsCommBufMmramRange\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_INFO, "NsCommBufMmramRange HOB data extraction failed - 0x%x\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINTN) NsCommBufMmramRange->PhysicalStart));\r
+ DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINTN) NsCommBufMmramRange->PhysicalSize));\r
+\r
+ CopyMem (&mNsCommBuffer, NsCommBufMmramRange, sizeof(EFI_MMRAM_DESCRIPTOR));\r
+ DEBUG ((DEBUG_INFO, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer.CpuStart, mNsCommBuffer.PhysicalSize));\r
+\r
+ //\r
+ // Extract the MP information from the Hoblist\r
+ //\r
+ Status = GetGuidedHobData (\r
+ HobStart,\r
+ &gMpInformationHobGuid,\r
+ (VOID **) &MpInformationHobData\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_INFO, "MpInformationHob extraction failed - 0x%x\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Allocate memory for the MP information and copy over the MP information\r
+ // passed by Trusted Firmware. Use the number of processors passed in the HOB\r
+ // to copy the processor information\r
+ //\r
+ MpInfoSize = sizeof (MP_INFORMATION_HOB_DATA) +\r
+ (sizeof (EFI_PROCESSOR_INFORMATION) *\r
+ MpInformationHobData->NumberOfProcessors);\r
+ Status = mMmst->MmAllocatePool (\r
+ EfiRuntimeServicesData,\r
+ MpInfoSize,\r
+ (VOID **) &mMpInformationHobData\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_INFO, "mMpInformationHobData mem alloc failed - 0x%x\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ CopyMem (mMpInformationHobData, MpInformationHobData, MpInfoSize);\r
+\r
+ // Print MP information\r
+ DEBUG ((DEBUG_INFO, "mMpInformationHobData: 0x%016lx - 0x%lx\n",\r
+ mMpInformationHobData->NumberOfProcessors,\r
+ mMpInformationHobData->NumberOfEnabledProcessors));\r
+ for (Index = 0; Index < mMpInformationHobData->NumberOfProcessors; Index++) {\r
+ DEBUG ((DEBUG_INFO, "mMpInformationHobData[0x%lx]: %d, %d, %d\n",\r
+ mMpInformationHobData->ProcessorInfoBuffer[Index].ProcessorId,\r
+ mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Package,\r
+ mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Core,\r
+ mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Thread));\r
+ }\r
+\r
+ //\r
+ // Allocate memory for a table to hold pointers to a\r
+ // EFI_MM_COMMUNICATE_HEADER for each CPU\r
+ //\r
+ ArraySize = sizeof (EFI_MM_COMMUNICATE_HEADER *) *\r
+ mMpInformationHobData->NumberOfEnabledProcessors;\r
+ Status = mMmst->MmAllocatePool (\r
+ EfiRuntimeServicesData,\r
+ ArraySize,\r
+ (VOID **) &PerCpuGuidedEventContext\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_INFO, "PerCpuGuidedEventContext mem alloc failed - 0x%x\n", Status));\r
+ return Status;\r
+ }\r
+ return Status;\r
+}\r
--- /dev/null
+/** @file\r
+ Private header with declarations and definitions specific to the MM Standalone\r
+ CPU driver\r
+\r
+ Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef _ARM_TF_CPU_DRIVER_H_\r
+#define _ARM_TF_CPU_DRIVER_H_\r
+\r
+#include <Protocol/MmCommunication2.h>\r
+#include <Protocol/MmConfiguration.h>\r
+#include <Protocol/MmCpu.h>\r
+#include <Guid/MpInformation.h>\r
+\r
+//\r
+// CPU driver initialization specific declarations\r
+//\r
+extern EFI_MM_SYSTEM_TABLE *mMmst;\r
+\r
+//\r
+// CPU State Save protocol specific declarations\r
+//\r
+extern EFI_MM_CPU_PROTOCOL mMmCpuState;\r
+\r
+//\r
+// MM event handling specific declarations\r
+//\r
+extern EFI_MM_COMMUNICATE_HEADER **PerCpuGuidedEventContext;\r
+extern EFI_MMRAM_DESCRIPTOR mNsCommBuffer;\r
+extern MP_INFORMATION_HOB_DATA *mMpInformationHobData;\r
+extern EFI_MM_CONFIGURATION_PROTOCOL mMmConfig;\r
+\r
+/**\r
+ The PI Standalone MM entry point for the TF-A CPU driver.\r
+\r
+ @param [in] EventId The event Id.\r
+ @param [in] CpuNumber The CPU number.\r
+ @param [in] NsCommBufferAddr Address of the NS common buffer.\r
+\r
+ @retval EFI_SUCCESS Success.\r
+ @retval EFI_INVALID_PARAMETER A parameter was invalid.\r
+ @retval EFI_ACCESS_DENIED Access not permitted.\r
+ @retval EFI_OUT_OF_RESOURCES Out of resources.\r
+ @retval EFI_UNSUPPORTED Operation not supported.\r
+**/\r
+EFI_STATUS\r
+PiMmStandaloneArmTfCpuDriverEntry (\r
+ IN UINTN EventId,\r
+ IN UINTN CpuNumber,\r
+ IN UINTN NsCommBufferAddr\r
+ );\r
+\r
+/**\r
+ This function is the main entry point for an MM handler dispatch\r
+ or communicate-based callback.\r
+\r
+ @param DispatchHandle The unique handle assigned to this handler by\r
+ MmiHandlerRegister().\r
+ @param Context Points to an optional handler context which was\r
+ specified when the handler was registered.\r
+ @param CommBuffer A pointer to a collection of data in memory that will\r
+ be conveyed from a non-MM environment into an\r
+ MM environment.\r
+ @param CommBufferSize The size of the CommBuffer.\r
+\r
+ @return Status Code\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PiMmCpuTpFwRootMmiHandler (\r
+ IN EFI_HANDLE DispatchHandle,\r
+ IN CONST VOID *Context, OPTIONAL\r
+ IN OUT VOID *CommBuffer, OPTIONAL\r
+ IN OUT UINTN *CommBufferSize OPTIONAL\r
+ );\r
+\r
+#endif\r
--- /dev/null
+## @file\r
+# Standalone MM CPU driver for ARM Standard Platforms\r
+#\r
+# Copyright (c) 2009, Apple Inc. All rights reserved.<BR>\r
+# Copyright (c) 2016 HP Development Company, L.P.\r
+# Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x0001001A\r
+ BASE_NAME = StandaloneMmCpu\r
+ FILE_GUID = 58F7A62B-6280-42A7-BC38-10535A64A92C\r
+ MODULE_TYPE = MM_STANDALONE\r
+ VERSION_STRING = 1.0\r
+ PI_SPECIFICATION_VERSION = 0x00010032\r
+ ENTRY_POINT = StandaloneMmCpuInitialize\r
+\r
+[Sources]\r
+ StandaloneMmCpu.c\r
+ StandaloneMmCpu.h\r
+ EventHandle.c\r
+\r
+[Packages]\r
+ ArmPkg/ArmPkg.dec\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+ StandaloneMmPkg/StandaloneMmPkg.dec\r
+\r
+[LibraryClasses]\r
+ ArmLib\r
+ ArmSvcLib\r
+ BaseMemoryLib\r
+ DebugLib\r
+ HobLib\r
+ StandaloneMmDriverEntryPoint\r
+\r
+[Protocols]\r
+ gEfiMmConfigurationProtocolGuid # PROTOCOL ALWAYS_PRODUCED\r
+ gEfiMmCpuProtocolGuid # PROTOCOL ALWAYS_PRODUCED\r
+\r
+[Guids]\r
+ gEfiHobListGuid\r
+ gEfiMmPeiMmramMemoryReserveGuid\r
+ gZeroGuid\r
+ gMpInformationHobGuid\r
+ gEfiStandaloneMmNonSecureBufferGuid\r
+ gEfiArmTfCpuDriverEpDescriptorGuid\r
+\r
+[Depex]\r
+ TRUE\r
+++ /dev/null
-/** @file\r
- Entry point to the Standalone MM Foundation when initialized during the SEC\r
- phase on ARM platforms\r
-\r
-Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef __STANDALONEMMCORE_ENTRY_POINT_H__\r
-#define __STANDALONEMMCORE_ENTRY_POINT_H__\r
-\r
-#include <Library/PeCoffLib.h>\r
-#include <Library/FvLib.h>\r
-\r
-#define CPU_INFO_FLAG_PRIMARY_CPU 0x00000001\r
-\r
-typedef struct {\r
- UINT8 Type; /* type of the structure */\r
- UINT8 Version; /* version of this structure */\r
- UINT16 Size; /* size of this structure in bytes */\r
- UINT32 Attr; /* attributes: unused bits SBZ */\r
-} EFI_PARAM_HEADER;\r
-\r
-typedef struct {\r
- UINT64 Mpidr;\r
- UINT32 LinearId;\r
- UINT32 Flags;\r
-} EFI_SECURE_PARTITION_CPU_INFO;\r
-\r
-typedef struct {\r
- EFI_PARAM_HEADER Header;\r
- UINT64 SpMemBase;\r
- UINT64 SpMemLimit;\r
- UINT64 SpImageBase;\r
- UINT64 SpStackBase;\r
- UINT64 SpHeapBase;\r
- UINT64 SpNsCommBufBase;\r
- UINT64 SpSharedBufBase;\r
- UINT64 SpImageSize;\r
- UINT64 SpPcpuStackSize;\r
- UINT64 SpHeapSize;\r
- UINT64 SpNsCommBufSize;\r
- UINT64 SpPcpuSharedBufSize;\r
- UINT32 NumSpMemRegions;\r
- UINT32 NumCpus;\r
- EFI_SECURE_PARTITION_CPU_INFO *CpuInfo;\r
-} EFI_SECURE_PARTITION_BOOT_INFO;\r
-\r
-typedef\r
-EFI_STATUS\r
-(*PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT) (\r
- IN UINTN EventId,\r
- IN UINTN CpuNumber,\r
- IN UINTN NsCommBufferAddr\r
- );\r
-\r
-typedef struct {\r
- PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT *ArmTfCpuDriverEpPtr;\r
-} ARM_TF_CPU_DRIVER_EP_DESCRIPTOR;\r
-\r
-typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) (\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length\r
- );\r
-\r
-/**\r
- Privileged firmware assigns RO & Executable attributes to all memory occupied\r
- by the Boot Firmware Volume. This function sets the correct permissions of\r
- sections in the Standalone MM Core module to be able to access RO and RW data\r
- and make further progress in the boot process.\r
-\r
- @param [in] ImageContext Pointer to PE/COFF image context\r
- @param [in] ImageBase Base of image in memory\r
- @param [in] SectionHeaderOffset Offset of PE/COFF image section header\r
- @param [in] NumberOfSections Number of Sections\r
- @param [in] TextUpdater Function to change code permissions\r
- @param [in] ReadOnlyUpdater Function to change RO permissions\r
- @param [in] ReadWriteUpdater Function to change RW permissions\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UpdateMmFoundationPeCoffPermissions (\r
- IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
- IN EFI_PHYSICAL_ADDRESS ImageBase,\r
- IN UINT32 SectionHeaderOffset,\r
- IN CONST UINT16 NumberOfSections,\r
- IN REGION_PERMISSION_UPDATE_FUNC TextUpdater,\r
- IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater,\r
- IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater\r
- );\r
-\r
-\r
-/**\r
- Privileged firmware assigns RO & Executable attributes to all memory occupied\r
- by the Boot Firmware Volume. This function locates the section information of\r
- the Standalone MM Core module to be able to change permissions of the\r
- individual sections later in the boot process.\r
-\r
- @param [in] TeData Pointer to PE/COFF image data\r
- @param [in, out] ImageContext Pointer to PE/COFF image context\r
- @param [out] ImageBase Pointer to ImageBase variable\r
- @param [in, out] SectionHeaderOffset Offset of PE/COFF image section header\r
- @param [in, out] NumberOfSections Number of Sections\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetStandaloneMmCorePeCoffSections (\r
- IN VOID *TeData,\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
- OUT EFI_PHYSICAL_ADDRESS *ImageBase,\r
- IN OUT UINT32 *SectionHeaderOffset,\r
- IN OUT UINT16 *NumberOfSections\r
- );\r
-\r
-\r
-/**\r
- Privileged firmware assigns RO & Executable attributes to all memory occupied\r
- by the Boot Firmware Volume. This function locates the Standalone MM Core\r
- module PE/COFF image in the BFV and returns this information.\r
-\r
- @param [in] BfvAddress Base Address of Boot Firmware Volume\r
- @param [in, out] TeData Pointer to address for allocating memory\r
- for PE/COFF image data\r
- @param [in, out] TeDataSize Pointer to size of PE/COFF image data\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-LocateStandaloneMmCorePeCoffData (\r
- IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress,\r
- IN OUT VOID **TeData,\r
- IN OUT UINTN *TeDataSize\r
- );\r
-\r
-\r
-/**\r
- Use the boot information passed by privileged firmware to populate a HOB list\r
- suitable for consumption by the MM Core and drivers.\r
-\r
- @param [in, out] CpuDriverEntryPoint Address of MM CPU driver entrypoint\r
- @param [in] PayloadBootInfo Boot information passed by privileged\r
- firmware\r
-\r
-**/\r
-VOID *\r
-EFIAPI\r
-CreateHobListFromBootInfo (\r
- IN OUT PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT *CpuDriverEntryPoint,\r
- IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo\r
- );\r
-\r
-\r
-/**\r
- The entry point of Standalone MM Foundation.\r
-\r
- @param [in] SharedBufAddress Pointer to the Buffer between SPM and SP.\r
- @param [in] SharedBufSize Size of the shared buffer.\r
- @param [in] cookie1 Cookie 1\r
- @param [in] cookie2 Cookie 2\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-_ModuleEntryPoint (\r
- IN VOID *SharedBufAddress,\r
- IN UINT64 SharedBufSize,\r
- IN UINT64 cookie1,\r
- IN UINT64 cookie2\r
- );\r
-\r
-\r
-/**\r
- Auto generated function that calls the library constructors for all of the module's dependent libraries.\r
-\r
- This function must be called by _ModuleEntryPoint().\r
- This function calls the set of library constructors for the set of library instances\r
- that a module depends on. This includes library instances that a module depends on\r
- directly and library instances that a module depends on indirectly through other\r
- libraries. This function is auto generated by build tools and those build tools are\r
- responsible for collecting the set of library instances, determine which ones have\r
- constructors, and calling the library constructors in the proper order based upon\r
- each of the library instances own dependencies.\r
-\r
- @param ImageHandle The image handle of the DXE Core.\r
- @param SystemTable A pointer to the EFI System Table.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-ProcessLibraryConstructorList (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_MM_SYSTEM_TABLE *MmSystemTable\r
- );\r
-\r
-\r
-/**\r
- Auto generated function that calls a set of module entry points.\r
-\r
- This function must be called by _ModuleEntryPoint().\r
- This function calls the set of module entry points.\r
- This function is auto generated by build tools and those build tools are responsible\r
- for collecting the module entry points and calling them in a specified order.\r
-\r
- @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-ProcessModuleEntryPointList (\r
- IN VOID *HobStart\r
- );\r
-\r
-#endif\r
--- /dev/null
+/** @file\r
+ Entry point to the Standalone MM Foundation when initialized during the SEC\r
+ phase on ARM platforms\r
+\r
+Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __STANDALONEMMCORE_ENTRY_POINT_H__\r
+#define __STANDALONEMMCORE_ENTRY_POINT_H__\r
+\r
+#include <Library/PeCoffLib.h>\r
+#include <Library/FvLib.h>\r
+\r
+#define CPU_INFO_FLAG_PRIMARY_CPU 0x00000001\r
+\r
+typedef struct {\r
+ UINT8 Type; /* type of the structure */\r
+ UINT8 Version; /* version of this structure */\r
+ UINT16 Size; /* size of this structure in bytes */\r
+ UINT32 Attr; /* attributes: unused bits SBZ */\r
+} EFI_PARAM_HEADER;\r
+\r
+typedef struct {\r
+ UINT64 Mpidr;\r
+ UINT32 LinearId;\r
+ UINT32 Flags;\r
+} EFI_SECURE_PARTITION_CPU_INFO;\r
+\r
+typedef struct {\r
+ EFI_PARAM_HEADER Header;\r
+ UINT64 SpMemBase;\r
+ UINT64 SpMemLimit;\r
+ UINT64 SpImageBase;\r
+ UINT64 SpStackBase;\r
+ UINT64 SpHeapBase;\r
+ UINT64 SpNsCommBufBase;\r
+ UINT64 SpSharedBufBase;\r
+ UINT64 SpImageSize;\r
+ UINT64 SpPcpuStackSize;\r
+ UINT64 SpHeapSize;\r
+ UINT64 SpNsCommBufSize;\r
+ UINT64 SpPcpuSharedBufSize;\r
+ UINT32 NumSpMemRegions;\r
+ UINT32 NumCpus;\r
+ EFI_SECURE_PARTITION_CPU_INFO *CpuInfo;\r
+} EFI_SECURE_PARTITION_BOOT_INFO;\r
+\r
+typedef\r
+EFI_STATUS\r
+(*PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT) (\r
+ IN UINTN EventId,\r
+ IN UINTN CpuNumber,\r
+ IN UINTN NsCommBufferAddr\r
+ );\r
+\r
+typedef struct {\r
+ PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT *ArmTfCpuDriverEpPtr;\r
+} ARM_TF_CPU_DRIVER_EP_DESCRIPTOR;\r
+\r
+typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length\r
+ );\r
+\r
+/**\r
+ Privileged firmware assigns RO & Executable attributes to all memory occupied\r
+ by the Boot Firmware Volume. This function sets the correct permissions of\r
+ sections in the Standalone MM Core module to be able to access RO and RW data\r
+ and make further progress in the boot process.\r
+\r
+ @param [in] ImageContext Pointer to PE/COFF image context\r
+ @param [in] ImageBase Base of image in memory\r
+ @param [in] SectionHeaderOffset Offset of PE/COFF image section header\r
+ @param [in] NumberOfSections Number of Sections\r
+ @param [in] TextUpdater Function to change code permissions\r
+ @param [in] ReadOnlyUpdater Function to change RO permissions\r
+ @param [in] ReadWriteUpdater Function to change RW permissions\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UpdateMmFoundationPeCoffPermissions (\r
+ IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ IN EFI_PHYSICAL_ADDRESS ImageBase,\r
+ IN UINT32 SectionHeaderOffset,\r
+ IN CONST UINT16 NumberOfSections,\r
+ IN REGION_PERMISSION_UPDATE_FUNC TextUpdater,\r
+ IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater,\r
+ IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater\r
+ );\r
+\r
+\r
+/**\r
+ Privileged firmware assigns RO & Executable attributes to all memory occupied\r
+ by the Boot Firmware Volume. This function locates the section information of\r
+ the Standalone MM Core module to be able to change permissions of the\r
+ individual sections later in the boot process.\r
+\r
+ @param [in] TeData Pointer to PE/COFF image data\r
+ @param [in, out] ImageContext Pointer to PE/COFF image context\r
+ @param [out] ImageBase Pointer to ImageBase variable\r
+ @param [in, out] SectionHeaderOffset Offset of PE/COFF image section header\r
+ @param [in, out] NumberOfSections Number of Sections\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetStandaloneMmCorePeCoffSections (\r
+ IN VOID *TeData,\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ OUT EFI_PHYSICAL_ADDRESS *ImageBase,\r
+ IN OUT UINT32 *SectionHeaderOffset,\r
+ IN OUT UINT16 *NumberOfSections\r
+ );\r
+\r
+\r
+/**\r
+ Privileged firmware assigns RO & Executable attributes to all memory occupied\r
+ by the Boot Firmware Volume. This function locates the Standalone MM Core\r
+ module PE/COFF image in the BFV and returns this information.\r
+\r
+ @param [in] BfvAddress Base Address of Boot Firmware Volume\r
+ @param [in, out] TeData Pointer to address for allocating memory\r
+ for PE/COFF image data\r
+ @param [in, out] TeDataSize Pointer to size of PE/COFF image data\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LocateStandaloneMmCorePeCoffData (\r
+ IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress,\r
+ IN OUT VOID **TeData,\r
+ IN OUT UINTN *TeDataSize\r
+ );\r
+\r
+\r
+/**\r
+ Use the boot information passed by privileged firmware to populate a HOB list\r
+ suitable for consumption by the MM Core and drivers.\r
+\r
+ @param [in, out] CpuDriverEntryPoint Address of MM CPU driver entrypoint\r
+ @param [in] PayloadBootInfo Boot information passed by privileged\r
+ firmware\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+CreateHobListFromBootInfo (\r
+ IN OUT PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT *CpuDriverEntryPoint,\r
+ IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo\r
+ );\r
+\r
+\r
+/**\r
+ The entry point of Standalone MM Foundation.\r
+\r
+ @param [in] SharedBufAddress Pointer to the Buffer between SPM and SP.\r
+ @param [in] SharedBufSize Size of the shared buffer.\r
+ @param [in] cookie1 Cookie 1\r
+ @param [in] cookie2 Cookie 2\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+_ModuleEntryPoint (\r
+ IN VOID *SharedBufAddress,\r
+ IN UINT64 SharedBufSize,\r
+ IN UINT64 cookie1,\r
+ IN UINT64 cookie2\r
+ );\r
+\r
+\r
+/**\r
+ Auto generated function that calls the library constructors for all of the module's dependent libraries.\r
+\r
+ This function must be called by _ModuleEntryPoint().\r
+ This function calls the set of library constructors for the set of library instances\r
+ that a module depends on. This includes library instances that a module depends on\r
+ directly and library instances that a module depends on indirectly through other\r
+ libraries. This function is auto generated by build tools and those build tools are\r
+ responsible for collecting the set of library instances, determine which ones have\r
+ constructors, and calling the library constructors in the proper order based upon\r
+ each of the library instances own dependencies.\r
+\r
+ @param ImageHandle The image handle of the DXE Core.\r
+ @param SystemTable A pointer to the EFI System Table.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ProcessLibraryConstructorList (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_MM_SYSTEM_TABLE *MmSystemTable\r
+ );\r
+\r
+\r
+/**\r
+ Auto generated function that calls a set of module entry points.\r
+\r
+ This function must be called by _ModuleEntryPoint().\r
+ This function calls the set of module entry points.\r
+ This function is auto generated by build tools and those build tools are responsible\r
+ for collecting the module entry points and calling them in a specified order.\r
+\r
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ProcessModuleEntryPointList (\r
+ IN VOID *HobStart\r
+ );\r
+\r
+#endif\r
+++ /dev/null
-/** @file\r
- Creates HOB during Standalone MM Foundation entry point\r
- on ARM platforms.\r
-\r
-Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-\r
-#include <PiMm.h>\r
-\r
-#include <PiPei.h>\r
-#include <Guid/MmramMemoryReserve.h>\r
-#include <Guid/MpInformation.h>\r
-\r
-#include <Library/AArch64/StandaloneMmCoreEntryPoint.h>\r
-#include <Library/ArmMmuLib.h>\r
-#include <Library/ArmSvcLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/HobLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/SerialPortLib.h>\r
-\r
-#include <IndustryStandard/ArmStdSmc.h>\r
-\r
-extern EFI_HOB_HANDOFF_INFO_TABLE*\r
-HobConstructor (\r
- IN VOID *EfiMemoryBegin,\r
- IN UINTN EfiMemoryLength,\r
- IN VOID *EfiFreeMemoryBottom,\r
- IN VOID *EfiFreeMemoryTop\r
- );\r
-\r
-// GUID to identify HOB with whereabouts of communication buffer with Normal\r
-// World\r
-extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;\r
-\r
-// GUID to identify HOB where the entry point of the CPU driver will be\r
-// populated to allow this entry point driver to invoke it upon receipt of an\r
-// event\r
-extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;\r
-\r
-/**\r
- Use the boot information passed by privileged firmware to populate a HOB list\r
- suitable for consumption by the MM Core and drivers.\r
-\r
- @param [in, out] CpuDriverEntryPoint Address of MM CPU driver entrypoint\r
- @param [in] PayloadBootInfo Boot information passed by privileged\r
- firmware\r
-\r
-**/\r
-VOID *\r
-CreateHobListFromBootInfo (\r
- IN OUT PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT *CpuDriverEntryPoint,\r
- IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo\r
-)\r
-{\r
- EFI_HOB_HANDOFF_INFO_TABLE *HobStart;\r
- EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;\r
- UINT32 Index;\r
- UINT32 BufferSize;\r
- UINT32 Flags;\r
- EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHob;\r
- EFI_MMRAM_DESCRIPTOR *MmramRanges;\r
- EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;\r
- MP_INFORMATION_HOB_DATA *MpInformationHobData;\r
- EFI_PROCESSOR_INFORMATION *ProcInfoBuffer;\r
- EFI_SECURE_PARTITION_CPU_INFO *CpuInfo;\r
- ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;\r
-\r
- // Create a hoblist with a PHIT and EOH\r
- HobStart = HobConstructor (\r
- (VOID *) (UINTN) PayloadBootInfo->SpMemBase,\r
- (UINTN) PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase,\r
- (VOID *) (UINTN) PayloadBootInfo->SpHeapBase,\r
- (VOID *) (UINTN) (PayloadBootInfo->SpHeapBase + PayloadBootInfo->SpHeapSize)\r
- );\r
-\r
- // Check that the Hoblist starts at the bottom of the Heap\r
- ASSERT (HobStart == (VOID *) (UINTN) PayloadBootInfo->SpHeapBase);\r
-\r
- // Build a Boot Firmware Volume HOB\r
- BuildFvHob (PayloadBootInfo->SpImageBase, PayloadBootInfo->SpImageSize);\r
-\r
- // Build a resource descriptor Hob that describes the available physical\r
- // memory range\r
- Attributes = (\r
- EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
- EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
- EFI_RESOURCE_ATTRIBUTE_TESTED |\r
- EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
- EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
- EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
- EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
- );\r
-\r
- BuildResourceDescriptorHob (\r
- EFI_RESOURCE_SYSTEM_MEMORY,\r
- Attributes,\r
- (UINTN) PayloadBootInfo->SpMemBase,\r
- PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase\r
- );\r
-\r
- // Find the size of the GUIDed HOB with MP information\r
- BufferSize = sizeof (MP_INFORMATION_HOB_DATA);\r
- BufferSize += sizeof (EFI_PROCESSOR_INFORMATION) * PayloadBootInfo->NumCpus;\r
-\r
- // Create a Guided MP information HOB to enable the ARM TF CPU driver to\r
- // perform per-cpu allocations.\r
- MpInformationHobData = BuildGuidHob (&gMpInformationHobGuid, BufferSize);\r
-\r
- // Populate the MP information HOB with the topology information passed by\r
- // privileged firmware\r
- MpInformationHobData->NumberOfProcessors = PayloadBootInfo->NumCpus;\r
- MpInformationHobData->NumberOfEnabledProcessors = PayloadBootInfo->NumCpus;\r
- ProcInfoBuffer = MpInformationHobData->ProcessorInfoBuffer;\r
- CpuInfo = PayloadBootInfo->CpuInfo;\r
-\r
- for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {\r
- ProcInfoBuffer[Index].ProcessorId = CpuInfo[Index].Mpidr;\r
- ProcInfoBuffer[Index].Location.Package = GET_CLUSTER_ID(CpuInfo[Index].Mpidr);\r
- ProcInfoBuffer[Index].Location.Core = GET_CORE_ID(CpuInfo[Index].Mpidr);\r
- ProcInfoBuffer[Index].Location.Thread = GET_CORE_ID(CpuInfo[Index].Mpidr);\r
-\r
- Flags = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;\r
- if (CpuInfo[Index].Flags & CPU_INFO_FLAG_PRIMARY_CPU) {\r
- Flags |= PROCESSOR_AS_BSP_BIT;\r
- }\r
- ProcInfoBuffer[Index].StatusFlag = Flags;\r
- }\r
-\r
- // Create a Guided HOB to tell the ARM TF CPU driver the location and length\r
- // of the communication buffer shared with the Normal world.\r
- NsCommBufMmramRange = (EFI_MMRAM_DESCRIPTOR *) BuildGuidHob (\r
- &gEfiStandaloneMmNonSecureBufferGuid,\r
- sizeof (EFI_MMRAM_DESCRIPTOR)\r
- );\r
- NsCommBufMmramRange->PhysicalStart = PayloadBootInfo->SpNsCommBufBase;\r
- NsCommBufMmramRange->CpuStart = PayloadBootInfo->SpNsCommBufBase;\r
- NsCommBufMmramRange->PhysicalSize = PayloadBootInfo->SpNsCommBufSize;\r
- NsCommBufMmramRange->RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
-\r
- // Create a Guided HOB to enable the ARM TF CPU driver to share its entry\r
- // point and populate it with the address of the shared buffer\r
- CpuDriverEntryPointDesc = (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *) BuildGuidHob (\r
- &gEfiArmTfCpuDriverEpDescriptorGuid,\r
- sizeof (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR)\r
- );\r
-\r
- *CpuDriverEntryPoint = NULL;\r
- CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr = CpuDriverEntryPoint;\r
-\r
- // Find the size of the GUIDed HOB with SRAM ranges\r
- BufferSize = sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK);\r
- BufferSize += PayloadBootInfo->NumSpMemRegions * sizeof (EFI_MMRAM_DESCRIPTOR);\r
-\r
- // Create a GUIDed HOB with SRAM ranges\r
- MmramRangesHob = BuildGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, BufferSize);\r
-\r
- // Fill up the number of MMRAM memory regions\r
- MmramRangesHob->NumberOfMmReservedRegions = PayloadBootInfo->NumSpMemRegions;\r
- // Fill up the MMRAM ranges\r
- MmramRanges = &MmramRangesHob->Descriptor[0];\r
-\r
- // Base and size of memory occupied by the Standalone MM image\r
- MmramRanges[0].PhysicalStart = PayloadBootInfo->SpImageBase;\r
- MmramRanges[0].CpuStart = PayloadBootInfo->SpImageBase;\r
- MmramRanges[0].PhysicalSize = PayloadBootInfo->SpImageSize;\r
- MmramRanges[0].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
-\r
- // Base and size of buffer shared with privileged Secure world software\r
- MmramRanges[1].PhysicalStart = PayloadBootInfo->SpSharedBufBase;\r
- MmramRanges[1].CpuStart = PayloadBootInfo->SpSharedBufBase;\r
- MmramRanges[1].PhysicalSize = PayloadBootInfo->SpPcpuSharedBufSize * PayloadBootInfo->NumCpus;\r
- MmramRanges[1].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
-\r
- // Base and size of buffer used for synchronous communication with Normal\r
- // world software\r
- MmramRanges[2].PhysicalStart = PayloadBootInfo->SpNsCommBufBase;\r
- MmramRanges[2].CpuStart = PayloadBootInfo->SpNsCommBufBase;\r
- MmramRanges[2].PhysicalSize = PayloadBootInfo->SpNsCommBufSize;\r
- MmramRanges[2].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
-\r
- // Base and size of memory allocated for stacks for all cpus\r
- MmramRanges[3].PhysicalStart = PayloadBootInfo->SpStackBase;\r
- MmramRanges[3].CpuStart = PayloadBootInfo->SpStackBase;\r
- MmramRanges[3].PhysicalSize = PayloadBootInfo->SpPcpuStackSize * PayloadBootInfo->NumCpus;\r
- MmramRanges[3].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
-\r
- // Base and size of heap memory shared by all cpus\r
- MmramRanges[4].PhysicalStart = (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;\r
- MmramRanges[4].CpuStart = (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;\r
- MmramRanges[4].PhysicalSize = HobStart->EfiFreeMemoryBottom - (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;\r
- MmramRanges[4].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
-\r
- // Base and size of heap memory shared by all cpus\r
- MmramRanges[5].PhysicalStart = HobStart->EfiFreeMemoryBottom;\r
- MmramRanges[5].CpuStart = HobStart->EfiFreeMemoryBottom;\r
- MmramRanges[5].PhysicalSize = HobStart->EfiFreeMemoryTop - HobStart->EfiFreeMemoryBottom;\r
- MmramRanges[5].RegionState = EFI_CACHEABLE;\r
-\r
- return HobStart;\r
-}\r
+++ /dev/null
-/** @file\r
- Locate, get and update PE/COFF permissions during Standalone MM\r
- Foundation Entry point on ARM platforms.\r
-\r
-Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-\r
-#include <PiMm.h>\r
-\r
-#include <PiPei.h>\r
-#include <Guid/MmramMemoryReserve.h>\r
-#include <Guid/MpInformation.h>\r
-\r
-#include <Library/AArch64/StandaloneMmCoreEntryPoint.h>\r
-#include <Library/ArmMmuLib.h>\r
-#include <Library/ArmSvcLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/HobLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/SerialPortLib.h>\r
-\r
-#include <IndustryStandard/ArmStdSmc.h>\r
-\r
-/**\r
- Privileged firmware assigns RO & Executable attributes to all memory occupied\r
- by the Boot Firmware Volume. This function sets the correct permissions of\r
- sections in the Standalone MM Core module to be able to access RO and RW data\r
- and make further progress in the boot process.\r
-\r
- @param [in] ImageContext Pointer to PE/COFF image context\r
- @param [in] ImageBase Base of image in memory\r
- @param [in] SectionHeaderOffset Offset of PE/COFF image section header\r
- @param [in] NumberOfSections Number of Sections\r
- @param [in] TextUpdater Function to change code permissions\r
- @param [in] ReadOnlyUpdater Function to change RO permissions\r
- @param [in] ReadWriteUpdater Function to change RW permissions\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UpdateMmFoundationPeCoffPermissions (\r
- IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
- IN EFI_PHYSICAL_ADDRESS ImageBase,\r
- IN UINT32 SectionHeaderOffset,\r
- IN CONST UINT16 NumberOfSections,\r
- IN REGION_PERMISSION_UPDATE_FUNC TextUpdater,\r
- IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater,\r
- IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater\r
- )\r
-{\r
- EFI_IMAGE_SECTION_HEADER SectionHeader;\r
- RETURN_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS Base;\r
- UINTN Size;\r
- UINTN ReadSize;\r
- UINTN Index;\r
-\r
- ASSERT (ImageContext != NULL);\r
-\r
- //\r
- // Iterate over the sections\r
- //\r
- for (Index = 0; Index < NumberOfSections; Index++) {\r
- //\r
- // Read section header from file\r
- //\r
- Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
- ReadSize = Size;\r
- Status = ImageContext->ImageRead (\r
- ImageContext->Handle,\r
- SectionHeaderOffset,\r
- &Size,\r
- &SectionHeader\r
- );\r
-\r
- if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
- DEBUG ((DEBUG_ERROR,\r
- "%a: ImageContext->ImageRead () failed (Status = %r)\n",\r
- __FUNCTION__, Status));\r
- return Status;\r
- }\r
-\r
- DEBUG ((DEBUG_INFO,\r
- "%a: Section %d of image at 0x%lx has 0x%x permissions\n",\r
- __FUNCTION__, Index, ImageContext->ImageAddress, SectionHeader.Characteristics));\r
- DEBUG ((DEBUG_INFO,\r
- "%a: Section %d of image at 0x%lx has %a name\n",\r
- __FUNCTION__, Index, ImageContext->ImageAddress, SectionHeader.Name));\r
- DEBUG ((DEBUG_INFO,\r
- "%a: Section %d of image at 0x%lx has 0x%x address\n",\r
- __FUNCTION__, Index, ImageContext->ImageAddress,\r
- ImageContext->ImageAddress + SectionHeader.VirtualAddress));\r
- DEBUG ((DEBUG_INFO,\r
- "%a: Section %d of image at 0x%lx has 0x%x data\n",\r
- __FUNCTION__, Index, ImageContext->ImageAddress, SectionHeader.PointerToRawData));\r
-\r
- //\r
- // If the section is marked as XN then remove the X attribute. Furthermore,\r
- // if it is a writeable section then mark it appropriately as well.\r
- //\r
- if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) {\r
- Base = ImageBase + SectionHeader.VirtualAddress;\r
-\r
- TextUpdater (Base, SectionHeader.Misc.VirtualSize);\r
-\r
- if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_WRITE) != 0) {\r
- ReadWriteUpdater (Base, SectionHeader.Misc.VirtualSize);\r
- DEBUG ((DEBUG_INFO,\r
- "%a: Mapping section %d of image at 0x%lx with RW-XN permissions\n",\r
- __FUNCTION__, Index, ImageContext->ImageAddress));\r
- } else {\r
- DEBUG ((DEBUG_INFO,\r
- "%a: Mapping section %d of image at 0x%lx with RO-XN permissions\n",\r
- __FUNCTION__, Index, ImageContext->ImageAddress));\r
- }\r
- } else {\r
- DEBUG ((DEBUG_INFO,\r
- "%a: Ignoring section %d of image at 0x%lx with 0x%x permissions\n",\r
- __FUNCTION__, Index, ImageContext->ImageAddress, SectionHeader.Characteristics));\r
- }\r
- SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
- }\r
-\r
- return RETURN_SUCCESS;\r
-}\r
-\r
-/**\r
- Privileged firmware assigns RO & Executable attributes to all memory occupied\r
- by the Boot Firmware Volume. This function locates the Standalone MM Core\r
- module PE/COFF image in the BFV and returns this information.\r
-\r
- @param [in] BfvAddress Base Address of Boot Firmware Volume\r
- @param [in, out] TeData Pointer to address for allocating memory\r
- for PE/COFF image data\r
- @param [in, out] TeDataSize Pointer to size of PE/COFF image data\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-LocateStandaloneMmCorePeCoffData (\r
- IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress,\r
- IN OUT VOID **TeData,\r
- IN OUT UINTN *TeDataSize\r
- )\r
-{\r
- EFI_FFS_FILE_HEADER *FileHeader;\r
- EFI_STATUS Status;\r
-\r
- FileHeader = NULL;\r
- Status = FfsFindNextFile (\r
- EFI_FV_FILETYPE_SECURITY_CORE,\r
- BfvAddress,\r
- &FileHeader\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM FFS file - 0x%x\n",\r
- Status));\r
- return Status;\r
- }\r
-\r
- Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, TeData, TeDataSize);\r
- if (EFI_ERROR (Status)) {\r
- Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, TeData, TeDataSize);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Section data - %r\n",\r
- Status));\r
- return Status;\r
- }\r
- }\r
-\r
- DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", *TeData));\r
- return Status;\r
-}\r
-\r
-/**\r
- Returns the PC COFF section information.\r
-\r
- @param [in, out] ImageContext Pointer to PE/COFF image context\r
- @param [out] ImageBase Base of image in memory\r
- @param [out] SectionHeaderOffset Offset of PE/COFF image section header\r
- @param [out] NumberOfSections Number of Sections\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-GetPeCoffSectionInformation (\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
- OUT EFI_PHYSICAL_ADDRESS *ImageBase,\r
- OUT UINT32 *SectionHeaderOffset,\r
- OUT UINT16 *NumberOfSections\r
- )\r
-{\r
- RETURN_STATUS Status;\r
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
- EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;\r
- UINTN Size;\r
- UINTN ReadSize;\r
-\r
- ASSERT (ImageContext != NULL);\r
- ASSERT (SectionHeaderOffset != NULL);\r
- ASSERT (NumberOfSections != NULL);\r
-\r
- Status = PeCoffLoaderGetImageInfo (ImageContext);\r
- if (RETURN_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR,\r
- "%a: PeCoffLoaderGetImageInfo () failed (Status == %r)\n",\r
- __FUNCTION__, Status));\r
- return Status;\r
- }\r
-\r
- if (ImageContext->SectionAlignment < EFI_PAGE_SIZE) {\r
- //\r
- // The sections need to be at least 4 KB aligned, since that is the\r
- // granularity at which we can tighten permissions.\r
- //\r
- if (!ImageContext->IsTeImage) {\r
- DEBUG ((DEBUG_WARN,\r
- "%a: non-TE Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n",\r
- __FUNCTION__, ImageContext->ImageAddress, ImageContext->SectionAlignment));\r
- return RETURN_UNSUPPORTED;\r
- }\r
- ImageContext->SectionAlignment = EFI_PAGE_SIZE;\r
- }\r
-\r
- //\r
- // Read the PE/COFF Header. For PE32 (32-bit) this will read in too much\r
- // data, but that should not hurt anything. Hdr.Pe32->OptionalHeader.Magic\r
- // determines if this is a PE32 or PE32+ image. The magic is in the same\r
- // location in both images.\r
- //\r
- Hdr.Union = &HdrData;\r
- Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);\r
- ReadSize = Size;\r
- Status = ImageContext->ImageRead (\r
- ImageContext->Handle,\r
- ImageContext->PeCoffHeaderOffset,\r
- &Size,\r
- Hdr.Pe32\r
- );\r
-\r
- if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
- DEBUG ((DEBUG_ERROR,\r
- "%a: TmpContext->ImageRead () failed (Status = %r)\n",\r
- __FUNCTION__, Status));\r
- return Status;\r
- }\r
-\r
- *ImageBase = ImageContext->ImageAddress;\r
- if (!ImageContext->IsTeImage) {\r
- ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE);\r
-\r
- *SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) +\r
- sizeof (EFI_IMAGE_FILE_HEADER);\r
- *NumberOfSections = Hdr.Pe32->FileHeader.NumberOfSections;\r
-\r
- switch (Hdr.Pe32->OptionalHeader.Magic) {\r
- case EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC:\r
- *SectionHeaderOffset += Hdr.Pe32->FileHeader.SizeOfOptionalHeader;\r
- break;\r
- case EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC:\r
- *SectionHeaderOffset += Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader;\r
- break;\r
- default:\r
- ASSERT (FALSE);\r
- }\r
- } else {\r
- *SectionHeaderOffset = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER));\r
- *NumberOfSections = Hdr.Te->NumberOfSections;\r
- *ImageBase -= (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);\r
- }\r
- return RETURN_SUCCESS;\r
-}\r
-\r
-/**\r
- Privileged firmware assigns RO & Executable attributes to all memory occupied\r
- by the Boot Firmware Volume. This function locates the section information of\r
- the Standalone MM Core module to be able to change permissions of the\r
- individual sections later in the boot process.\r
-\r
- @param [in] TeData Pointer to PE/COFF image data\r
- @param [in, out] ImageContext Pointer to PE/COFF image context\r
- @param [out] ImageBase Pointer to ImageBase variable\r
- @param [in, out] SectionHeaderOffset Offset of PE/COFF image section header\r
- @param [in, out] NumberOfSections Number of Sections\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetStandaloneMmCorePeCoffSections (\r
- IN VOID *TeData,\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
- OUT EFI_PHYSICAL_ADDRESS *ImageBase,\r
- IN OUT UINT32 *SectionHeaderOffset,\r
- IN OUT UINT16 *NumberOfSections\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- // Initialize the Image Context\r
- ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));\r
- ImageContext->Handle = TeData;\r
- ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory;\r
-\r
- DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData));\r
-\r
- Status = GetPeCoffSectionInformation (ImageContext, ImageBase,\r
- SectionHeaderOffset, NumberOfSections);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status));\r
- return Status;\r
- }\r
-\r
- DEBUG ((DEBUG_INFO, "Standalone MM Core PE-COFF SectionHeaderOffset - 0x%x, NumberOfSections - %d\n",\r
- *SectionHeaderOffset, *NumberOfSections));\r
-\r
- return Status;\r
-}\r
+++ /dev/null
-/** @file\r
- Entry point to the Standalone MM Foundation when initialized during the SEC\r
- phase on ARM platforms\r
-\r
-Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-\r
-#include <PiMm.h>\r
-\r
-#include <Library/AArch64/StandaloneMmCoreEntryPoint.h>\r
-\r
-#include <PiPei.h>\r
-#include <Guid/MmramMemoryReserve.h>\r
-#include <Guid/MpInformation.h>\r
-\r
-#include <Library/ArmMmuLib.h>\r
-#include <Library/ArmSvcLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/HobLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/SerialPortLib.h>\r
-#include <Library/PcdLib.h>\r
-\r
-#include <IndustryStandard/ArmStdSmc.h>\r
-#include <IndustryStandard/ArmMmSvc.h>\r
-#include <IndustryStandard/ArmFfaSvc.h>\r
-\r
-#define SPM_MAJOR_VER_MASK 0xFFFF0000\r
-#define SPM_MINOR_VER_MASK 0x0000FFFF\r
-#define SPM_MAJOR_VER_SHIFT 16\r
-#define FFA_NOT_SUPPORTED -1\r
-\r
-STATIC CONST UINT32 mSpmMajorVer = SPM_MAJOR_VERSION;\r
-STATIC CONST UINT32 mSpmMinorVer = SPM_MINOR_VERSION;\r
-\r
-STATIC CONST UINT32 mSpmMajorVerFfa = SPM_MAJOR_VERSION_FFA;\r
-STATIC CONST UINT32 mSpmMinorVerFfa = SPM_MINOR_VERSION_FFA;\r
-\r
-#define BOOT_PAYLOAD_VERSION 1\r
-\r
-PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint = NULL;\r
-\r
-/**\r
- Retrieve a pointer to and print the boot information passed by privileged\r
- secure firmware.\r
-\r
- @param [in] SharedBufAddress The pointer memory shared with privileged\r
- firmware.\r
-\r
-**/\r
-EFI_SECURE_PARTITION_BOOT_INFO *\r
-GetAndPrintBootinformation (\r
- IN VOID *SharedBufAddress\r
-)\r
-{\r
- EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;\r
- EFI_SECURE_PARTITION_CPU_INFO *PayloadCpuInfo;\r
- UINTN Index;\r
-\r
- PayloadBootInfo = (EFI_SECURE_PARTITION_BOOT_INFO *) SharedBufAddress;\r
-\r
- if (PayloadBootInfo == NULL) {\r
- DEBUG ((DEBUG_ERROR, "PayloadBootInfo NULL\n"));\r
- return NULL;\r
- }\r
-\r
- if (PayloadBootInfo->Header.Version != BOOT_PAYLOAD_VERSION) {\r
- DEBUG ((DEBUG_ERROR, "Boot Information Version Mismatch. Current=0x%x, Expected=0x%x.\n",\r
- PayloadBootInfo->Header.Version, BOOT_PAYLOAD_VERSION));\r
- return NULL;\r
- }\r
-\r
- DEBUG ((DEBUG_INFO, "NumSpMemRegions - 0x%x\n", PayloadBootInfo->NumSpMemRegions));\r
- DEBUG ((DEBUG_INFO, "SpMemBase - 0x%lx\n", PayloadBootInfo->SpMemBase));\r
- DEBUG ((DEBUG_INFO, "SpMemLimit - 0x%lx\n", PayloadBootInfo->SpMemLimit));\r
- DEBUG ((DEBUG_INFO, "SpImageBase - 0x%lx\n", PayloadBootInfo->SpImageBase));\r
- DEBUG ((DEBUG_INFO, "SpStackBase - 0x%lx\n", PayloadBootInfo->SpStackBase));\r
- DEBUG ((DEBUG_INFO, "SpHeapBase - 0x%lx\n", PayloadBootInfo->SpHeapBase));\r
- DEBUG ((DEBUG_INFO, "SpNsCommBufBase - 0x%lx\n", PayloadBootInfo->SpNsCommBufBase));\r
- DEBUG ((DEBUG_INFO, "SpSharedBufBase - 0x%lx\n", PayloadBootInfo->SpSharedBufBase));\r
-\r
- DEBUG ((DEBUG_INFO, "SpImageSize - 0x%x\n", PayloadBootInfo->SpImageSize));\r
- DEBUG ((DEBUG_INFO, "SpPcpuStackSize - 0x%x\n", PayloadBootInfo->SpPcpuStackSize));\r
- DEBUG ((DEBUG_INFO, "SpHeapSize - 0x%x\n", PayloadBootInfo->SpHeapSize));\r
- DEBUG ((DEBUG_INFO, "SpNsCommBufSize - 0x%x\n", PayloadBootInfo->SpNsCommBufSize));\r
- DEBUG ((DEBUG_INFO, "SpPcpuSharedBufSize - 0x%x\n", PayloadBootInfo->SpPcpuSharedBufSize));\r
-\r
- DEBUG ((DEBUG_INFO, "NumCpus - 0x%x\n", PayloadBootInfo->NumCpus));\r
- DEBUG ((DEBUG_INFO, "CpuInfo - 0x%p\n", PayloadBootInfo->CpuInfo));\r
-\r
- PayloadCpuInfo = (EFI_SECURE_PARTITION_CPU_INFO *) PayloadBootInfo->CpuInfo;\r
-\r
- if (PayloadCpuInfo == NULL) {\r
- DEBUG ((DEBUG_ERROR, "PayloadCpuInfo NULL\n"));\r
- return NULL;\r
- }\r
-\r
- for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {\r
- DEBUG ((DEBUG_INFO, "Mpidr - 0x%lx\n", PayloadCpuInfo[Index].Mpidr));\r
- DEBUG ((DEBUG_INFO, "LinearId - 0x%x\n", PayloadCpuInfo[Index].LinearId));\r
- DEBUG ((DEBUG_INFO, "Flags - 0x%x\n", PayloadCpuInfo[Index].Flags));\r
- }\r
-\r
- return PayloadBootInfo;\r
-}\r
-\r
-/**\r
- A loop to delegated events.\r
-\r
- @param [in] EventCompleteSvcArgs Pointer to the event completion arguments.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-DelegatedEventLoop (\r
- IN ARM_SVC_ARGS *EventCompleteSvcArgs\r
- )\r
-{\r
- BOOLEAN FfaEnabled;\r
- EFI_STATUS Status;\r
- UINTN SvcStatus;\r
-\r
- while (TRUE) {\r
- ArmCallSvc (EventCompleteSvcArgs);\r
-\r
- DEBUG ((DEBUG_INFO, "Received delegated event\n"));\r
- DEBUG ((DEBUG_INFO, "X0 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg0));\r
- DEBUG ((DEBUG_INFO, "X1 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg1));\r
- DEBUG ((DEBUG_INFO, "X2 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg2));\r
- DEBUG ((DEBUG_INFO, "X3 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg3));\r
- DEBUG ((DEBUG_INFO, "X4 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg4));\r
- DEBUG ((DEBUG_INFO, "X5 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg5));\r
- DEBUG ((DEBUG_INFO, "X6 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg6));\r
- DEBUG ((DEBUG_INFO, "X7 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg7));\r
-\r
- FfaEnabled = FeaturePcdGet (PcdFfaEnable);\r
- if (FfaEnabled) {\r
- Status = CpuDriverEntryPoint (\r
- EventCompleteSvcArgs->Arg0,\r
- EventCompleteSvcArgs->Arg6,\r
- EventCompleteSvcArgs->Arg3\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "Failed delegated event 0x%x, Status 0x%x\n",\r
- EventCompleteSvcArgs->Arg3, Status));\r
- }\r
- } else {\r
- Status = CpuDriverEntryPoint (\r
- EventCompleteSvcArgs->Arg0,\r
- EventCompleteSvcArgs->Arg3,\r
- EventCompleteSvcArgs->Arg1\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_ERROR, "Failed delegated event 0x%x, Status 0x%x\n",\r
- EventCompleteSvcArgs->Arg0, Status));\r
- }\r
- }\r
-\r
- switch (Status) {\r
- case EFI_SUCCESS:\r
- SvcStatus = ARM_SVC_SPM_RET_SUCCESS;\r
- break;\r
- case EFI_INVALID_PARAMETER:\r
- SvcStatus = ARM_SVC_SPM_RET_INVALID_PARAMS;\r
- break;\r
- case EFI_ACCESS_DENIED:\r
- SvcStatus = ARM_SVC_SPM_RET_DENIED;\r
- break;\r
- case EFI_OUT_OF_RESOURCES:\r
- SvcStatus = ARM_SVC_SPM_RET_NO_MEMORY;\r
- break;\r
- case EFI_UNSUPPORTED:\r
- SvcStatus = ARM_SVC_SPM_RET_NOT_SUPPORTED;\r
- break;\r
- default:\r
- SvcStatus = ARM_SVC_SPM_RET_NOT_SUPPORTED;\r
- break;\r
- }\r
-\r
- if (FfaEnabled) {\r
- EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64;\r
- EventCompleteSvcArgs->Arg1 = 0;\r
- EventCompleteSvcArgs->Arg2 = 0;\r
- EventCompleteSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64;\r
- EventCompleteSvcArgs->Arg4 = SvcStatus;\r
- } else {\r
- EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64;\r
- EventCompleteSvcArgs->Arg1 = SvcStatus;\r
- }\r
- }\r
-}\r
-\r
-/**\r
- Query the SPM version, check compatibility and return success if compatible.\r
-\r
- @retval EFI_SUCCESS SPM versions compatible.\r
- @retval EFI_UNSUPPORTED SPM versions not compatible.\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-GetSpmVersion (VOID)\r
-{\r
- EFI_STATUS Status;\r
- UINT16 CalleeSpmMajorVer;\r
- UINT16 CallerSpmMajorVer;\r
- UINT16 CalleeSpmMinorVer;\r
- UINT16 CallerSpmMinorVer;\r
- UINT32 SpmVersion;\r
- ARM_SVC_ARGS SpmVersionArgs;\r
-\r
- if (FeaturePcdGet (PcdFfaEnable)) {\r
- SpmVersionArgs.Arg0 = ARM_SVC_ID_FFA_VERSION_AARCH32;\r
- SpmVersionArgs.Arg1 = mSpmMajorVerFfa << SPM_MAJOR_VER_SHIFT;\r
- SpmVersionArgs.Arg1 |= mSpmMinorVerFfa;\r
- CallerSpmMajorVer = mSpmMajorVerFfa;\r
- CallerSpmMinorVer = mSpmMinorVerFfa;\r
- } else {\r
- SpmVersionArgs.Arg0 = ARM_SVC_ID_SPM_VERSION_AARCH32;\r
- CallerSpmMajorVer = mSpmMajorVer;\r
- CallerSpmMinorVer = mSpmMinorVer;\r
- }\r
-\r
- ArmCallSvc (&SpmVersionArgs);\r
-\r
- SpmVersion = SpmVersionArgs.Arg0;\r
- if (SpmVersion == FFA_NOT_SUPPORTED) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- CalleeSpmMajorVer = ((SpmVersion & SPM_MAJOR_VER_MASK) >> SPM_MAJOR_VER_SHIFT);\r
- CalleeSpmMinorVer = ((SpmVersion & SPM_MINOR_VER_MASK) >> 0);\r
-\r
- // Different major revision values indicate possibly incompatible functions.\r
- // For two revisions, A and B, for which the major revision values are\r
- // identical, if the minor revision value of revision B is greater than\r
- // the minor revision value of revision A, then every function in\r
- // revision A must work in a compatible way with revision B.\r
- // However, it is possible for revision B to have a higher\r
- // function count than revision A.\r
- if ((CalleeSpmMajorVer == CallerSpmMajorVer) &&\r
- (CalleeSpmMinorVer >= CallerSpmMinorVer))\r
- {\r
- DEBUG ((DEBUG_INFO, "SPM Version: Major=0x%x, Minor=0x%x\n",\r
- CalleeSpmMajorVer, CalleeSpmMinorVer));\r
- Status = EFI_SUCCESS;\r
- }\r
- else\r
- {\r
- DEBUG ((DEBUG_INFO, "Incompatible SPM Versions.\n Callee Version: Major=0x%x, Minor=0x%x.\n Caller: Major=0x%x, Minor>=0x%x.\n",\r
- CalleeSpmMajorVer, CalleeSpmMinorVer, CallerSpmMajorVer, CallerSpmMinorVer));\r
- Status = EFI_UNSUPPORTED;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Initialize parameters to be sent via SVC call.\r
-\r
- @param[out] InitMmFoundationSvcArgs Args structure\r
- @param[out] Ret Return Code\r
-\r
-**/\r
-STATIC\r
-VOID\r
-InitArmSvcArgs (\r
- OUT ARM_SVC_ARGS *InitMmFoundationSvcArgs,\r
- OUT INT32 *Ret\r
- )\r
-{\r
- if (FeaturePcdGet (PcdFfaEnable)) {\r
- InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP_AARCH64;\r
- InitMmFoundationSvcArgs->Arg1 = 0;\r
- InitMmFoundationSvcArgs->Arg2 = 0;\r
- InitMmFoundationSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64;\r
- InitMmFoundationSvcArgs->Arg4 = *Ret;\r
- } else {\r
- InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE_AARCH64;\r
- InitMmFoundationSvcArgs->Arg1 = *Ret;\r
- }\r
-}\r
-\r
-/**\r
- The entry point of Standalone MM Foundation.\r
-\r
- @param [in] SharedBufAddress Pointer to the Buffer between SPM and SP.\r
- @param [in] SharedBufSize Size of the shared buffer.\r
- @param [in] cookie1 Cookie 1\r
- @param [in] cookie2 Cookie 2\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-_ModuleEntryPoint (\r
- IN VOID *SharedBufAddress,\r
- IN UINT64 SharedBufSize,\r
- IN UINT64 cookie1,\r
- IN UINT64 cookie2\r
- )\r
-{\r
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
- EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;\r
- ARM_SVC_ARGS InitMmFoundationSvcArgs;\r
- EFI_STATUS Status;\r
- INT32 Ret;\r
- UINT32 SectionHeaderOffset;\r
- UINT16 NumberOfSections;\r
- VOID *HobStart;\r
- VOID *TeData;\r
- UINTN TeDataSize;\r
- EFI_PHYSICAL_ADDRESS ImageBase;\r
-\r
- // Get Secure Partition Manager Version Information\r
- Status = GetSpmVersion ();\r
- if (EFI_ERROR (Status)) {\r
- goto finish;\r
- }\r
-\r
- PayloadBootInfo = GetAndPrintBootinformation (SharedBufAddress);\r
- if (PayloadBootInfo == NULL) {\r
- Status = EFI_UNSUPPORTED;\r
- goto finish;\r
- }\r
-\r
- // Locate PE/COFF File information for the Standalone MM core module\r
- Status = LocateStandaloneMmCorePeCoffData (\r
- (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PayloadBootInfo->SpImageBase,\r
- &TeData,\r
- &TeDataSize\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto finish;\r
- }\r
-\r
- // Obtain the PE/COFF Section information for the Standalone MM core module\r
- Status = GetStandaloneMmCorePeCoffSections (\r
- TeData,\r
- &ImageContext,\r
- &ImageBase,\r
- &SectionHeaderOffset,\r
- &NumberOfSections\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto finish;\r
- }\r
-\r
- //\r
- // ImageBase may deviate from ImageContext.ImageAddress if we are dealing\r
- // with a TE image, in which case the latter points to the actual offset\r
- // of the image, whereas ImageBase refers to the address where the image\r
- // would start if the stripped PE headers were still in place. In either\r
- // case, we need to fix up ImageBase so it refers to the actual current\r
- // load address.\r
- //\r
- ImageBase += (UINTN)TeData - ImageContext.ImageAddress;\r
-\r
- // Update the memory access permissions of individual sections in the\r
- // Standalone MM core module\r
- Status = UpdateMmFoundationPeCoffPermissions (\r
- &ImageContext,\r
- ImageBase,\r
- SectionHeaderOffset,\r
- NumberOfSections,\r
- ArmSetMemoryRegionNoExec,\r
- ArmSetMemoryRegionReadOnly,\r
- ArmClearMemoryRegionReadOnly\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto finish;\r
- }\r
-\r
- if (ImageContext.ImageAddress != (UINTN)TeData) {\r
- ImageContext.ImageAddress = (UINTN)TeData;\r
- ArmSetMemoryRegionNoExec (ImageBase, SIZE_4KB);\r
- ArmClearMemoryRegionReadOnly (ImageBase, SIZE_4KB);\r
-\r
- Status = PeCoffLoaderRelocateImage (&ImageContext);\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-\r
- //\r
- // Create Hoblist based upon boot information passed by privileged software\r
- //\r
- HobStart = CreateHobListFromBootInfo (&CpuDriverEntryPoint, PayloadBootInfo);\r
-\r
- //\r
- // Call the MM Core entry point\r
- //\r
- ProcessModuleEntryPointList (HobStart);\r
-\r
- DEBUG ((DEBUG_INFO, "Shared Cpu Driver EP 0x%lx\n", (UINT64) CpuDriverEntryPoint));\r
-\r
-finish:\r
- if (Status == RETURN_UNSUPPORTED) {\r
- Ret = -1;\r
- } else if (Status == RETURN_INVALID_PARAMETER) {\r
- Ret = -2;\r
- } else if (Status == EFI_NOT_FOUND) {\r
- Ret = -7;\r
- } else {\r
- Ret = 0;\r
- }\r
- ZeroMem (&InitMmFoundationSvcArgs, sizeof(InitMmFoundationSvcArgs));\r
- InitArmSvcArgs (&InitMmFoundationSvcArgs, &Ret);\r
- DelegatedEventLoop (&InitMmFoundationSvcArgs);\r
-}\r
--- /dev/null
+/** @file\r
+ Creates HOB during Standalone MM Foundation entry point\r
+ on ARM platforms.\r
+\r
+Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+\r
+#include <PiMm.h>\r
+\r
+#include <PiPei.h>\r
+#include <Guid/MmramMemoryReserve.h>\r
+#include <Guid/MpInformation.h>\r
+\r
+#include <Library/Arm/StandaloneMmCoreEntryPoint.h>\r
+#include <Library/ArmMmuLib.h>\r
+#include <Library/ArmSvcLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/SerialPortLib.h>\r
+\r
+#include <IndustryStandard/ArmStdSmc.h>\r
+\r
+extern EFI_HOB_HANDOFF_INFO_TABLE*\r
+HobConstructor (\r
+ IN VOID *EfiMemoryBegin,\r
+ IN UINTN EfiMemoryLength,\r
+ IN VOID *EfiFreeMemoryBottom,\r
+ IN VOID *EfiFreeMemoryTop\r
+ );\r
+\r
+// GUID to identify HOB with whereabouts of communication buffer with Normal\r
+// World\r
+extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;\r
+\r
+// GUID to identify HOB where the entry point of the CPU driver will be\r
+// populated to allow this entry point driver to invoke it upon receipt of an\r
+// event\r
+extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;\r
+\r
+/**\r
+ Use the boot information passed by privileged firmware to populate a HOB list\r
+ suitable for consumption by the MM Core and drivers.\r
+\r
+ @param [in, out] CpuDriverEntryPoint Address of MM CPU driver entrypoint\r
+ @param [in] PayloadBootInfo Boot information passed by privileged\r
+ firmware\r
+\r
+**/\r
+VOID *\r
+CreateHobListFromBootInfo (\r
+ IN OUT PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT *CpuDriverEntryPoint,\r
+ IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo\r
+)\r
+{\r
+ EFI_HOB_HANDOFF_INFO_TABLE *HobStart;\r
+ EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;\r
+ UINT32 Index;\r
+ UINT32 BufferSize;\r
+ UINT32 Flags;\r
+ EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHob;\r
+ EFI_MMRAM_DESCRIPTOR *MmramRanges;\r
+ EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;\r
+ MP_INFORMATION_HOB_DATA *MpInformationHobData;\r
+ EFI_PROCESSOR_INFORMATION *ProcInfoBuffer;\r
+ EFI_SECURE_PARTITION_CPU_INFO *CpuInfo;\r
+ ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;\r
+\r
+ // Create a hoblist with a PHIT and EOH\r
+ HobStart = HobConstructor (\r
+ (VOID *) (UINTN) PayloadBootInfo->SpMemBase,\r
+ (UINTN) PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase,\r
+ (VOID *) (UINTN) PayloadBootInfo->SpHeapBase,\r
+ (VOID *) (UINTN) (PayloadBootInfo->SpHeapBase + PayloadBootInfo->SpHeapSize)\r
+ );\r
+\r
+ // Check that the Hoblist starts at the bottom of the Heap\r
+ ASSERT (HobStart == (VOID *) (UINTN) PayloadBootInfo->SpHeapBase);\r
+\r
+ // Build a Boot Firmware Volume HOB\r
+ BuildFvHob (PayloadBootInfo->SpImageBase, PayloadBootInfo->SpImageSize);\r
+\r
+ // Build a resource descriptor Hob that describes the available physical\r
+ // memory range\r
+ Attributes = (\r
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+ EFI_RESOURCE_ATTRIBUTE_TESTED |\r
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+ );\r
+\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_SYSTEM_MEMORY,\r
+ Attributes,\r
+ (UINTN) PayloadBootInfo->SpMemBase,\r
+ PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase\r
+ );\r
+\r
+ // Find the size of the GUIDed HOB with MP information\r
+ BufferSize = sizeof (MP_INFORMATION_HOB_DATA);\r
+ BufferSize += sizeof (EFI_PROCESSOR_INFORMATION) * PayloadBootInfo->NumCpus;\r
+\r
+ // Create a Guided MP information HOB to enable the ARM TF CPU driver to\r
+ // perform per-cpu allocations.\r
+ MpInformationHobData = BuildGuidHob (&gMpInformationHobGuid, BufferSize);\r
+\r
+ // Populate the MP information HOB with the topology information passed by\r
+ // privileged firmware\r
+ MpInformationHobData->NumberOfProcessors = PayloadBootInfo->NumCpus;\r
+ MpInformationHobData->NumberOfEnabledProcessors = PayloadBootInfo->NumCpus;\r
+ ProcInfoBuffer = MpInformationHobData->ProcessorInfoBuffer;\r
+ CpuInfo = PayloadBootInfo->CpuInfo;\r
+\r
+ for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {\r
+ ProcInfoBuffer[Index].ProcessorId = CpuInfo[Index].Mpidr;\r
+ ProcInfoBuffer[Index].Location.Package = GET_CLUSTER_ID(CpuInfo[Index].Mpidr);\r
+ ProcInfoBuffer[Index].Location.Core = GET_CORE_ID(CpuInfo[Index].Mpidr);\r
+ ProcInfoBuffer[Index].Location.Thread = GET_CORE_ID(CpuInfo[Index].Mpidr);\r
+\r
+ Flags = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;\r
+ if (CpuInfo[Index].Flags & CPU_INFO_FLAG_PRIMARY_CPU) {\r
+ Flags |= PROCESSOR_AS_BSP_BIT;\r
+ }\r
+ ProcInfoBuffer[Index].StatusFlag = Flags;\r
+ }\r
+\r
+ // Create a Guided HOB to tell the ARM TF CPU driver the location and length\r
+ // of the communication buffer shared with the Normal world.\r
+ NsCommBufMmramRange = (EFI_MMRAM_DESCRIPTOR *) BuildGuidHob (\r
+ &gEfiStandaloneMmNonSecureBufferGuid,\r
+ sizeof (EFI_MMRAM_DESCRIPTOR)\r
+ );\r
+ NsCommBufMmramRange->PhysicalStart = PayloadBootInfo->SpNsCommBufBase;\r
+ NsCommBufMmramRange->CpuStart = PayloadBootInfo->SpNsCommBufBase;\r
+ NsCommBufMmramRange->PhysicalSize = PayloadBootInfo->SpNsCommBufSize;\r
+ NsCommBufMmramRange->RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+ // Create a Guided HOB to enable the ARM TF CPU driver to share its entry\r
+ // point and populate it with the address of the shared buffer\r
+ CpuDriverEntryPointDesc = (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *) BuildGuidHob (\r
+ &gEfiArmTfCpuDriverEpDescriptorGuid,\r
+ sizeof (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR)\r
+ );\r
+\r
+ *CpuDriverEntryPoint = NULL;\r
+ CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr = CpuDriverEntryPoint;\r
+\r
+ // Find the size of the GUIDed HOB with SRAM ranges\r
+ BufferSize = sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK);\r
+ BufferSize += PayloadBootInfo->NumSpMemRegions * sizeof (EFI_MMRAM_DESCRIPTOR);\r
+\r
+ // Create a GUIDed HOB with SRAM ranges\r
+ MmramRangesHob = BuildGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, BufferSize);\r
+\r
+ // Fill up the number of MMRAM memory regions\r
+ MmramRangesHob->NumberOfMmReservedRegions = PayloadBootInfo->NumSpMemRegions;\r
+ // Fill up the MMRAM ranges\r
+ MmramRanges = &MmramRangesHob->Descriptor[0];\r
+\r
+ // Base and size of memory occupied by the Standalone MM image\r
+ MmramRanges[0].PhysicalStart = PayloadBootInfo->SpImageBase;\r
+ MmramRanges[0].CpuStart = PayloadBootInfo->SpImageBase;\r
+ MmramRanges[0].PhysicalSize = PayloadBootInfo->SpImageSize;\r
+ MmramRanges[0].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+ // Base and size of buffer shared with privileged Secure world software\r
+ MmramRanges[1].PhysicalStart = PayloadBootInfo->SpSharedBufBase;\r
+ MmramRanges[1].CpuStart = PayloadBootInfo->SpSharedBufBase;\r
+ MmramRanges[1].PhysicalSize = PayloadBootInfo->SpPcpuSharedBufSize * PayloadBootInfo->NumCpus;\r
+ MmramRanges[1].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+ // Base and size of buffer used for synchronous communication with Normal\r
+ // world software\r
+ MmramRanges[2].PhysicalStart = PayloadBootInfo->SpNsCommBufBase;\r
+ MmramRanges[2].CpuStart = PayloadBootInfo->SpNsCommBufBase;\r
+ MmramRanges[2].PhysicalSize = PayloadBootInfo->SpNsCommBufSize;\r
+ MmramRanges[2].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+ // Base and size of memory allocated for stacks for all cpus\r
+ MmramRanges[3].PhysicalStart = PayloadBootInfo->SpStackBase;\r
+ MmramRanges[3].CpuStart = PayloadBootInfo->SpStackBase;\r
+ MmramRanges[3].PhysicalSize = PayloadBootInfo->SpPcpuStackSize * PayloadBootInfo->NumCpus;\r
+ MmramRanges[3].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+ // Base and size of heap memory shared by all cpus\r
+ MmramRanges[4].PhysicalStart = (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;\r
+ MmramRanges[4].CpuStart = (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;\r
+ MmramRanges[4].PhysicalSize = HobStart->EfiFreeMemoryBottom - (EFI_PHYSICAL_ADDRESS) (UINTN) HobStart;\r
+ MmramRanges[4].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;\r
+\r
+ // Base and size of heap memory shared by all cpus\r
+ MmramRanges[5].PhysicalStart = HobStart->EfiFreeMemoryBottom;\r
+ MmramRanges[5].CpuStart = HobStart->EfiFreeMemoryBottom;\r
+ MmramRanges[5].PhysicalSize = HobStart->EfiFreeMemoryTop - HobStart->EfiFreeMemoryBottom;\r
+ MmramRanges[5].RegionState = EFI_CACHEABLE;\r
+\r
+ return HobStart;\r
+}\r
--- /dev/null
+/** @file\r
+ Locate, get and update PE/COFF permissions during Standalone MM\r
+ Foundation Entry point on ARM platforms.\r
+\r
+Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+\r
+#include <PiMm.h>\r
+\r
+#include <PiPei.h>\r
+#include <Guid/MmramMemoryReserve.h>\r
+#include <Guid/MpInformation.h>\r
+\r
+#include <Library/Arm/StandaloneMmCoreEntryPoint.h>\r
+#include <Library/ArmMmuLib.h>\r
+#include <Library/ArmSvcLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/SerialPortLib.h>\r
+\r
+#include <IndustryStandard/ArmStdSmc.h>\r
+\r
+/**\r
+ Privileged firmware assigns RO & Executable attributes to all memory occupied\r
+ by the Boot Firmware Volume. This function sets the correct permissions of\r
+ sections in the Standalone MM Core module to be able to access RO and RW data\r
+ and make further progress in the boot process.\r
+\r
+ @param [in] ImageContext Pointer to PE/COFF image context\r
+ @param [in] ImageBase Base of image in memory\r
+ @param [in] SectionHeaderOffset Offset of PE/COFF image section header\r
+ @param [in] NumberOfSections Number of Sections\r
+ @param [in] TextUpdater Function to change code permissions\r
+ @param [in] ReadOnlyUpdater Function to change RO permissions\r
+ @param [in] ReadWriteUpdater Function to change RW permissions\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UpdateMmFoundationPeCoffPermissions (\r
+ IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ IN EFI_PHYSICAL_ADDRESS ImageBase,\r
+ IN UINT32 SectionHeaderOffset,\r
+ IN CONST UINT16 NumberOfSections,\r
+ IN REGION_PERMISSION_UPDATE_FUNC TextUpdater,\r
+ IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater,\r
+ IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater\r
+ )\r
+{\r
+ EFI_IMAGE_SECTION_HEADER SectionHeader;\r
+ RETURN_STATUS Status;\r
+ EFI_PHYSICAL_ADDRESS Base;\r
+ UINTN Size;\r
+ UINTN ReadSize;\r
+ UINTN Index;\r
+\r
+ ASSERT (ImageContext != NULL);\r
+\r
+ //\r
+ // Iterate over the sections\r
+ //\r
+ for (Index = 0; Index < NumberOfSections; Index++) {\r
+ //\r
+ // Read section header from file\r
+ //\r
+ Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ ReadSize = Size;\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ SectionHeaderOffset,\r
+ &Size,\r
+ &SectionHeader\r
+ );\r
+\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+ DEBUG ((DEBUG_ERROR,\r
+ "%a: ImageContext->ImageRead () failed (Status = %r)\n",\r
+ __FUNCTION__, Status));\r
+ return Status;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ "%a: Section %d of image at 0x%lx has 0x%x permissions\n",\r
+ __FUNCTION__, Index, ImageContext->ImageAddress, SectionHeader.Characteristics));\r
+ DEBUG ((DEBUG_INFO,\r
+ "%a: Section %d of image at 0x%lx has %a name\n",\r
+ __FUNCTION__, Index, ImageContext->ImageAddress, SectionHeader.Name));\r
+ DEBUG ((DEBUG_INFO,\r
+ "%a: Section %d of image at 0x%lx has 0x%x address\n",\r
+ __FUNCTION__, Index, ImageContext->ImageAddress,\r
+ ImageContext->ImageAddress + SectionHeader.VirtualAddress));\r
+ DEBUG ((DEBUG_INFO,\r
+ "%a: Section %d of image at 0x%lx has 0x%x data\n",\r
+ __FUNCTION__, Index, ImageContext->ImageAddress, SectionHeader.PointerToRawData));\r
+\r
+ //\r
+ // If the section is marked as XN then remove the X attribute. Furthermore,\r
+ // if it is a writeable section then mark it appropriately as well.\r
+ //\r
+ if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) {\r
+ Base = ImageBase + SectionHeader.VirtualAddress;\r
+\r
+ TextUpdater (Base, SectionHeader.Misc.VirtualSize);\r
+\r
+ if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_WRITE) != 0) {\r
+ ReadWriteUpdater (Base, SectionHeader.Misc.VirtualSize);\r
+ DEBUG ((DEBUG_INFO,\r
+ "%a: Mapping section %d of image at 0x%lx with RW-XN permissions\n",\r
+ __FUNCTION__, Index, ImageContext->ImageAddress));\r
+ } else {\r
+ DEBUG ((DEBUG_INFO,\r
+ "%a: Mapping section %d of image at 0x%lx with RO-XN permissions\n",\r
+ __FUNCTION__, Index, ImageContext->ImageAddress));\r
+ }\r
+ } else {\r
+ DEBUG ((DEBUG_INFO,\r
+ "%a: Ignoring section %d of image at 0x%lx with 0x%x permissions\n",\r
+ __FUNCTION__, Index, ImageContext->ImageAddress, SectionHeader.Characteristics));\r
+ }\r
+ SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Privileged firmware assigns RO & Executable attributes to all memory occupied\r
+ by the Boot Firmware Volume. This function locates the Standalone MM Core\r
+ module PE/COFF image in the BFV and returns this information.\r
+\r
+ @param [in] BfvAddress Base Address of Boot Firmware Volume\r
+ @param [in, out] TeData Pointer to address for allocating memory\r
+ for PE/COFF image data\r
+ @param [in, out] TeDataSize Pointer to size of PE/COFF image data\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LocateStandaloneMmCorePeCoffData (\r
+ IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress,\r
+ IN OUT VOID **TeData,\r
+ IN OUT UINTN *TeDataSize\r
+ )\r
+{\r
+ EFI_FFS_FILE_HEADER *FileHeader;\r
+ EFI_STATUS Status;\r
+\r
+ FileHeader = NULL;\r
+ Status = FfsFindNextFile (\r
+ EFI_FV_FILETYPE_SECURITY_CORE,\r
+ BfvAddress,\r
+ &FileHeader\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM FFS file - 0x%x\n",\r
+ Status));\r
+ return Status;\r
+ }\r
+\r
+ Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, TeData, TeDataSize);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, TeData, TeDataSize);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Section data - %r\n",\r
+ Status));\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", *TeData));\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Returns the PC COFF section information.\r
+\r
+ @param [in, out] ImageContext Pointer to PE/COFF image context\r
+ @param [out] ImageBase Base of image in memory\r
+ @param [out] SectionHeaderOffset Offset of PE/COFF image section header\r
+ @param [out] NumberOfSections Number of Sections\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GetPeCoffSectionInformation (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ OUT EFI_PHYSICAL_ADDRESS *ImageBase,\r
+ OUT UINT32 *SectionHeaderOffset,\r
+ OUT UINT16 *NumberOfSections\r
+ )\r
+{\r
+ RETURN_STATUS Status;\r
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;\r
+ UINTN Size;\r
+ UINTN ReadSize;\r
+\r
+ ASSERT (ImageContext != NULL);\r
+ ASSERT (SectionHeaderOffset != NULL);\r
+ ASSERT (NumberOfSections != NULL);\r
+\r
+ Status = PeCoffLoaderGetImageInfo (ImageContext);\r
+ if (RETURN_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR,\r
+ "%a: PeCoffLoaderGetImageInfo () failed (Status == %r)\n",\r
+ __FUNCTION__, Status));\r
+ return Status;\r
+ }\r
+\r
+ if (ImageContext->SectionAlignment < EFI_PAGE_SIZE) {\r
+ //\r
+ // The sections need to be at least 4 KB aligned, since that is the\r
+ // granularity at which we can tighten permissions.\r
+ //\r
+ if (!ImageContext->IsTeImage) {\r
+ DEBUG ((DEBUG_WARN,\r
+ "%a: non-TE Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n",\r
+ __FUNCTION__, ImageContext->ImageAddress, ImageContext->SectionAlignment));\r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+ ImageContext->SectionAlignment = EFI_PAGE_SIZE;\r
+ }\r
+\r
+ //\r
+ // Read the PE/COFF Header. For PE32 (32-bit) this will read in too much\r
+ // data, but that should not hurt anything. Hdr.Pe32->OptionalHeader.Magic\r
+ // determines if this is a PE32 or PE32+ image. The magic is in the same\r
+ // location in both images.\r
+ //\r
+ Hdr.Union = &HdrData;\r
+ Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);\r
+ ReadSize = Size;\r
+ Status = ImageContext->ImageRead (\r
+ ImageContext->Handle,\r
+ ImageContext->PeCoffHeaderOffset,\r
+ &Size,\r
+ Hdr.Pe32\r
+ );\r
+\r
+ if (RETURN_ERROR (Status) || (Size != ReadSize)) {\r
+ DEBUG ((DEBUG_ERROR,\r
+ "%a: TmpContext->ImageRead () failed (Status = %r)\n",\r
+ __FUNCTION__, Status));\r
+ return Status;\r
+ }\r
+\r
+ *ImageBase = ImageContext->ImageAddress;\r
+ if (!ImageContext->IsTeImage) {\r
+ ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE);\r
+\r
+ *SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) +\r
+ sizeof (EFI_IMAGE_FILE_HEADER);\r
+ *NumberOfSections = Hdr.Pe32->FileHeader.NumberOfSections;\r
+\r
+ switch (Hdr.Pe32->OptionalHeader.Magic) {\r
+ case EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC:\r
+ *SectionHeaderOffset += Hdr.Pe32->FileHeader.SizeOfOptionalHeader;\r
+ break;\r
+ case EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC:\r
+ *SectionHeaderOffset += Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader;\r
+ break;\r
+ default:\r
+ ASSERT (FALSE);\r
+ }\r
+ } else {\r
+ *SectionHeaderOffset = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER));\r
+ *NumberOfSections = Hdr.Te->NumberOfSections;\r
+ *ImageBase -= (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);\r
+ }\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+ Privileged firmware assigns RO & Executable attributes to all memory occupied\r
+ by the Boot Firmware Volume. This function locates the section information of\r
+ the Standalone MM Core module to be able to change permissions of the\r
+ individual sections later in the boot process.\r
+\r
+ @param [in] TeData Pointer to PE/COFF image data\r
+ @param [in, out] ImageContext Pointer to PE/COFF image context\r
+ @param [out] ImageBase Pointer to ImageBase variable\r
+ @param [in, out] SectionHeaderOffset Offset of PE/COFF image section header\r
+ @param [in, out] NumberOfSections Number of Sections\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetStandaloneMmCorePeCoffSections (\r
+ IN VOID *TeData,\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ OUT EFI_PHYSICAL_ADDRESS *ImageBase,\r
+ IN OUT UINT32 *SectionHeaderOffset,\r
+ IN OUT UINT16 *NumberOfSections\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ // Initialize the Image Context\r
+ ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));\r
+ ImageContext->Handle = TeData;\r
+ ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory;\r
+\r
+ DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData));\r
+\r
+ Status = GetPeCoffSectionInformation (ImageContext, ImageBase,\r
+ SectionHeaderOffset, NumberOfSections);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status));\r
+ return Status;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "Standalone MM Core PE-COFF SectionHeaderOffset - 0x%x, NumberOfSections - %d\n",\r
+ *SectionHeaderOffset, *NumberOfSections));\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+/** @file\r
+ Entry point to the Standalone MM Foundation when initialized during the SEC\r
+ phase on ARM platforms\r
+\r
+Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+\r
+#include <PiMm.h>\r
+\r
+#include <Library/Arm/StandaloneMmCoreEntryPoint.h>\r
+\r
+#include <PiPei.h>\r
+#include <Guid/MmramMemoryReserve.h>\r
+#include <Guid/MpInformation.h>\r
+\r
+#include <Library/ArmMmuLib.h>\r
+#include <Library/ArmSvcLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#include <IndustryStandard/ArmStdSmc.h>\r
+#include <IndustryStandard/ArmMmSvc.h>\r
+#include <IndustryStandard/ArmFfaSvc.h>\r
+\r
+#define SPM_MAJOR_VER_MASK 0xFFFF0000\r
+#define SPM_MINOR_VER_MASK 0x0000FFFF\r
+#define SPM_MAJOR_VER_SHIFT 16\r
+#define FFA_NOT_SUPPORTED -1\r
+\r
+STATIC CONST UINT32 mSpmMajorVer = SPM_MAJOR_VERSION;\r
+STATIC CONST UINT32 mSpmMinorVer = SPM_MINOR_VERSION;\r
+\r
+STATIC CONST UINT32 mSpmMajorVerFfa = SPM_MAJOR_VERSION_FFA;\r
+STATIC CONST UINT32 mSpmMinorVerFfa = SPM_MINOR_VERSION_FFA;\r
+\r
+#define BOOT_PAYLOAD_VERSION 1\r
+\r
+PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint = NULL;\r
+\r
+/**\r
+ Retrieve a pointer to and print the boot information passed by privileged\r
+ secure firmware.\r
+\r
+ @param [in] SharedBufAddress The pointer memory shared with privileged\r
+ firmware.\r
+\r
+**/\r
+EFI_SECURE_PARTITION_BOOT_INFO *\r
+GetAndPrintBootinformation (\r
+ IN VOID *SharedBufAddress\r
+)\r
+{\r
+ EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;\r
+ EFI_SECURE_PARTITION_CPU_INFO *PayloadCpuInfo;\r
+ UINTN Index;\r
+\r
+ PayloadBootInfo = (EFI_SECURE_PARTITION_BOOT_INFO *) SharedBufAddress;\r
+\r
+ if (PayloadBootInfo == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "PayloadBootInfo NULL\n"));\r
+ return NULL;\r
+ }\r
+\r
+ if (PayloadBootInfo->Header.Version != BOOT_PAYLOAD_VERSION) {\r
+ DEBUG ((DEBUG_ERROR, "Boot Information Version Mismatch. Current=0x%x, Expected=0x%x.\n",\r
+ PayloadBootInfo->Header.Version, BOOT_PAYLOAD_VERSION));\r
+ return NULL;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "NumSpMemRegions - 0x%x\n", PayloadBootInfo->NumSpMemRegions));\r
+ DEBUG ((DEBUG_INFO, "SpMemBase - 0x%lx\n", PayloadBootInfo->SpMemBase));\r
+ DEBUG ((DEBUG_INFO, "SpMemLimit - 0x%lx\n", PayloadBootInfo->SpMemLimit));\r
+ DEBUG ((DEBUG_INFO, "SpImageBase - 0x%lx\n", PayloadBootInfo->SpImageBase));\r
+ DEBUG ((DEBUG_INFO, "SpStackBase - 0x%lx\n", PayloadBootInfo->SpStackBase));\r
+ DEBUG ((DEBUG_INFO, "SpHeapBase - 0x%lx\n", PayloadBootInfo->SpHeapBase));\r
+ DEBUG ((DEBUG_INFO, "SpNsCommBufBase - 0x%lx\n", PayloadBootInfo->SpNsCommBufBase));\r
+ DEBUG ((DEBUG_INFO, "SpSharedBufBase - 0x%lx\n", PayloadBootInfo->SpSharedBufBase));\r
+\r
+ DEBUG ((DEBUG_INFO, "SpImageSize - 0x%x\n", PayloadBootInfo->SpImageSize));\r
+ DEBUG ((DEBUG_INFO, "SpPcpuStackSize - 0x%x\n", PayloadBootInfo->SpPcpuStackSize));\r
+ DEBUG ((DEBUG_INFO, "SpHeapSize - 0x%x\n", PayloadBootInfo->SpHeapSize));\r
+ DEBUG ((DEBUG_INFO, "SpNsCommBufSize - 0x%x\n", PayloadBootInfo->SpNsCommBufSize));\r
+ DEBUG ((DEBUG_INFO, "SpPcpuSharedBufSize - 0x%x\n", PayloadBootInfo->SpPcpuSharedBufSize));\r
+\r
+ DEBUG ((DEBUG_INFO, "NumCpus - 0x%x\n", PayloadBootInfo->NumCpus));\r
+ DEBUG ((DEBUG_INFO, "CpuInfo - 0x%p\n", PayloadBootInfo->CpuInfo));\r
+\r
+ PayloadCpuInfo = (EFI_SECURE_PARTITION_CPU_INFO *) PayloadBootInfo->CpuInfo;\r
+\r
+ if (PayloadCpuInfo == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "PayloadCpuInfo NULL\n"));\r
+ return NULL;\r
+ }\r
+\r
+ for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {\r
+ DEBUG ((DEBUG_INFO, "Mpidr - 0x%lx\n", PayloadCpuInfo[Index].Mpidr));\r
+ DEBUG ((DEBUG_INFO, "LinearId - 0x%x\n", PayloadCpuInfo[Index].LinearId));\r
+ DEBUG ((DEBUG_INFO, "Flags - 0x%x\n", PayloadCpuInfo[Index].Flags));\r
+ }\r
+\r
+ return PayloadBootInfo;\r
+}\r
+\r
+/**\r
+ A loop to delegated events.\r
+\r
+ @param [in] EventCompleteSvcArgs Pointer to the event completion arguments.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DelegatedEventLoop (\r
+ IN ARM_SVC_ARGS *EventCompleteSvcArgs\r
+ )\r
+{\r
+ BOOLEAN FfaEnabled;\r
+ EFI_STATUS Status;\r
+ UINTN SvcStatus;\r
+\r
+ while (TRUE) {\r
+ ArmCallSvc (EventCompleteSvcArgs);\r
+\r
+ DEBUG ((DEBUG_INFO, "Received delegated event\n"));\r
+ DEBUG ((DEBUG_INFO, "X0 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg0));\r
+ DEBUG ((DEBUG_INFO, "X1 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg1));\r
+ DEBUG ((DEBUG_INFO, "X2 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg2));\r
+ DEBUG ((DEBUG_INFO, "X3 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg3));\r
+ DEBUG ((DEBUG_INFO, "X4 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg4));\r
+ DEBUG ((DEBUG_INFO, "X5 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg5));\r
+ DEBUG ((DEBUG_INFO, "X6 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg6));\r
+ DEBUG ((DEBUG_INFO, "X7 : 0x%x\n", (UINT32) EventCompleteSvcArgs->Arg7));\r
+\r
+ FfaEnabled = FeaturePcdGet (PcdFfaEnable);\r
+ if (FfaEnabled) {\r
+ Status = CpuDriverEntryPoint (\r
+ EventCompleteSvcArgs->Arg0,\r
+ EventCompleteSvcArgs->Arg6,\r
+ EventCompleteSvcArgs->Arg3\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed delegated event 0x%x, Status 0x%x\n",\r
+ EventCompleteSvcArgs->Arg3, Status));\r
+ }\r
+ } else {\r
+ Status = CpuDriverEntryPoint (\r
+ EventCompleteSvcArgs->Arg0,\r
+ EventCompleteSvcArgs->Arg3,\r
+ EventCompleteSvcArgs->Arg1\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "Failed delegated event 0x%x, Status 0x%x\n",\r
+ EventCompleteSvcArgs->Arg0, Status));\r
+ }\r
+ }\r
+\r
+ switch (Status) {\r
+ case EFI_SUCCESS:\r
+ SvcStatus = ARM_SVC_SPM_RET_SUCCESS;\r
+ break;\r
+ case EFI_INVALID_PARAMETER:\r
+ SvcStatus = ARM_SVC_SPM_RET_INVALID_PARAMS;\r
+ break;\r
+ case EFI_ACCESS_DENIED:\r
+ SvcStatus = ARM_SVC_SPM_RET_DENIED;\r
+ break;\r
+ case EFI_OUT_OF_RESOURCES:\r
+ SvcStatus = ARM_SVC_SPM_RET_NO_MEMORY;\r
+ break;\r
+ case EFI_UNSUPPORTED:\r
+ SvcStatus = ARM_SVC_SPM_RET_NOT_SUPPORTED;\r
+ break;\r
+ default:\r
+ SvcStatus = ARM_SVC_SPM_RET_NOT_SUPPORTED;\r
+ break;\r
+ }\r
+\r
+ if (FfaEnabled) {\r
+ EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;\r
+ EventCompleteSvcArgs->Arg1 = 0;\r
+ EventCompleteSvcArgs->Arg2 = 0;\r
+ EventCompleteSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
+ EventCompleteSvcArgs->Arg4 = SvcStatus;\r
+ } else {\r
+ EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
+ EventCompleteSvcArgs->Arg1 = SvcStatus;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Query the SPM version, check compatibility and return success if compatible.\r
+\r
+ @retval EFI_SUCCESS SPM versions compatible.\r
+ @retval EFI_UNSUPPORTED SPM versions not compatible.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GetSpmVersion (VOID)\r
+{\r
+ EFI_STATUS Status;\r
+ UINT16 CalleeSpmMajorVer;\r
+ UINT16 CallerSpmMajorVer;\r
+ UINT16 CalleeSpmMinorVer;\r
+ UINT16 CallerSpmMinorVer;\r
+ UINT32 SpmVersion;\r
+ ARM_SVC_ARGS SpmVersionArgs;\r
+\r
+ if (FeaturePcdGet (PcdFfaEnable)) {\r
+ SpmVersionArgs.Arg0 = ARM_SVC_ID_FFA_VERSION_AARCH32;\r
+ SpmVersionArgs.Arg1 = mSpmMajorVerFfa << SPM_MAJOR_VER_SHIFT;\r
+ SpmVersionArgs.Arg1 |= mSpmMinorVerFfa;\r
+ CallerSpmMajorVer = mSpmMajorVerFfa;\r
+ CallerSpmMinorVer = mSpmMinorVerFfa;\r
+ } else {\r
+ SpmVersionArgs.Arg0 = ARM_SVC_ID_SPM_VERSION_AARCH32;\r
+ CallerSpmMajorVer = mSpmMajorVer;\r
+ CallerSpmMinorVer = mSpmMinorVer;\r
+ }\r
+\r
+ ArmCallSvc (&SpmVersionArgs);\r
+\r
+ SpmVersion = SpmVersionArgs.Arg0;\r
+ if (SpmVersion == FFA_NOT_SUPPORTED) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ CalleeSpmMajorVer = ((SpmVersion & SPM_MAJOR_VER_MASK) >> SPM_MAJOR_VER_SHIFT);\r
+ CalleeSpmMinorVer = ((SpmVersion & SPM_MINOR_VER_MASK) >> 0);\r
+\r
+ // Different major revision values indicate possibly incompatible functions.\r
+ // For two revisions, A and B, for which the major revision values are\r
+ // identical, if the minor revision value of revision B is greater than\r
+ // the minor revision value of revision A, then every function in\r
+ // revision A must work in a compatible way with revision B.\r
+ // However, it is possible for revision B to have a higher\r
+ // function count than revision A.\r
+ if ((CalleeSpmMajorVer == CallerSpmMajorVer) &&\r
+ (CalleeSpmMinorVer >= CallerSpmMinorVer))\r
+ {\r
+ DEBUG ((DEBUG_INFO, "SPM Version: Major=0x%x, Minor=0x%x\n",\r
+ CalleeSpmMajorVer, CalleeSpmMinorVer));\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ else\r
+ {\r
+ DEBUG ((DEBUG_INFO, "Incompatible SPM Versions.\n Callee Version: Major=0x%x, Minor=0x%x.\n Caller: Major=0x%x, Minor>=0x%x.\n",\r
+ CalleeSpmMajorVer, CalleeSpmMinorVer, CallerSpmMajorVer, CallerSpmMinorVer));\r
+ Status = EFI_UNSUPPORTED;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Initialize parameters to be sent via SVC call.\r
+\r
+ @param[out] InitMmFoundationSvcArgs Args structure\r
+ @param[out] Ret Return Code\r
+\r
+**/\r
+STATIC\r
+VOID\r
+InitArmSvcArgs (\r
+ OUT ARM_SVC_ARGS *InitMmFoundationSvcArgs,\r
+ OUT INT32 *Ret\r
+ )\r
+{\r
+ if (FeaturePcdGet (PcdFfaEnable)) {\r
+ InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;\r
+ InitMmFoundationSvcArgs->Arg1 = 0;\r
+ InitMmFoundationSvcArgs->Arg2 = 0;\r
+ InitMmFoundationSvcArgs->Arg3 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
+ InitMmFoundationSvcArgs->Arg4 = *Ret;\r
+ } else {\r
+ InitMmFoundationSvcArgs->Arg0 = ARM_SVC_ID_SP_EVENT_COMPLETE;\r
+ InitMmFoundationSvcArgs->Arg1 = *Ret;\r
+ }\r
+}\r
+\r
+/**\r
+ The entry point of Standalone MM Foundation.\r
+\r
+ @param [in] SharedBufAddress Pointer to the Buffer between SPM and SP.\r
+ @param [in] SharedBufSize Size of the shared buffer.\r
+ @param [in] cookie1 Cookie 1\r
+ @param [in] cookie2 Cookie 2\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+_ModuleEntryPoint (\r
+ IN VOID *SharedBufAddress,\r
+ IN UINT64 SharedBufSize,\r
+ IN UINT64 cookie1,\r
+ IN UINT64 cookie2\r
+ )\r
+{\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;\r
+ ARM_SVC_ARGS InitMmFoundationSvcArgs;\r
+ EFI_STATUS Status;\r
+ INT32 Ret;\r
+ UINT32 SectionHeaderOffset;\r
+ UINT16 NumberOfSections;\r
+ VOID *HobStart;\r
+ VOID *TeData;\r
+ UINTN TeDataSize;\r
+ EFI_PHYSICAL_ADDRESS ImageBase;\r
+\r
+ // Get Secure Partition Manager Version Information\r
+ Status = GetSpmVersion ();\r
+ if (EFI_ERROR (Status)) {\r
+ goto finish;\r
+ }\r
+\r
+ PayloadBootInfo = GetAndPrintBootinformation (SharedBufAddress);\r
+ if (PayloadBootInfo == NULL) {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto finish;\r
+ }\r
+\r
+ // Locate PE/COFF File information for the Standalone MM core module\r
+ Status = LocateStandaloneMmCorePeCoffData (\r
+ (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PayloadBootInfo->SpImageBase,\r
+ &TeData,\r
+ &TeDataSize\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto finish;\r
+ }\r
+\r
+ // Obtain the PE/COFF Section information for the Standalone MM core module\r
+ Status = GetStandaloneMmCorePeCoffSections (\r
+ TeData,\r
+ &ImageContext,\r
+ &ImageBase,\r
+ &SectionHeaderOffset,\r
+ &NumberOfSections\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto finish;\r
+ }\r
+\r
+ //\r
+ // ImageBase may deviate from ImageContext.ImageAddress if we are dealing\r
+ // with a TE image, in which case the latter points to the actual offset\r
+ // of the image, whereas ImageBase refers to the address where the image\r
+ // would start if the stripped PE headers were still in place. In either\r
+ // case, we need to fix up ImageBase so it refers to the actual current\r
+ // load address.\r
+ //\r
+ ImageBase += (UINTN)TeData - ImageContext.ImageAddress;\r
+\r
+ // Update the memory access permissions of individual sections in the\r
+ // Standalone MM core module\r
+ Status = UpdateMmFoundationPeCoffPermissions (\r
+ &ImageContext,\r
+ ImageBase,\r
+ SectionHeaderOffset,\r
+ NumberOfSections,\r
+ ArmSetMemoryRegionNoExec,\r
+ ArmSetMemoryRegionReadOnly,\r
+ ArmClearMemoryRegionReadOnly\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto finish;\r
+ }\r
+\r
+ if (ImageContext.ImageAddress != (UINTN)TeData) {\r
+ ImageContext.ImageAddress = (UINTN)TeData;\r
+ ArmSetMemoryRegionNoExec (ImageBase, SIZE_4KB);\r
+ ArmClearMemoryRegionReadOnly (ImageBase, SIZE_4KB);\r
+\r
+ Status = PeCoffLoaderRelocateImage (&ImageContext);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ //\r
+ // Create Hoblist based upon boot information passed by privileged software\r
+ //\r
+ HobStart = CreateHobListFromBootInfo (&CpuDriverEntryPoint, PayloadBootInfo);\r
+\r
+ //\r
+ // Call the MM Core entry point\r
+ //\r
+ ProcessModuleEntryPointList (HobStart);\r
+\r
+ DEBUG ((DEBUG_INFO, "Shared Cpu Driver EP %p\n", (VOID *) CpuDriverEntryPoint));\r
+\r
+finish:\r
+ if (Status == RETURN_UNSUPPORTED) {\r
+ Ret = -1;\r
+ } else if (Status == RETURN_INVALID_PARAMETER) {\r
+ Ret = -2;\r
+ } else if (Status == EFI_NOT_FOUND) {\r
+ Ret = -7;\r
+ } else {\r
+ Ret = 0;\r
+ }\r
+ ZeroMem (&InitMmFoundationSvcArgs, sizeof(InitMmFoundationSvcArgs));\r
+ InitArmSvcArgs (&InitMmFoundationSvcArgs, &Ret);\r
+ DelegatedEventLoop (&InitMmFoundationSvcArgs);\r
+}\r
# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only)\r
#\r
\r
-[Sources.AARCH64]\r
- AArch64/StandaloneMmCoreEntryPoint.c\r
- AArch64/SetPermissions.c\r
- AArch64/CreateHobList.c\r
+[Sources.AARCH64, Sources.ARM]\r
+ Arm/StandaloneMmCoreEntryPoint.c\r
+ Arm/SetPermissions.c\r
+ Arm/CreateHobList.c\r
\r
[Sources.X64]\r
X64/StandaloneMmCoreEntryPoint.c\r
MdeModulePkg/MdeModulePkg.dec\r
StandaloneMmPkg/StandaloneMmPkg.dec\r
\r
-[Packages.AARCH64]\r
+[Packages.ARM, Packages.AARCH64]\r
ArmPkg/ArmPkg.dec\r
\r
[LibraryClasses]\r
BaseLib\r
DebugLib\r
\r
-[LibraryClasses.AARCH64]\r
+[LibraryClasses.ARM, LibraryClasses.AARCH64]\r
StandaloneMmMmuLib\r
ArmSvcLib\r
\r
gEfiStandaloneMmNonSecureBufferGuid\r
gEfiArmTfCpuDriverEpDescriptorGuid\r
\r
-[FeaturePcd.AARCH64]\r
+[FeaturePcd.ARM, FeaturePcd.AARCH64]\r
gArmTokenSpaceGuid.PcdFfaEnable\r
\r
[BuildOptions]\r
+++ /dev/null
-/** @file\r
- HOB Library implementation for Standalone MM Core.\r
-\r
-Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
-Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <PiMm.h>\r
-\r
-#include <Library/HobLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-\r
-#include <Guid/MemoryAllocationHob.h>\r
-\r
-//\r
-// Cache copy of HobList pointer.\r
-//\r
-VOID *gHobList = NULL;\r
-\r
-VOID *\r
-CreateHob (\r
- IN UINT16 HobType,\r
- IN UINT16 HobLength\r
- )\r
-{\r
- EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;\r
- EFI_HOB_GENERIC_HEADER *HobEnd;\r
- EFI_PHYSICAL_ADDRESS FreeMemory;\r
- VOID *Hob;\r
-\r
- HandOffHob = GetHobList ();\r
-\r
- HobLength = (UINT16)((HobLength + 0x7) & (~0x7));\r
-\r
- FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;\r
-\r
- if (FreeMemory < HobLength) {\r
- return NULL;\r
- }\r
-\r
- Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;\r
- ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;\r
- ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;\r
- ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;\r
-\r
- HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);\r
- HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
-\r
- HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
- HobEnd->HobLength = sizeof (EFI_HOB_GENERIC_HEADER);\r
- HobEnd->Reserved = 0;\r
- HobEnd++;\r
- HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
-\r
- return Hob;\r
-}\r
-\r
-/**\r
- Builds a HOB for a loaded PE32 module.\r
-\r
- This function builds a HOB for a loaded PE32 module.\r
- If ModuleName is NULL, then ASSERT().\r
- If there is no additional space for HOB creation, then ASSERT().\r
-\r
- @param ModuleName The GUID File Name of the module.\r
- @param MemoryAllocationModule The 64 bit physical address of the module.\r
- @param ModuleLength The length of the module in bytes.\r
- @param EntryPoint The 64 bit physical address of the module entry point.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BuildModuleHob (\r
- IN CONST EFI_GUID *ModuleName,\r
- IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,\r
- IN UINT64 ModuleLength,\r
- IN EFI_PHYSICAL_ADDRESS EntryPoint\r
- )\r
-{\r
- EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;\r
-\r
- ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&\r
- ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));\r
-\r
- Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));\r
-\r
- CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);\r
- Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;\r
- Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;\r
- Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;\r
-\r
- //\r
- // Zero the reserved space to match HOB spec\r
- //\r
- ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));\r
-\r
- CopyGuid (&Hob->ModuleName, ModuleName);\r
- Hob->EntryPoint = EntryPoint;\r
-}\r
-\r
-/**\r
- Builds a HOB that describes a chunk of system memory.\r
-\r
- This function builds a HOB that describes a chunk of system memory.\r
- If there is no additional space for HOB creation, then ASSERT().\r
-\r
- @param ResourceType The type of resource described by this HOB.\r
- @param ResourceAttribute The resource attributes of the memory described by this HOB.\r
- @param PhysicalStart The 64 bit physical address of memory described by this HOB.\r
- @param NumberOfBytes The length of the memory described by this HOB in bytes.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BuildResourceDescriptorHob (\r
- IN EFI_RESOURCE_TYPE ResourceType,\r
- IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,\r
- IN EFI_PHYSICAL_ADDRESS PhysicalStart,\r
- IN UINT64 NumberOfBytes\r
- )\r
-{\r
- EFI_HOB_RESOURCE_DESCRIPTOR *Hob;\r
-\r
- Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));\r
- ASSERT (Hob != NULL);\r
-\r
- Hob->ResourceType = ResourceType;\r
- Hob->ResourceAttribute = ResourceAttribute;\r
- Hob->PhysicalStart = PhysicalStart;\r
- Hob->ResourceLength = NumberOfBytes;\r
-}\r
-\r
-/**\r
- Builds a GUID HOB with a certain data length.\r
-\r
- This function builds a customized HOB tagged with a GUID for identification\r
- and returns the start address of GUID HOB data so that caller can fill the customized data.\r
- The HOB Header and Name field is already stripped.\r
- If Guid is NULL, then ASSERT().\r
- If there is no additional space for HOB creation, then ASSERT().\r
- If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
-\r
- @param Guid The GUID to tag the customized HOB.\r
- @param DataLength The size of the data payload for the GUID HOB.\r
-\r
- @return The start address of GUID HOB data.\r
-\r
-**/\r
-VOID *\r
-EFIAPI\r
-BuildGuidHob (\r
- IN CONST EFI_GUID *Guid,\r
- IN UINTN DataLength\r
- )\r
-{\r
- EFI_HOB_GUID_TYPE *Hob;\r
-\r
- //\r
- // Make sure that data length is not too long.\r
- //\r
- ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));\r
-\r
- Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));\r
- CopyGuid (&Hob->Name, Guid);\r
- return Hob + 1;\r
-}\r
-\r
-\r
-/**\r
- Copies a data buffer to a newly-built HOB.\r
-\r
- This function builds a customized HOB tagged with a GUID for identification,\r
- copies the input data to the HOB data field and returns the start address of the GUID HOB data.\r
- The HOB Header and Name field is already stripped.\r
- If Guid is NULL, then ASSERT().\r
- If Data is NULL and DataLength > 0, then ASSERT().\r
- If there is no additional space for HOB creation, then ASSERT().\r
- If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
-\r
- @param Guid The GUID to tag the customized HOB.\r
- @param Data The data to be copied into the data field of the GUID HOB.\r
- @param DataLength The size of the data payload for the GUID HOB.\r
-\r
- @return The start address of GUID HOB data.\r
-\r
-**/\r
-VOID *\r
-EFIAPI\r
-BuildGuidDataHob (\r
- IN CONST EFI_GUID *Guid,\r
- IN VOID *Data,\r
- IN UINTN DataLength\r
- )\r
-{\r
- VOID *HobData;\r
-\r
- ASSERT (Data != NULL || DataLength == 0);\r
-\r
- HobData = BuildGuidHob (Guid, DataLength);\r
-\r
- return CopyMem (HobData, Data, DataLength);\r
-}\r
-\r
-/**\r
- Builds a Firmware Volume HOB.\r
-\r
- This function builds a Firmware Volume HOB.\r
- If there is no additional space for HOB creation, then ASSERT().\r
-\r
- @param BaseAddress The base address of the Firmware Volume.\r
- @param Length The size of the Firmware Volume in bytes.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BuildFvHob (\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length\r
- )\r
-{\r
- EFI_HOB_FIRMWARE_VOLUME *Hob;\r
-\r
- Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));\r
-\r
- Hob->BaseAddress = BaseAddress;\r
- Hob->Length = Length;\r
-}\r
-\r
-\r
-/**\r
- Builds a EFI_HOB_TYPE_FV2 HOB.\r
-\r
- This function builds a EFI_HOB_TYPE_FV2 HOB.\r
- If there is no additional space for HOB creation, then ASSERT().\r
-\r
- @param BaseAddress The base address of the Firmware Volume.\r
- @param Length The size of the Firmware Volume in bytes.\r
- @param FvName The name of the Firmware Volume.\r
- @param FileName The name of the file.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BuildFv2Hob (\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length,\r
- IN CONST EFI_GUID *FvName,\r
- IN CONST EFI_GUID *FileName\r
- )\r
-{\r
- EFI_HOB_FIRMWARE_VOLUME2 *Hob;\r
-\r
- Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));\r
-\r
- Hob->BaseAddress = BaseAddress;\r
- Hob->Length = Length;\r
- CopyGuid (&Hob->FvName, FvName);\r
- CopyGuid (&Hob->FileName, FileName);\r
-}\r
-\r
-\r
-/**\r
- Builds a HOB for the CPU.\r
-\r
- This function builds a HOB for the CPU.\r
- If there is no additional space for HOB creation, then ASSERT().\r
-\r
- @param SizeOfMemorySpace The maximum physical memory addressability of the processor.\r
- @param SizeOfIoSpace The maximum physical I/O addressability of the processor.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BuildCpuHob (\r
- IN UINT8 SizeOfMemorySpace,\r
- IN UINT8 SizeOfIoSpace\r
- )\r
-{\r
- EFI_HOB_CPU *Hob;\r
-\r
- Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));\r
-\r
- Hob->SizeOfMemorySpace = SizeOfMemorySpace;\r
- Hob->SizeOfIoSpace = SizeOfIoSpace;\r
-\r
- //\r
- // Zero the reserved space to match HOB spec\r
- //\r
- ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));\r
-}\r
-\r
-/**\r
- Builds a HOB for the memory allocation.\r
-\r
- This function builds a HOB for the memory allocation.\r
- If there is no additional space for HOB creation, then ASSERT().\r
-\r
- @param BaseAddress The 64 bit physical address of the memory.\r
- @param Length The length of the memory allocation in bytes.\r
- @param MemoryType Type of memory allocated by this HOB.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BuildMemoryAllocationHob (\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length,\r
- IN EFI_MEMORY_TYPE MemoryType\r
- )\r
-{\r
- EFI_HOB_MEMORY_ALLOCATION *Hob;\r
-\r
- ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
- ((Length & (EFI_PAGE_SIZE - 1)) == 0));\r
-\r
- Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));\r
-\r
- ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));\r
- Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
- Hob->AllocDescriptor.MemoryLength = Length;\r
- Hob->AllocDescriptor.MemoryType = MemoryType;\r
- //\r
- // Zero the reserved space to match HOB spec\r
- //\r
- ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));\r
-}\r
+++ /dev/null
-/** @file\r
- HOB Library implementation for Standalone MM Core.\r
-\r
-Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
-Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <PiMm.h>\r
-\r
-#include <Library/HobLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-\r
-#include <Guid/MemoryAllocationHob.h>\r
-\r
-//\r
-// Cache copy of HobList pointer.\r
-//\r
-extern VOID *gHobList;\r
-\r
-EFI_HOB_HANDOFF_INFO_TABLE*\r
-HobConstructor (\r
- IN VOID *EfiMemoryBegin,\r
- IN UINTN EfiMemoryLength,\r
- IN VOID *EfiFreeMemoryBottom,\r
- IN VOID *EfiFreeMemoryTop\r
- )\r
-{\r
- EFI_HOB_HANDOFF_INFO_TABLE *Hob;\r
- EFI_HOB_GENERIC_HEADER *HobEnd;\r
-\r
- Hob = EfiFreeMemoryBottom;\r
- HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);\r
-\r
- Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;\r
- Hob->Header.HobLength = sizeof (EFI_HOB_HANDOFF_INFO_TABLE);\r
- Hob->Header.Reserved = 0;\r
-\r
- HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
- HobEnd->HobLength = sizeof (EFI_HOB_GENERIC_HEADER);\r
- HobEnd->Reserved = 0;\r
-\r
- Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;\r
- Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION;\r
-\r
- Hob->EfiMemoryTop = (UINTN)EfiMemoryBegin + EfiMemoryLength;\r
- Hob->EfiMemoryBottom = (UINTN)EfiMemoryBegin;\r
- Hob->EfiFreeMemoryTop = (UINTN)EfiFreeMemoryTop;\r
- Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);\r
- Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;\r
-\r
- gHobList = Hob;\r
-\r
- return Hob;\r
-}\r
--- /dev/null
+/** @file\r
+ HOB Library implementation for Standalone MM Core.\r
+\r
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiMm.h>\r
+\r
+#include <Library/HobLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+#include <Guid/MemoryAllocationHob.h>\r
+\r
+//\r
+// Cache copy of HobList pointer.\r
+//\r
+VOID *gHobList = NULL;\r
+\r
+VOID *\r
+CreateHob (\r
+ IN UINT16 HobType,\r
+ IN UINT16 HobLength\r
+ )\r
+{\r
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;\r
+ EFI_HOB_GENERIC_HEADER *HobEnd;\r
+ EFI_PHYSICAL_ADDRESS FreeMemory;\r
+ VOID *Hob;\r
+\r
+ HandOffHob = GetHobList ();\r
+\r
+ HobLength = (UINT16)((HobLength + 0x7) & (~0x7));\r
+\r
+ FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;\r
+\r
+ if (FreeMemory < HobLength) {\r
+ return NULL;\r
+ }\r
+\r
+ Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;\r
+ ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;\r
+ ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;\r
+ ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;\r
+\r
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);\r
+ HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
+\r
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
+ HobEnd->HobLength = sizeof (EFI_HOB_GENERIC_HEADER);\r
+ HobEnd->Reserved = 0;\r
+ HobEnd++;\r
+ HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
+\r
+ return Hob;\r
+}\r
+\r
+/**\r
+ Builds a HOB for a loaded PE32 module.\r
+\r
+ This function builds a HOB for a loaded PE32 module.\r
+ If ModuleName is NULL, then ASSERT().\r
+ If there is no additional space for HOB creation, then ASSERT().\r
+\r
+ @param ModuleName The GUID File Name of the module.\r
+ @param MemoryAllocationModule The 64 bit physical address of the module.\r
+ @param ModuleLength The length of the module in bytes.\r
+ @param EntryPoint The 64 bit physical address of the module entry point.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildModuleHob (\r
+ IN CONST EFI_GUID *ModuleName,\r
+ IN EFI_PHYSICAL_ADDRESS MemoryAllocationModule,\r
+ IN UINT64 ModuleLength,\r
+ IN EFI_PHYSICAL_ADDRESS EntryPoint\r
+ )\r
+{\r
+ EFI_HOB_MEMORY_ALLOCATION_MODULE *Hob;\r
+\r
+ ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&\r
+ ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));\r
+\r
+ Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));\r
+\r
+ CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);\r
+ Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;\r
+ Hob->MemoryAllocationHeader.MemoryLength = ModuleLength;\r
+ Hob->MemoryAllocationHeader.MemoryType = EfiBootServicesCode;\r
+\r
+ //\r
+ // Zero the reserved space to match HOB spec\r
+ //\r
+ ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));\r
+\r
+ CopyGuid (&Hob->ModuleName, ModuleName);\r
+ Hob->EntryPoint = EntryPoint;\r
+}\r
+\r
+/**\r
+ Builds a HOB that describes a chunk of system memory.\r
+\r
+ This function builds a HOB that describes a chunk of system memory.\r
+ If there is no additional space for HOB creation, then ASSERT().\r
+\r
+ @param ResourceType The type of resource described by this HOB.\r
+ @param ResourceAttribute The resource attributes of the memory described by this HOB.\r
+ @param PhysicalStart The 64 bit physical address of memory described by this HOB.\r
+ @param NumberOfBytes The length of the memory described by this HOB in bytes.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildResourceDescriptorHob (\r
+ IN EFI_RESOURCE_TYPE ResourceType,\r
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,\r
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,\r
+ IN UINT64 NumberOfBytes\r
+ )\r
+{\r
+ EFI_HOB_RESOURCE_DESCRIPTOR *Hob;\r
+\r
+ Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));\r
+ ASSERT (Hob != NULL);\r
+\r
+ Hob->ResourceType = ResourceType;\r
+ Hob->ResourceAttribute = ResourceAttribute;\r
+ Hob->PhysicalStart = PhysicalStart;\r
+ Hob->ResourceLength = NumberOfBytes;\r
+}\r
+\r
+/**\r
+ Builds a GUID HOB with a certain data length.\r
+\r
+ This function builds a customized HOB tagged with a GUID for identification\r
+ and returns the start address of GUID HOB data so that caller can fill the customized data.\r
+ The HOB Header and Name field is already stripped.\r
+ If Guid is NULL, then ASSERT().\r
+ If there is no additional space for HOB creation, then ASSERT().\r
+ If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
+\r
+ @param Guid The GUID to tag the customized HOB.\r
+ @param DataLength The size of the data payload for the GUID HOB.\r
+\r
+ @return The start address of GUID HOB data.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+BuildGuidHob (\r
+ IN CONST EFI_GUID *Guid,\r
+ IN UINTN DataLength\r
+ )\r
+{\r
+ EFI_HOB_GUID_TYPE *Hob;\r
+\r
+ //\r
+ // Make sure that data length is not too long.\r
+ //\r
+ ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));\r
+\r
+ Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));\r
+ CopyGuid (&Hob->Name, Guid);\r
+ return Hob + 1;\r
+}\r
+\r
+\r
+/**\r
+ Copies a data buffer to a newly-built HOB.\r
+\r
+ This function builds a customized HOB tagged with a GUID for identification,\r
+ copies the input data to the HOB data field and returns the start address of the GUID HOB data.\r
+ The HOB Header and Name field is already stripped.\r
+ If Guid is NULL, then ASSERT().\r
+ If Data is NULL and DataLength > 0, then ASSERT().\r
+ If there is no additional space for HOB creation, then ASSERT().\r
+ If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
+\r
+ @param Guid The GUID to tag the customized HOB.\r
+ @param Data The data to be copied into the data field of the GUID HOB.\r
+ @param DataLength The size of the data payload for the GUID HOB.\r
+\r
+ @return The start address of GUID HOB data.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+BuildGuidDataHob (\r
+ IN CONST EFI_GUID *Guid,\r
+ IN VOID *Data,\r
+ IN UINTN DataLength\r
+ )\r
+{\r
+ VOID *HobData;\r
+\r
+ ASSERT (Data != NULL || DataLength == 0);\r
+\r
+ HobData = BuildGuidHob (Guid, DataLength);\r
+\r
+ return CopyMem (HobData, Data, DataLength);\r
+}\r
+\r
+/**\r
+ Builds a Firmware Volume HOB.\r
+\r
+ This function builds a Firmware Volume HOB.\r
+ If there is no additional space for HOB creation, then ASSERT().\r
+\r
+ @param BaseAddress The base address of the Firmware Volume.\r
+ @param Length The size of the Firmware Volume in bytes.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildFvHob (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length\r
+ )\r
+{\r
+ EFI_HOB_FIRMWARE_VOLUME *Hob;\r
+\r
+ Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));\r
+\r
+ Hob->BaseAddress = BaseAddress;\r
+ Hob->Length = Length;\r
+}\r
+\r
+\r
+/**\r
+ Builds a EFI_HOB_TYPE_FV2 HOB.\r
+\r
+ This function builds a EFI_HOB_TYPE_FV2 HOB.\r
+ If there is no additional space for HOB creation, then ASSERT().\r
+\r
+ @param BaseAddress The base address of the Firmware Volume.\r
+ @param Length The size of the Firmware Volume in bytes.\r
+ @param FvName The name of the Firmware Volume.\r
+ @param FileName The name of the file.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildFv2Hob (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN CONST EFI_GUID *FvName,\r
+ IN CONST EFI_GUID *FileName\r
+ )\r
+{\r
+ EFI_HOB_FIRMWARE_VOLUME2 *Hob;\r
+\r
+ Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));\r
+\r
+ Hob->BaseAddress = BaseAddress;\r
+ Hob->Length = Length;\r
+ CopyGuid (&Hob->FvName, FvName);\r
+ CopyGuid (&Hob->FileName, FileName);\r
+}\r
+\r
+\r
+/**\r
+ Builds a HOB for the CPU.\r
+\r
+ This function builds a HOB for the CPU.\r
+ If there is no additional space for HOB creation, then ASSERT().\r
+\r
+ @param SizeOfMemorySpace The maximum physical memory addressability of the processor.\r
+ @param SizeOfIoSpace The maximum physical I/O addressability of the processor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildCpuHob (\r
+ IN UINT8 SizeOfMemorySpace,\r
+ IN UINT8 SizeOfIoSpace\r
+ )\r
+{\r
+ EFI_HOB_CPU *Hob;\r
+\r
+ Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));\r
+\r
+ Hob->SizeOfMemorySpace = SizeOfMemorySpace;\r
+ Hob->SizeOfIoSpace = SizeOfIoSpace;\r
+\r
+ //\r
+ // Zero the reserved space to match HOB spec\r
+ //\r
+ ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));\r
+}\r
+\r
+/**\r
+ Builds a HOB for the memory allocation.\r
+\r
+ This function builds a HOB for the memory allocation.\r
+ If there is no additional space for HOB creation, then ASSERT().\r
+\r
+ @param BaseAddress The 64 bit physical address of the memory.\r
+ @param Length The length of the memory allocation in bytes.\r
+ @param MemoryType Type of memory allocated by this HOB.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildMemoryAllocationHob (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN EFI_MEMORY_TYPE MemoryType\r
+ )\r
+{\r
+ EFI_HOB_MEMORY_ALLOCATION *Hob;\r
+\r
+ ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
+ ((Length & (EFI_PAGE_SIZE - 1)) == 0));\r
+\r
+ Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));\r
+\r
+ ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));\r
+ Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
+ Hob->AllocDescriptor.MemoryLength = Length;\r
+ Hob->AllocDescriptor.MemoryType = MemoryType;\r
+ //\r
+ // Zero the reserved space to match HOB spec\r
+ //\r
+ ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));\r
+}\r
--- /dev/null
+/** @file\r
+ HOB Library implementation for Standalone MM Core.\r
+\r
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiMm.h>\r
+\r
+#include <Library/HobLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+#include <Guid/MemoryAllocationHob.h>\r
+\r
+//\r
+// Cache copy of HobList pointer.\r
+//\r
+extern VOID *gHobList;\r
+\r
+EFI_HOB_HANDOFF_INFO_TABLE*\r
+HobConstructor (\r
+ IN VOID *EfiMemoryBegin,\r
+ IN UINTN EfiMemoryLength,\r
+ IN VOID *EfiFreeMemoryBottom,\r
+ IN VOID *EfiFreeMemoryTop\r
+ )\r
+{\r
+ EFI_HOB_HANDOFF_INFO_TABLE *Hob;\r
+ EFI_HOB_GENERIC_HEADER *HobEnd;\r
+\r
+ Hob = EfiFreeMemoryBottom;\r
+ HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);\r
+\r
+ Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;\r
+ Hob->Header.HobLength = sizeof (EFI_HOB_HANDOFF_INFO_TABLE);\r
+ Hob->Header.Reserved = 0;\r
+\r
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
+ HobEnd->HobLength = sizeof (EFI_HOB_GENERIC_HEADER);\r
+ HobEnd->Reserved = 0;\r
+\r
+ Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;\r
+ Hob->BootMode = BOOT_WITH_FULL_CONFIGURATION;\r
+\r
+ Hob->EfiMemoryTop = (UINTN)EfiMemoryBegin + EfiMemoryLength;\r
+ Hob->EfiMemoryBottom = (UINTN)EfiMemoryBegin;\r
+ Hob->EfiFreeMemoryTop = (UINTN)EfiFreeMemoryTop;\r
+ Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);\r
+ Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;\r
+\r
+ gHobList = Hob;\r
+\r
+ return Hob;\r
+}\r
LIBRARY_CLASS = HobLib|MM_CORE_STANDALONE\r
\r
#\r
-# VALID_ARCHITECTURES = X64 AARCH64\r
+# VALID_ARCHITECTURES = X64 AARCH64 ARM\r
#\r
[Sources.common]\r
Common.c\r
[Sources.X64]\r
X64/StandaloneMmCoreHobLib.c\r
\r
-[Sources.AARCH64]\r
- AArch64/StandaloneMmCoreHobLib.c\r
- AArch64/StandaloneMmCoreHobLibInternal.c\r
+[Sources.AARCH64, Sources.ARM]\r
+ Arm/StandaloneMmCoreHobLib.c\r
+ Arm/StandaloneMmCoreHobLibInternal.c\r
\r
[Packages]\r
MdePkg/MdePkg.dec\r
+++ /dev/null
-/** @file\r
- Internal ARCH Specific file of MM memory check library.\r
-\r
- MM memory check library implementation. This library consumes MM_ACCESS_PROTOCOL\r
- to get MMRAM information. In order to use this library instance, the platform should produce\r
- all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core\r
- and MM driver) and/or specific dedicated hardware.\r
-\r
- Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
- Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>\r
-\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-//\r
-// Maximum support address used to check input buffer\r
-//\r
-extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress;\r
-\r
-/**\r
- Calculate and save the maximum support address.\r
-\r
-**/\r
-VOID\r
-MmMemLibInternalCalculateMaximumSupportAddress (\r
- VOID\r
- )\r
-{\r
- UINT8 PhysicalAddressBits;\r
-\r
- PhysicalAddressBits = 36;\r
-\r
- //\r
- // Save the maximum support address in one global variable\r
- //\r
- mMmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1);\r
- DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress));\r
-}\r
-\r
-/**\r
- Initialize cached Mmram Ranges from HOB.\r
-\r
- @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.\r
- @retval EFI_SUCCESS MmRanges are populated successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-MmMemLibInternalPopulateMmramRanges (\r
- VOID\r
- )\r
-{\r
- // Not implemented for AARCH64.\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Deinitialize cached Mmram Ranges.\r
-\r
-**/\r
-VOID\r
-MmMemLibInternalFreeMmramRanges (\r
- VOID\r
- )\r
-{\r
- // Not implemented for AARCH64.\r
-}\r
-\r
--- /dev/null
+/** @file\r
+ Internal ARCH Specific file of MM memory check library.\r
+\r
+ MM memory check library implementation. This library consumes MM_ACCESS_PROTOCOL\r
+ to get MMRAM information. In order to use this library instance, the platform should produce\r
+ all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core\r
+ and MM driver) and/or specific dedicated hardware.\r
+\r
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+//\r
+// Maximum support address used to check input buffer\r
+//\r
+extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress;\r
+\r
+#ifdef MDE_CPU_AARCH64\r
+#define ARM_PHYSICAL_ADDRESS_BITS 36\r
+#endif\r
+#ifdef MDE_CPU_ARM\r
+#define ARM_PHYSICAL_ADDRESS_BITS 32\r
+#endif\r
+\r
+/**\r
+ Calculate and save the maximum support address.\r
+\r
+**/\r
+VOID\r
+MmMemLibInternalCalculateMaximumSupportAddress (\r
+ VOID\r
+ )\r
+{\r
+ UINT8 PhysicalAddressBits;\r
+\r
+ PhysicalAddressBits = ARM_PHYSICAL_ADDRESS_BITS;\r
+\r
+ //\r
+ // Save the maximum support address in one global variable\r
+ //\r
+ mMmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1);\r
+ DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress));\r
+}\r
+\r
+/**\r
+ Initialize cached Mmram Ranges from HOB.\r
+\r
+ @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.\r
+ @retval EFI_SUCCESS MmRanges are populated successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+MmMemLibInternalPopulateMmramRanges (\r
+ VOID\r
+ )\r
+{\r
+ // Not implemented for AARCH64.\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Deinitialize cached Mmram Ranges.\r
+\r
+**/\r
+VOID\r
+MmMemLibInternalFreeMmramRanges (\r
+ VOID\r
+ )\r
+{\r
+ // Not implemented for AARCH64.\r
+}\r
+\r
#\r
# The following information is for reference only and not required by the build tools.\r
#\r
-# VALID_ARCHITECTURES = IA32 X64 AARCH64\r
+# VALID_ARCHITECTURES = IA32 X64 AARCH64 ARM\r
#\r
\r
[Sources.Common]\r
[Sources.IA32, Sources.X64]\r
X86StandaloneMmMemLibInternal.c\r
\r
-[Sources.AARCH64]\r
- AArch64/StandaloneMmMemLibInternal.c\r
+[Sources.AARCH64, Sources.ARM]\r
+ ArmStandaloneMmMemLibInternal.c\r
\r
[Packages]\r
MdePkg/MdePkg.dec\r
#\r
# The following information is for reference only and not required by the build tools.\r
#\r
-# VALID_ARCHITECTURES = AARCH64\r
+# VALID_ARCHITECTURES = AARCH64|ARM\r
#\r
#\r
\r
## MM Memory Operation.\r
MemLib|Include/Library/StandaloneMmMemLib.h\r
\r
-[LibraryClasses.AArch64]\r
+[LibraryClasses.AArch64, LibraryClasses.ARM]\r
## @libraryclass Defines a set of interfaces for the MM core entrypoint for\r
- ## AArch64.\r
- StandaloneMmCoreEntryPoint|Include/Library/AArch64/StandaloneMmCoreEntryPoint.h\r
+ ## AArch64 and ARM.\r
+ StandaloneMmCoreEntryPoint|Include/Library/Arm/StandaloneMmCoreEntryPoint.h\r
\r
[Guids]\r
gStandaloneMmPkgTokenSpaceGuid = { 0x18fe7632, 0xf5c8, 0x4e63, { 0x8d, 0xe8, 0x17, 0xa5, 0x5c, 0x59, 0x13, 0xbd }}\r
PLATFORM_VERSION = 1.0\r
DSC_SPECIFICATION = 0x00010011\r
OUTPUT_DIRECTORY = Build/StandaloneMm\r
- SUPPORTED_ARCHITECTURES = AARCH64|X64\r
+ SUPPORTED_ARCHITECTURES = AARCH64|X64|ARM\r
BUILD_TARGETS = DEBUG|RELEASE\r
SKUID_IDENTIFIER = DEFAULT\r
\r
StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf\r
VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf\r
\r
-[LibraryClasses.AARCH64]\r
+[LibraryClasses.AARCH64, LibraryClasses.ARM]\r
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf\r
StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf\r
ArmSvcLib|ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf\r
StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf\r
StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf\r
\r
-[Components.AARCH64]\r
- StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.inf\r
+[Components.AARCH64, Components.ARM]\r
+ StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf\r
StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf\r
\r
###################################################################################################\r
GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -march=armv8-a+nofp -mstrict-align\r
GCC:*_*_*_CC_FLAGS = -mstrict-align\r
\r
+[BuildOptions.ARM]\r
+GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 -march=armv7-a\r
+GCC:*_*_*_CC_FLAGS = -fno-stack-protector\r
+\r
[BuildOptions.X64]\r
MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096\r
GCC:*_GCC*_*_DLINK_FLAGS = -z common-page-size=0x1000\r