3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4 Copyright (c) 2016 HP Development Company, L.P.
5 Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Pi/PiMmCis.h>
19 #include <Library/AArch64/StandaloneMmCoreEntryPoint.h>
20 #include <Library/DebugLib.h>
21 #include <Library/ArmSvcLib.h>
22 #include <Library/ArmLib.h>
23 #include <Library/BaseMemoryLib.h>
24 #include <Library/HobLib.h>
26 #include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT
28 #include <Guid/ZeroGuid.h>
29 #include <Guid/MmramMemoryReserve.h>
32 #include "StandaloneMmCpu.h"
34 // GUID to identify HOB with whereabouts of communication buffer with Normal
36 extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid
;
38 // GUID to identify HOB where the entry point of this CPU driver will be
39 // populated to allow the entry point driver to invoke it upon receipt of an
41 extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid
;
44 // Private copy of the MM system table for future use
46 EFI_MM_SYSTEM_TABLE
*mMmst
= NULL
;
49 // Globals used to initialize the protocol
51 STATIC EFI_HANDLE mMmCpuHandle
= NULL
;
56 IN CONST EFI_GUID
*HobGuid
,
60 EFI_HOB_GUID_TYPE
*Hob
;
62 if (!HobList
|| !HobGuid
|| !HobData
)
63 return EFI_INVALID_PARAMETER
;
65 Hob
= GetNextGuidHob (HobGuid
, HobList
);
69 *HobData
= GET_GUID_HOB_DATA (Hob
);
77 StandloneMmCpuInitialize (
78 IN EFI_HANDLE ImageHandle
, // not actual imagehandle
79 IN EFI_MM_SYSTEM_TABLE
*SystemTable
// not actual systemtable
82 ARM_TF_CPU_DRIVER_EP_DESCRIPTOR
*CpuDriverEntryPointDesc
;
83 EFI_CONFIGURATION_TABLE
*ConfigurationTable
;
84 MP_INFORMATION_HOB_DATA
*MpInformationHobData
;
85 EFI_MMRAM_DESCRIPTOR
*NsCommBufMmramRange
;
87 EFI_HANDLE DispatchHandle
;
93 ASSERT (SystemTable
!= NULL
);
96 // publish the MM config protocol so the MM core can register its entry point
97 Status
= mMmst
->MmInstallProtocolInterface (
99 &gEfiMmConfigurationProtocolGuid
,
100 EFI_NATIVE_INTERFACE
,
103 if (EFI_ERROR (Status
)) {
107 // register the root MMI handler
108 Status
= mMmst
->MmiHandlerRegister (
109 PiMmCpuTpFwRootMmiHandler
,
113 if (EFI_ERROR (Status
)) {
117 // Retrieve the Hoblist from the MMST to extract the details of the NS
118 // communication buffer that has been reserved by S-EL1/EL3
119 ConfigurationTable
= mMmst
->MmConfigurationTable
;
120 for (Index
= 0; Index
< mMmst
->NumberOfTableEntries
; Index
++) {
121 if (CompareGuid (&gEfiHobListGuid
, &(ConfigurationTable
[Index
].VendorGuid
))) {
126 // Bail out if the Hoblist could not be found
127 if (Index
>= mMmst
->NumberOfTableEntries
) {
128 DEBUG ((DEBUG_INFO
, "Hoblist not found - 0x%x\n", Index
));
129 return EFI_OUT_OF_RESOURCES
;
132 HobStart
= ConfigurationTable
[Index
].VendorTable
;
135 // Locate the HOB with the buffer to populate the entry point of this driver
137 Status
= GetGuidedHobData (
139 &gEfiArmTfCpuDriverEpDescriptorGuid
,
140 (VOID
**) &CpuDriverEntryPointDesc
142 if (EFI_ERROR (Status
)) {
143 DEBUG ((DEBUG_INFO
, "ArmTfCpuDriverEpDesc HOB data extraction failed - 0x%x\n", Status
));
147 // Share the entry point of the CPU driver
148 DEBUG ((DEBUG_INFO
, "Sharing Cpu Driver EP *0x%lx = 0x%lx\n",
149 (UINT64
) CpuDriverEntryPointDesc
->ArmTfCpuDriverEpPtr
,
150 (UINT64
) PiMmStandloneArmTfCpuDriverEntry
));
151 *(CpuDriverEntryPointDesc
->ArmTfCpuDriverEpPtr
) = PiMmStandloneArmTfCpuDriverEntry
;
153 // Find the descriptor that contains the whereabouts of the buffer for
154 // communication with the Normal world.
155 Status
= GetGuidedHobData (
157 &gEfiStandaloneMmNonSecureBufferGuid
,
158 (VOID
**) &NsCommBufMmramRange
160 if (EFI_ERROR (Status
)) {
161 DEBUG ((DEBUG_INFO
, "NsCommBufMmramRange HOB data extraction failed - 0x%x\n", Status
));
165 DEBUG ((DEBUG_INFO
, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINT64
) NsCommBufMmramRange
->PhysicalStart
));
166 DEBUG ((DEBUG_INFO
, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINT64
) NsCommBufMmramRange
->PhysicalSize
));
168 CopyMem (&mNsCommBuffer
, NsCommBufMmramRange
, sizeof(EFI_MMRAM_DESCRIPTOR
));
169 DEBUG ((DEBUG_INFO
, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer
.CpuStart
, mNsCommBuffer
.PhysicalSize
));
172 // Extract the MP information from the Hoblist
174 Status
= GetGuidedHobData (
176 &gMpInformationHobGuid
,
177 (VOID
**) &MpInformationHobData
179 if (EFI_ERROR (Status
)) {
180 DEBUG ((DEBUG_INFO
, "MpInformationHob extraction failed - 0x%x\n", Status
));
185 // Allocate memory for the MP information and copy over the MP information
186 // passed by Trusted Firmware. Use the number of processors passed in the HOB
187 // to copy the processor information
189 MpInfoSize
= sizeof (MP_INFORMATION_HOB_DATA
) +
190 (sizeof (EFI_PROCESSOR_INFORMATION
) *
191 MpInformationHobData
->NumberOfProcessors
);
192 Status
= mMmst
->MmAllocatePool (
193 EfiRuntimeServicesData
,
195 (VOID
**) &mMpInformationHobData
197 if (EFI_ERROR (Status
)) {
198 DEBUG ((DEBUG_INFO
, "mMpInformationHobData mem alloc failed - 0x%x\n", Status
));
202 CopyMem (mMpInformationHobData
, MpInformationHobData
, MpInfoSize
);
204 // Print MP information
205 DEBUG ((DEBUG_INFO
, "mMpInformationHobData: 0x%016lx - 0x%lx\n",
206 mMpInformationHobData
->NumberOfProcessors
,
207 mMpInformationHobData
->NumberOfEnabledProcessors
));
208 for (Index
= 0; Index
< mMpInformationHobData
->NumberOfProcessors
; Index
++) {
209 DEBUG ((DEBUG_INFO
, "mMpInformationHobData[0x%lx]: %d, %d, %d\n",
210 mMpInformationHobData
->ProcessorInfoBuffer
[Index
].ProcessorId
,
211 mMpInformationHobData
->ProcessorInfoBuffer
[Index
].Location
.Package
,
212 mMpInformationHobData
->ProcessorInfoBuffer
[Index
].Location
.Core
,
213 mMpInformationHobData
->ProcessorInfoBuffer
[Index
].Location
.Thread
));
217 // Allocate memory for a table to hold pointers to a
218 // EFI_MM_COMMUNICATE_HEADER for each CPU
220 ArraySize
= sizeof (EFI_MM_COMMUNICATE_HEADER
*) *
221 mMpInformationHobData
->NumberOfEnabledProcessors
;
222 Status
= mMmst
->MmAllocatePool (
223 EfiRuntimeServicesData
,
225 (VOID
**) &PerCpuGuidedEventContext
227 if (EFI_ERROR (Status
)) {
228 DEBUG ((DEBUG_INFO
, "PerCpuGuidedEventContext mem alloc failed - 0x%x\n", Status
));