From nobody Fri Nov 1 04:43:48 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1523025817555333.0121505988427; Fri, 6 Apr 2018 07:43:37 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 1CEA622620E70; Fri, 6 Apr 2018 07:43:35 -0700 (PDT) Received: from foss.arm.com (usa-sjc-mx-foss1.foss.arm.com [217.140.101.70]) by ml01.01.org (Postfix) with ESMTP id 2D8C222620E6A for ; Fri, 6 Apr 2018 07:43:33 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D966C1529; Fri, 6 Apr 2018 07:43:33 -0700 (PDT) Received: from u201365.usa.Arm.com (bc-c3-3-14.eu.iaas.arm.com [10.6.43.238]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 3E02C3F587; Fri, 6 Apr 2018 07:43:32 -0700 (PDT) X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=217.140.101.70; helo=foss.arm.com; envelope-from=supreeth.venkatesh@arm.com; receiver=edk2-devel@lists.01.org From: Supreeth Venkatesh To: edk2-devel@lists.01.org Date: Fri, 6 Apr 2018 15:42:17 +0100 Message-Id: <20180406144223.10931-13-supreeth.venkatesh@arm.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180406144223.10931-1-supreeth.venkatesh@arm.com> References: <20180406144223.10931-1-supreeth.venkatesh@arm.com> Subject: [edk2] [PATCH v1 12/18] StandaloneMmPkg/CpuMm: Add CPU driver suitable for ARM Platforms. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: ard.biesheuvel@linaro.org, leif.lindholm@linaro.org, jiewen.yao@intel.com, liming.gao@intel.com, michael.d.kinney@intel.com MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This patch adds a simple CPU driver that exports the EFI_MM_CONFIGURATION_PROTOCOL to allow registration of the Standalone MM Foundation entry point. It preserves the existing notification mechanism for the configuration protocol. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Achin Gupta Signed-off-by: Supreeth Venkatesh --- StandaloneMmPkg/Drivers/CpuMm/Arm/Entry.S | 33 +++ StandaloneMmPkg/Drivers/CpuMm/Arm/EventHandle.c | 231 +++++++++++++++++= ++++ StandaloneMmPkg/Drivers/CpuMm/Arm/Init.c | 229 +++++++++++++++++= +++ .../CpuMm/Arm/PiMmStandloneArmTfCpuDriver.h | 89 ++++++++ .../CpuMm/Arm/PiMmStandloneArmTfCpuDriver.inf | 60 ++++++ StandaloneMmPkg/Drivers/CpuMm/Arm/StateSave.c | 51 +++++ StandaloneMmPkg/Include/Guid/MpInformation.h | 41 ++++ 7 files changed, 734 insertions(+) create mode 100644 StandaloneMmPkg/Drivers/CpuMm/Arm/Entry.S create mode 100644 StandaloneMmPkg/Drivers/CpuMm/Arm/EventHandle.c create mode 100644 StandaloneMmPkg/Drivers/CpuMm/Arm/Init.c create mode 100644 StandaloneMmPkg/Drivers/CpuMm/Arm/PiMmStandloneArmTfCpu= Driver.h create mode 100644 StandaloneMmPkg/Drivers/CpuMm/Arm/PiMmStandloneArmTfCpu= Driver.inf create mode 100644 StandaloneMmPkg/Drivers/CpuMm/Arm/StateSave.c create mode 100644 StandaloneMmPkg/Include/Guid/MpInformation.h diff --git a/StandaloneMmPkg/Drivers/CpuMm/Arm/Entry.S b/StandaloneMmPkg/Dr= ivers/CpuMm/Arm/Entry.S new file mode 100644 index 0000000000..0b6e1c330d --- /dev/null +++ b/StandaloneMmPkg/Drivers/CpuMm/Arm/Entry.S @@ -0,0 +1,33 @@ +// +// Copyright (c) 2017, ARM Limited. All rights reserved. +// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the = BSD License +// which accompanies this distribution. The full text of the license may= be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. +// +// + +#include +#include +#include + +.text +.align 3 + +GCC_ASM_IMPORT(PiMmStandloneArmTfCpuDriverEntry) +GCC_ASM_EXPORT(_PiMmStandloneArmTfCpuDriverEntry) + +// Stub entry point to ensure that the stacks are completely unwound before +// signalling completion of event handling +ASM_PFX(_PiMmStandloneArmTfCpuDriverEntry): + bl PiMmStandloneArmTfCpuDriverEntry + mov x1, x0 + mov x0, #(ARM_SMC_ID_MM_EVENT_COMPLETE_AARCH64 & 0xffff) + movk x0, #((ARM_SMC_ID_MM_EVENT_COMPLETE_AARCH64 >> 16) & 0xffff), lsl = #16 + svc #0 +LoopForever: + b LoopForever diff --git a/StandaloneMmPkg/Drivers/CpuMm/Arm/EventHandle.c b/StandaloneMm= Pkg/Drivers/CpuMm/Arm/EventHandle.c new file mode 100644 index 0000000000..7b19f53ecb --- /dev/null +++ b/StandaloneMmPkg/Drivers/CpuMm/Arm/EventHandle.c @@ -0,0 +1,231 @@ +/** @file + + Copyright (c) 2016 HP Development Company, L.P. + Copyright (c) 2016 - 2017, ARM Limited. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ + +#include +#include + + +#include +#include +#include +#include +#include + +#include // for EFI_SYSTEM_CONTEXT + +#include +#include + +#include + +#include "PiMmStandloneArmTfCpuDriver.h" + +EFI_STATUS +EFIAPI +MmFoundationEntryRegister( + IN CONST EFI_MM_CONFIGURATION_PROTOCOL *This, + IN EFI_MM_ENTRY_POINT MmEntryPoint + ); + +// +// On ARM platforms every event is expected to have a GUID associated with +// it. It will be used by the MM Entry point to find the handler for the +// event. It will either be populated in a EFI_MM_COMMUNICATE_HEADER by the +// caller of the event (e.g. MM_COMMUNICATE SMC) or by the CPU driver +// (e.g. during an asynchronous event). In either case, this context is +// maintained in an array which has an entry for each CPU. The pointer to = this +// array is held in PerCpuGuidedEventContext. Memory is allocated once the +// number of CPUs in the system are made known through the +// MP_INFORMATION_HOB_DATA. +// +EFI_MM_COMMUNICATE_HEADER **PerCpuGuidedEventContext =3D NULL; + +// +// When an event is received by the CPU driver, it could correspond to a u= nique +// GUID (e.g. interrupt events) or to multiple GUIDs (e.g. MM_COMMUNICATE +// SMC). A table is used by the CPU driver to find the GUID corresponding = to the +// event id in case there is a 1:1 mapping between the two. If an event id= has +// multiple GUIDs associated with it then such an entry will not be found = in +// this table. +// +// TODO: Currently NULL since there are no asynchronous events +static EFI_GUID *EventIdToGuidLookupTable =3D NULL; + +// Descriptor with whereabouts of memory used for communication with the n= ormal world +EFI_MMRAM_DESCRIPTOR mNsCommBuffer; + +MP_INFORMATION_HOB_DATA *mMpInformationHobData; + +EFI_MM_CONFIGURATION_PROTOCOL mMmConfig =3D { + 0, + MmFoundationEntryRegister +}; + +static EFI_MM_ENTRY_POINT mMmEntryPoint =3D NULL; + +EFI_STATUS +PiMmStandloneArmTfCpuDriverEntry ( + IN UINTN EventId, + IN UINTN CpuNumber, + IN UINTN NsCommBufferAddr + ) +{ + EFI_MM_COMMUNICATE_HEADER *GuidedEventContext =3D NULL; + EFI_MM_ENTRY_CONTEXT MmEntryPointContext =3D {0}; + EFI_STATUS Status; + UINTN NsCommBufferSize; + + DEBUG ((DEBUG_INFO, "Received event - 0x%x on cpu %d\n", EventId, CpuNum= ber)); + + // + // ARM TF passes SMC FID of the MM_COMMUNICATE interface as the Event ID= upon + // receipt of a synchronous MM request. Use the Event ID to distinguish + // between synchronous and asynchronous events. + // + if (ARM_SMC_ID_MM_COMMUNICATE_AARCH64 !=3D EventId) { + // Found a GUID, allocate memory to populate a communication buffer + // with the GUID in it + Status =3D mMmst->MmAllocatePool(EfiRuntimeServicesData, sizeof(EFI_MM= _COMMUNICATE_HEADER), (VOID **) &GuidedEventContext); + if (Status !=3D EFI_SUCCESS) { + DEBUG ((DEBUG_INFO, "Mem alloc failed - 0x%x\n", EventId)); + return Status; + } + + // Copy the GUID + CopyGuid(&GuidedEventContext->HeaderGuid, &EventIdToGuidLookupTable[Ev= entId]); + + // Message Length is 0 'cause of the assumption mentioned above + GuidedEventContext->MessageLength =3D 0; + } else { + // TODO: Perform parameter validation of NsCommBufferAddr + + // This event id is the parent of multiple GUIDed handlers. Retrieve + // the specific GUID from the communication buffer passed by the + // caller. + + if (NsCommBufferAddr && (NsCommBufferAddr < mNsCommBuffer.PhysicalStar= t)) + return EFI_INVALID_PARAMETER; + + // Find out the size of the buffer passed + NsCommBufferSize =3D ((EFI_MM_COMMUNICATE_HEADER *) NsCommBufferAddr)-= >MessageLength + + sizeof(((EFI_MM_COMMUNICATE_HEADER *)NsCommBufferA= ddr)->MessageLength) + + sizeof(((EFI_MM_COMMUNICATE_HEADER *)NsCommBufferA= ddr)->HeaderGuid); + + // Alternative approach in case EL3 has preallocated the non-secure + // buffer. MM Foundation is told about the buffer through the Hoblist + // and is responsible for performing the bounds check. + if (NsCommBufferAddr + NsCommBufferSize >=3D + mNsCommBuffer.PhysicalStart + mNsCommBuffer.PhysicalSize) + return EFI_INVALID_PARAMETER; + + + // Now that the secure world can see the normal world buffer, allocate + // memory to copy the communication buffer to the secure world. + Status =3D mMmst->MmAllocatePool(EfiRuntimeServicesData, NsCommBufferS= ize, (VOID **) &GuidedEventContext); + if (Status !=3D EFI_SUCCESS) { + DEBUG ((DEBUG_INFO, "Mem alloc failed - 0x%x\n", EventId)); + // TODO: Unmap secure memory before exiting to the normal world + return Status; + } + + // X1 contains the VA of the normal world memory accessible from + // S-EL0 + CopyMem(GuidedEventContext, (CONST VOID *) NsCommBufferAddr, NsCommBuf= ferSize); + } + + // Stash the pointer to the allocated Event Context for this CPU + PerCpuGuidedEventContext[CpuNumber] =3D GuidedEventContext; + + // TODO: Populate entire entry point context with valid information + MmEntryPointContext.CurrentlyExecutingCpu =3D CpuNumber; + MmEntryPointContext.NumberOfCpus =3D mMpInformationHobData->NumberOfProc= essors; + + // Populate the MM system table with MP and state information + mMmst->CurrentlyExecutingCpu =3D CpuNumber; + mMmst->NumberOfCpus =3D mMpInformationHobData->NumberOfProcessors; + mMmst->CpuSaveStateSize =3D 0; + mMmst->CpuSaveState =3D NULL; + + mMmEntryPoint(&MmEntryPointContext); + + // Free the memory allocation done earlier and reset the per-cpu context + // TODO: Check for the return status of the FreePool API + ASSERT (GuidedEventContext); + CopyMem ((VOID *)NsCommBufferAddr, (CONST VOID *) GuidedEventContext, Ns= CommBufferSize); + mMmst->MmFreePool((VOID *) GuidedEventContext); + PerCpuGuidedEventContext[CpuNumber] =3D NULL; + + return Status; +} + +EFI_STATUS +EFIAPI +MmFoundationEntryRegister( + IN CONST EFI_MM_CONFIGURATION_PROTOCOL *This, + IN EFI_MM_ENTRY_POINT MmEntryPoint + ) { + // store the entry point in a global + mMmEntryPoint =3D MmEntryPoint; + return EFI_SUCCESS; +} + +/** + This function is the main entry point for an MM handler dispatch + or communicate-based callback. + + @param DispatchHandle The unique handle assigned to this handler by Mm= iHandlerRegister(). + @param Context Points to an optional handler context which was = specified when the handler was registered. + @param CommBuffer A pointer to a collection of data in memory that= will + be conveyed from a non-MM environment into an MM= environment. + @param CommBufferSize The size of the CommBuffer. + + @return Status Code + +**/ +EFI_STATUS +EFIAPI +PiMmCpuTpFwRootMmiHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context, OPTIONAL + IN OUT VOID *CommBuffer, OPTIONAL + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN CpuNumber; + + ASSERT (Context =3D=3D NULL); + ASSERT (CommBuffer =3D=3D NULL); + ASSERT (CommBufferSize =3D=3D NULL); + + CpuNumber =3D mMmst->CurrentlyExecutingCpu; + if (!PerCpuGuidedEventContext[CpuNumber]) + return EFI_NOT_FOUND; + + DEBUG ((DEBUG_INFO, "CommBuffer - 0x%x, CommBufferSize - 0x%x\n", + PerCpuGuidedEventContext[CpuNumber], + PerCpuGuidedEventContext[CpuNumber]->MessageLength)); + + Status =3D mMmst->MmiManage(&PerCpuGuidedEventContext[CpuNumber]->Header= Guid, + NULL, + PerCpuGuidedEventContext[CpuNumber]->Data, + &PerCpuGuidedEventContext[CpuNumber]->MessageLength); + + if (Status !=3D EFI_SUCCESS) { + DEBUG ((DEBUG_WARN, "Unable to manage Guided Event - %d\n", Status)); + } + + return Status; +} diff --git a/StandaloneMmPkg/Drivers/CpuMm/Arm/Init.c b/StandaloneMmPkg/Dri= vers/CpuMm/Arm/Init.c new file mode 100644 index 0000000000..9b48ea15c1 --- /dev/null +++ b/StandaloneMmPkg/Drivers/CpuMm/Arm/Init.c @@ -0,0 +1,229 @@ +/** @file + + Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ Copyright (c) 2011, ARM Limited. All rights reserved. + Copyright (c) 2016 HP Development Company, L.P. + Copyright (c) 2016-2017, ARM Limited. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include // for EFI_SYSTEM_CONTEXT + +#include +#include + + +#include "PiMmStandloneArmTfCpuDriver.h" + +// GUID to identify HOB with whereabouts of communication buffer with Norm= al +// World +extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid; + +// GUID to identify HOB where the entry point of this CPU driver will be +// populated to allow the entry point driver to invoke it upon receipt of = an +// event +extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid; + +// +// Private copy of the MM system table for future use +// +EFI_MM_SYSTEM_TABLE *mMmst =3D NULL; + +// +// Globals used to initialize the protocol +// +static EFI_HANDLE mMmCpuHandle =3D NULL; + +EFI_STATUS +GetGuidedHobData ( + IN VOID *HobList, + IN CONST EFI_GUID *HobGuid, + OUT VOID **HobData) +{ + EFI_HOB_GUID_TYPE *Hob; + + if (!HobList || !HobGuid || !HobData) + return EFI_INVALID_PARAMETER; + + Hob =3D GetNextGuidHob (HobGuid, HobList); + if (!Hob) + return EFI_NOT_FOUND; + + *HobData =3D GET_GUID_HOB_DATA (Hob); + if (!HobData) + return EFI_NOT_FOUND; + + return EFI_SUCCESS; +} + +EFI_STATUS +PiMmStandloneArmTfCpuDriverInitialize ( + IN EFI_HANDLE ImageHandle, // not actual imagehandle + IN EFI_MM_SYSTEM_TABLE *SystemTable // not actual systemtable + ) +{ + ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc; + EFI_CONFIGURATION_TABLE *ConfigurationTable; + MP_INFORMATION_HOB_DATA *MpInformationHobData; + EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange; + EFI_STATUS Status; + EFI_HANDLE DispatchHandle; + UINT32 MpInfoSize; + UINTN Index; + UINTN ArraySize; + VOID *HobStart; + + ASSERT (SystemTable !=3D NULL); + mMmst =3D SystemTable; + + // publish the MM config protocol so the MM core can register its entry = point + Status =3D mMmst->MmInstallProtocolInterface (&mMmCpuHandle, + &gEfiMmConfigurationProtocol= Guid, + EFI_NATIVE_INTERFACE, + &mMmConfig); + if (EFI_ERROR(Status)) { + return Status; + } + + // publish the MM CPU save state protocol + Status =3D mMmst->MmInstallProtocolInterface (&mMmCpuHandle, + &gEfiMmCpuProtocolGuid, EFI_NATIVE_INTERFACE, &mMmCpuState); + if (EFI_ERROR(Status)) { + return Status; + } + + // register the root MMI handler + Status =3D mMmst->MmiHandlerRegister (PiMmCpuTpFwRootMmiHandler, + NULL, + &DispatchHandle); + if (EFI_ERROR(Status)) { + return Status; + } + + // Retrieve the Hoblist from the MMST to extract the details of the NS + // communication buffer that has been reserved by S-EL1/EL3 + ConfigurationTable =3D mMmst->MmConfigurationTable; + for (Index =3D 0; Index < mMmst->NumberOfTableEntries; Index++) { + if (CompareGuid (&gEfiHobListGuid, &(ConfigurationTable[Index].VendorG= uid))) { + break; + } + } + + // Bail out if the Hoblist could not be found + // TODO: This could also mean that + // the normal world will never interact synchronously with the MM enviro= nment + if (Index >=3D mMmst->NumberOfTableEntries) { + DEBUG ((DEBUG_INFO, "Hoblist not found - 0x%x\n", Index)); + return EFI_OUT_OF_RESOURCES; + } + + HobStart =3D ConfigurationTable[Index].VendorTable; + + // + // Locate the HOB with the buffer to populate the entry point of this dr= iver + // + Status =3D GetGuidedHobData ( + HobStart, + &gEfiArmTfCpuDriverEpDescriptorGuid, + (VOID **) &CpuDriverEntryPointDesc); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "ArmTfCpuDriverEpDesc HOB data extraction failed -= 0x%x\n", Status)); + return Status; + } + + // Share the entry point of the CPU driver + DEBUG ((DEBUG_INFO, "Sharing Cpu Driver EP *0x%lx =3D 0x%lx\n", + (UINT64) CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr, + (UINT64) PiMmStandloneArmTfCpuDriverEntry)); + *(CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr) =3D PiMmStandloneArmTfCp= uDriverEntry; + + // Find the descriptor that contains the whereabouts of the buffer for + // communication with the Normal world. + Status =3D GetGuidedHobData ( + HobStart, + &gEfiStandaloneMmNonSecureBufferGuid, + (VOID **) &NsCommBufMmramRange); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_INFO, "NsCommBufMmramRange HOB data extraction failed - = 0x%x\n", Status)); + return Status; + } + + DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINT64) Ns= CommBufMmramRange->PhysicalStart)); + DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINT64) NsC= ommBufMmramRange->PhysicalSize)); + + CopyMem (&mNsCommBuffer, NsCommBufMmramRange, sizeof(EFI_MMRAM_DESCRIPTO= R)); + DEBUG ((DEBUG_INFO, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer.C= puStart, mNsCommBuffer.PhysicalSize)); + + // + // Extract the MP information from the Hoblist + // + Status =3D GetGuidedHobData (HobStart, + &gMpInformationHobGuid, + (VOID **) &MpInformationHobData); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "MpInformationHob extraction failed - 0x%x\n", Sta= tus)); + return Status; + } + + // + // Allocate memory for the MP information and copy over the MP informati= on + // passed by Trusted Firmware. Use the number of processors passed in th= e HOB + // to copy the processor information + // + MpInfoSize =3D sizeof (MP_INFORMATION_HOB_DATA) + + (sizeof (EFI_PROCESSOR_INFORMATION) * + MpInformationHobData->NumberOfProcessors); + Status =3D mMmst->MmAllocatePool (EfiRuntimeServicesData, + MpInfoSize, + (void **) &mMpInformationHobData); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "mMpInformationHobData mem alloc failed - 0x%x\n",= Status)); + return Status; + } + + CopyMem (mMpInformationHobData, MpInformationHobData, MpInfoSize); + + // Print MP information + DEBUG ((DEBUG_INFO, "mMpInformationHobData: 0x%016lx - 0x%lx\n", + mMpInformationHobData->NumberOfProcessors, + mMpInformationHobData->NumberOfEnabledProcessors)); + for (Index =3D 0; Index < mMpInformationHobData->NumberOfProcessors; Ind= ex++) { + DEBUG ((DEBUG_INFO, "mMpInformationHobData[0x%lx]: %d, %d, %d\n", + mMpInformationHobData->ProcessorInfoBuffer[Index].ProcessorId, + mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Pac= kage, + mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Cor= e, + mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Thr= ead)); + } + + // + // Allocate memory for a table to hold pointers to a + // EFI_MM_COMMUNICATE_HEADER for each CPU + // + ArraySize =3D sizeof (EFI_MM_COMMUNICATE_HEADER *) * + mMpInformationHobData->NumberOfEnabledProcessors; + Status =3D mMmst->MmAllocatePool (EfiRuntimeServicesData, + ArraySize, + (VOID **) &PerCpuGuidedEventContext); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "PerCpuGuidedEventContext mem alloc failed - 0x%x\= n", Status)); + return Status; + } + return Status; +} diff --git a/StandaloneMmPkg/Drivers/CpuMm/Arm/PiMmStandloneArmTfCpuDriver.= h b/StandaloneMmPkg/Drivers/CpuMm/Arm/PiMmStandloneArmTfCpuDriver.h new file mode 100644 index 0000000000..17cefd171c --- /dev/null +++ b/StandaloneMmPkg/Drivers/CpuMm/Arm/PiMmStandloneArmTfCpuDriver.h @@ -0,0 +1,89 @@ +/** @file + Private header with declarations and definitions specific to the MM Stan= dalone + CPU driver + + Copyright (c) 2017, ARM Limited. All rights reserved. + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ + +#ifndef _ARM_TF_CPU_DRIVER_H_ +#define _ARM_TF_CPU_DRIVER_H_ + +#include +#include +#include +#include + +// +// Common declarations and definitions +// +#define EVENT_ID_MM_COMMUNICATE_SMC 0x10 + +// +// CPU driver initialization specific declarations +// +extern EFI_MM_SYSTEM_TABLE *mMmst; + +// +// CPU State Save protocol specific declarations +// +extern EFI_MM_CPU_PROTOCOL mMmCpuState; + +EFI_STATUS +EFIAPI +MmReadSaveState ( + IN CONST EFI_MM_CPU_PROTOCOL *This, + IN UINTN Width, + IN EFI_MM_SAVE_STATE_REGISTER Register, + IN UINTN CpuIndex, + OUT VOID *Buffer + ); + +EFI_STATUS +EFIAPI +MmWriteSaveState ( + IN CONST EFI_MM_CPU_PROTOCOL *This, + IN UINTN Width, + IN EFI_MM_SAVE_STATE_REGISTER Register, + IN UINTN CpuIndex, + IN CONST VOID *Buffer + ); + +// +// MM event handling specific declarations +// +extern EFI_MM_COMMUNICATE_HEADER **PerCpuGuidedEventContext; +extern EFI_MMRAM_DESCRIPTOR mNsCommBuffer; +extern MP_INFORMATION_HOB_DATA *mMpInformationHobData; +extern EFI_MM_CONFIGURATION_PROTOCOL mMmConfig; + +EFI_STATUS +PiMmStandloneArmTfCpuDriverEntry ( + IN UINTN EventId, + IN UINTN CpuNumber, + IN UINTN NsCommBufferAddr + ); + +EFI_STATUS +EFIAPI +PiMmCpuTpFwRootMmiHandler ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *Context, OPTIONAL + IN OUT VOID *CommBuffer, OPTIONAL + IN OUT UINTN *CommBufferSize OPTIONAL + ); + +EFI_STATUS _PiMmStandloneArmTfCpuDriverEntry ( + IN UINTN EventId, + IN UINTN CpuNumber, + IN UINTN NsCommBufferAddr + ); + +#endif diff --git a/StandaloneMmPkg/Drivers/CpuMm/Arm/PiMmStandloneArmTfCpuDriver.= inf b/StandaloneMmPkg/Drivers/CpuMm/Arm/PiMmStandloneArmTfCpuDriver.inf new file mode 100644 index 0000000000..baf6d957bb --- /dev/null +++ b/StandaloneMmPkg/Drivers/CpuMm/Arm/PiMmStandloneArmTfCpuDriver.inf @@ -0,0 +1,60 @@ +#/** @file +# +# Standalone MM CPU driver for ARM Standard Platforms +# +# Copyright (c) 2009, Apple Inc. All rights reserved.
+# Copyright (c) 2016 HP Development Company, L.P. +# Copyright (c) 2017, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# +#**/ + +[Defines] + INF_VERSION =3D 0x0001001A + BASE_NAME =3D PiMmStandloneArmTfCpuDriver + FILE_GUID =3D 58F7A62B-6280-42A7-BC38-10535A64A92C + MODULE_TYPE =3D MM_STANDALONE + VERSION_STRING =3D 1.0 + PI_SPECIFICATION_VERSION =3D 0x00010032 + ENTRY_POINT =3D PiMmStandloneArmTfCpuDriverInitialize + +[Sources] + Init.c + EventHandle.c + StateSave.c + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec + +[LibraryClasses] + ArmLib + ArmSvcLib + BaseMemoryLib + DebugLib + HobLib + StandaloneMmDriverEntryPoint + +[Protocols] + gEfiMmConfigurationProtocolGuid # PROTOCOL ALWAYS= _PRODUCED + gEfiMmCpuProtocolGuid # PROTOCOL ALWAYS= _PRODUCED + +[Guids] + gEfiHobListGuid + gEfiMmPeiMmramMemoryReserveGuid + gZeroGuid + gMpInformationHobGuid + gEfiStandaloneMmNonSecureBufferGuid + gEfiArmTfCpuDriverEpDescriptorGuid + +[Depex] + TRUE diff --git a/StandaloneMmPkg/Drivers/CpuMm/Arm/StateSave.c b/StandaloneMmPk= g/Drivers/CpuMm/Arm/StateSave.c new file mode 100644 index 0000000000..c5155e1b31 --- /dev/null +++ b/StandaloneMmPkg/Drivers/CpuMm/Arm/StateSave.c @@ -0,0 +1,51 @@ +/** @file + + Copyright (c) 2016 HP Development Company, L.P. + Copyright (c) 2016-2017, ARM Limited. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ + +#include +#include +#include + +#include "PiMmStandloneArmTfCpuDriver.h" + +EFI_MM_CPU_PROTOCOL mMmCpuState =3D { + MmReadSaveState, + MmWriteSaveState +}; + +EFI_STATUS +EFIAPI +MmReadSaveState( + IN CONST EFI_MM_CPU_PROTOCOL *This, + IN UINTN Width, + IN EFI_MM_SAVE_STATE_REGISTER Register, + IN UINTN CpuIndex, + OUT VOID *Buffer + ) { + // todo: implement + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +MmWriteSaveState( + IN CONST EFI_MM_CPU_PROTOCOL *This, + IN UINTN Width, + IN EFI_MM_SAVE_STATE_REGISTER Register, + IN UINTN CpuIndex, + IN CONST VOID *Buffer + ) { + // todo: implement + return EFI_UNSUPPORTED; +} diff --git a/StandaloneMmPkg/Include/Guid/MpInformation.h b/StandaloneMmPkg= /Include/Guid/MpInformation.h new file mode 100644 index 0000000000..4e9a3c04ec --- /dev/null +++ b/StandaloneMmPkg/Include/Guid/MpInformation.h @@ -0,0 +1,41 @@ +/** @file + EFI MP information protocol provides a lightweight MP_SERVICES_PROTOCOL. + + MP information protocol only provides static information of MP processor. + + Copyright (c) 2009, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2017, ARM Limited. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. + +**/ + +#ifndef _MP_INFORMATION_H_ +#define _MP_INFORMATION_H_ + +#include +#include +#include + +#define MP_INFORMATION_GUID \ + { \ + 0xba33f15d, 0x4000, 0x45c1, {0x8e, 0x88, 0xf9, 0x16, 0x92, 0xd4, 0x57,= 0xe3} \ + } + +#pragma pack(1) +typedef struct { + UINT64 NumberOfProcessors; + UINT64 NumberOfEnabledProcessors; + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer[]; +} MP_INFORMATION_HOB_DATA; +#pragma pack() + +extern EFI_GUID gMpInformationHobGuid; + +#endif --=20 2.16.2 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel