3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4 Copyright (c) 2016 HP Development Company, L.P.
5 Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
7 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <Pi/PiMmCis.h>
13 #include <Library/Arm/StandaloneMmCoreEntryPoint.h>
14 #include <Library/DebugLib.h>
15 #include <Library/ArmSvcLib.h>
16 #include <Library/ArmLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/HobLib.h>
20 #include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT
22 #include <Guid/ZeroGuid.h>
23 #include <Guid/MmramMemoryReserve.h>
25 #include "StandaloneMmCpu.h"
27 // GUID to identify HOB with whereabouts of communication buffer with Normal
29 extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid
;
31 // GUID to identify HOB where the entry point of this CPU driver will be
32 // populated to allow the entry point driver to invoke it upon receipt of an
34 extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid
;
37 // Private copy of the MM system table for future use
39 EFI_MM_SYSTEM_TABLE
*mMmst
= NULL
;
42 // Globals used to initialize the protocol
44 STATIC EFI_HANDLE mMmCpuHandle
= NULL
;
46 /** Returns the HOB data for the matching HOB GUID.
48 @param [in] HobList Pointer to the HOB list.
49 @param [in] HobGuid The GUID for the HOB.
50 @param [out] HobData Pointer to the HOB data.
52 @retval EFI_SUCCESS The function completed successfully.
53 @retval EFI_INVALID_PARAMETER Invalid parameter.
54 @retval EFI_NOT_FOUND Could not find HOB with matching GUID.
59 IN CONST EFI_GUID
*HobGuid
,
63 EFI_HOB_GUID_TYPE
*Hob
;
65 if ((HobList
== NULL
) || (HobGuid
== NULL
) || (HobData
== NULL
)) {
66 return EFI_INVALID_PARAMETER
;
69 Hob
= GetNextGuidHob (HobGuid
, HobList
);
74 *HobData
= GET_GUID_HOB_DATA (Hob
);
75 if (*HobData
== NULL
) {
82 /** Entry point for the Standalone MM CPU driver.
84 @param [in] ImageHandle Unused. Not actual image handle.
85 @param [in] SystemTable Pointer to MM System table.
87 @retval EFI_SUCCESS The function completed successfully.
88 @retval EFI_INVALID_PARAMETER Invalid parameter.
89 @retval EFI_OUT_OF_RESOURCES Out of resources.
90 @retval EFI_NOT_FOUND Failed to find the HOB for the CPU
91 driver endpoint descriptor.
94 StandaloneMmCpuInitialize (
95 IN EFI_HANDLE ImageHandle
, // not actual imagehandle
96 IN EFI_MM_SYSTEM_TABLE
*SystemTable
// not actual systemtable
99 ARM_TF_CPU_DRIVER_EP_DESCRIPTOR
*CpuDriverEntryPointDesc
;
100 EFI_CONFIGURATION_TABLE
*ConfigurationTable
;
101 MP_INFORMATION_HOB_DATA
*MpInformationHobData
;
102 EFI_MMRAM_DESCRIPTOR
*NsCommBufMmramRange
;
104 EFI_HANDLE DispatchHandle
;
109 EFI_MMRAM_HOB_DESCRIPTOR_BLOCK
*MmramRangesHob
;
111 ASSERT (SystemTable
!= NULL
);
114 // publish the MM config protocol so the MM core can register its entry point
115 Status
= mMmst
->MmInstallProtocolInterface (
117 &gEfiMmConfigurationProtocolGuid
,
118 EFI_NATIVE_INTERFACE
,
121 if (EFI_ERROR (Status
)) {
125 // register the root MMI handler
126 Status
= mMmst
->MmiHandlerRegister (
127 PiMmCpuTpFwRootMmiHandler
,
131 if (EFI_ERROR (Status
)) {
135 // Retrieve the Hoblist from the MMST to extract the details of the NS
136 // communication buffer that has been reserved by S-EL1/EL3
137 ConfigurationTable
= mMmst
->MmConfigurationTable
;
138 for (Index
= 0; Index
< mMmst
->NumberOfTableEntries
; Index
++) {
139 if (CompareGuid (&gEfiHobListGuid
, &(ConfigurationTable
[Index
].VendorGuid
))) {
144 // Bail out if the Hoblist could not be found
145 if (Index
>= mMmst
->NumberOfTableEntries
) {
146 DEBUG ((DEBUG_ERROR
, "Hoblist not found - 0x%x\n", Index
));
147 return EFI_OUT_OF_RESOURCES
;
150 HobStart
= ConfigurationTable
[Index
].VendorTable
;
153 // Locate the HOB with the buffer to populate the entry point of this driver
155 Status
= GetGuidedHobData (
157 &gEfiArmTfCpuDriverEpDescriptorGuid
,
158 (VOID
**)&CpuDriverEntryPointDesc
160 if (EFI_ERROR (Status
)) {
161 DEBUG ((DEBUG_ERROR
, "ArmTfCpuDriverEpDesc HOB data extraction failed - 0x%x\n", Status
));
165 // Share the entry point of the CPU driver
168 "Sharing Cpu Driver EP *0x%lx = 0x%lx\n",
169 (UINTN
)CpuDriverEntryPointDesc
->ArmTfCpuDriverEpPtr
,
170 (UINTN
)PiMmStandaloneArmTfCpuDriverEntry
172 *(CpuDriverEntryPointDesc
->ArmTfCpuDriverEpPtr
) = PiMmStandaloneArmTfCpuDriverEntry
;
174 // Find the descriptor that contains the whereabouts of the buffer for
175 // communication with the Normal world.
176 Status
= GetGuidedHobData (
178 &gEfiStandaloneMmNonSecureBufferGuid
,
179 (VOID
**)&NsCommBufMmramRange
181 if (EFI_ERROR (Status
)) {
182 DEBUG ((DEBUG_ERROR
, "NsCommBufMmramRange HOB data extraction failed - 0x%x\n", Status
));
186 DEBUG ((DEBUG_INFO
, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINTN
)NsCommBufMmramRange
->PhysicalStart
));
187 DEBUG ((DEBUG_INFO
, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINTN
)NsCommBufMmramRange
->PhysicalSize
));
189 CopyMem (&mNsCommBuffer
, NsCommBufMmramRange
, sizeof (EFI_MMRAM_DESCRIPTOR
));
190 DEBUG ((DEBUG_INFO
, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer
.CpuStart
, mNsCommBuffer
.PhysicalSize
));
192 Status
= GetGuidedHobData (
194 &gEfiMmPeiMmramMemoryReserveGuid
,
195 (VOID
**)&MmramRangesHob
197 if (EFI_ERROR (Status
)) {
198 DEBUG ((DEBUG_ERROR
, "MmramRangesHob data extraction failed - 0x%x\n", Status
));
203 // As CreateHobListFromBootInfo(), the base and size of buffer shared with
204 // privileged Secure world software is in second one.
208 &MmramRangesHob
->Descriptor
[0] + 1,
209 sizeof (EFI_MMRAM_DESCRIPTOR
)
213 // Extract the MP information from the Hoblist
215 Status
= GetGuidedHobData (
217 &gMpInformationHobGuid
,
218 (VOID
**)&MpInformationHobData
220 if (EFI_ERROR (Status
)) {
221 DEBUG ((DEBUG_ERROR
, "MpInformationHob extraction failed - 0x%x\n", Status
));
226 // Allocate memory for the MP information and copy over the MP information
227 // passed by Trusted Firmware. Use the number of processors passed in the HOB
228 // to copy the processor information
230 MpInfoSize
= sizeof (MP_INFORMATION_HOB_DATA
) +
231 (sizeof (EFI_PROCESSOR_INFORMATION
) *
232 MpInformationHobData
->NumberOfProcessors
);
233 Status
= mMmst
->MmAllocatePool (
234 EfiRuntimeServicesData
,
236 (VOID
**)&mMpInformationHobData
238 if (EFI_ERROR (Status
)) {
239 DEBUG ((DEBUG_ERROR
, "mMpInformationHobData mem alloc failed - 0x%x\n", Status
));
243 CopyMem (mMpInformationHobData
, MpInformationHobData
, MpInfoSize
);
245 // Print MP information
248 "mMpInformationHobData: 0x%016lx - 0x%lx\n",
249 mMpInformationHobData
->NumberOfProcessors
,
250 mMpInformationHobData
->NumberOfEnabledProcessors
252 for (Index
= 0; Index
< mMpInformationHobData
->NumberOfProcessors
; Index
++) {
255 "mMpInformationHobData[0x%lx]: %d, %d, %d\n",
256 mMpInformationHobData
->ProcessorInfoBuffer
[Index
].ProcessorId
,
257 mMpInformationHobData
->ProcessorInfoBuffer
[Index
].Location
.Package
,
258 mMpInformationHobData
->ProcessorInfoBuffer
[Index
].Location
.Core
,
259 mMpInformationHobData
->ProcessorInfoBuffer
[Index
].Location
.Thread
264 // Allocate memory for a table to hold pointers to a
265 // EFI_MM_COMMUNICATE_HEADER for each CPU
267 ArraySize
= sizeof (EFI_MM_COMMUNICATE_HEADER
*) *
268 mMpInformationHobData
->NumberOfEnabledProcessors
;
269 Status
= mMmst
->MmAllocatePool (
270 EfiRuntimeServicesData
,
272 (VOID
**)&PerCpuGuidedEventContext
274 if (EFI_ERROR (Status
)) {
275 DEBUG ((DEBUG_ERROR
, "PerCpuGuidedEventContext mem alloc failed - 0x%x\n", Status
));