]> git.proxmox.com Git - mirror_edk2.git/blob - StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c
9e496096018da80aa8e7fe84721b1fa757a0b3ce
[mirror_edk2.git] / StandaloneMmPkg / Drivers / StandaloneMmCpu / AArch64 / StandaloneMmCpu.c
1 /** @file
2
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.
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include <Base.h>
12 #include <Pi/PiMmCis.h>
13 #include <Library/AArch64/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>
19
20 #include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT
21
22 #include <Guid/ZeroGuid.h>
23 #include <Guid/MmramMemoryReserve.h>
24
25
26 #include "StandaloneMmCpu.h"
27
28 // GUID to identify HOB with whereabouts of communication buffer with Normal
29 // World
30 extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;
31
32 // GUID to identify HOB where the entry point of this CPU driver will be
33 // populated to allow the entry point driver to invoke it upon receipt of an
34 // event
35 extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;
36
37 //
38 // Private copy of the MM system table for future use
39 //
40 EFI_MM_SYSTEM_TABLE *mMmst = NULL;
41
42 //
43 // Globals used to initialize the protocol
44 //
45 STATIC EFI_HANDLE mMmCpuHandle = NULL;
46
47 EFI_STATUS
48 GetGuidedHobData (
49 IN VOID *HobList,
50 IN CONST EFI_GUID *HobGuid,
51 OUT VOID **HobData
52 )
53 {
54 EFI_HOB_GUID_TYPE *Hob;
55
56 if ((HobList == NULL) || (HobGuid == NULL) || (HobData == NULL)) {
57 return EFI_INVALID_PARAMETER;
58 }
59
60 Hob = GetNextGuidHob (HobGuid, HobList);
61 if (Hob == NULL) {
62 return EFI_NOT_FOUND;
63 }
64
65 *HobData = GET_GUID_HOB_DATA (Hob);
66 if (*HobData == NULL) {
67 return EFI_NOT_FOUND;
68 }
69
70 return EFI_SUCCESS;
71 }
72
73 EFI_STATUS
74 StandaloneMmCpuInitialize (
75 IN EFI_HANDLE ImageHandle, // not actual imagehandle
76 IN EFI_MM_SYSTEM_TABLE *SystemTable // not actual systemtable
77 )
78 {
79 ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;
80 EFI_CONFIGURATION_TABLE *ConfigurationTable;
81 MP_INFORMATION_HOB_DATA *MpInformationHobData;
82 EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;
83 EFI_STATUS Status;
84 EFI_HANDLE DispatchHandle;
85 UINT32 MpInfoSize;
86 UINTN Index;
87 UINTN ArraySize;
88 VOID *HobStart;
89
90 ASSERT (SystemTable != NULL);
91 mMmst = SystemTable;
92
93 // publish the MM config protocol so the MM core can register its entry point
94 Status = mMmst->MmInstallProtocolInterface (
95 &mMmCpuHandle,
96 &gEfiMmConfigurationProtocolGuid,
97 EFI_NATIVE_INTERFACE,
98 &mMmConfig
99 );
100 if (EFI_ERROR (Status)) {
101 return Status;
102 }
103
104 // register the root MMI handler
105 Status = mMmst->MmiHandlerRegister (
106 PiMmCpuTpFwRootMmiHandler,
107 NULL,
108 &DispatchHandle
109 );
110 if (EFI_ERROR (Status)) {
111 return Status;
112 }
113
114 // Retrieve the Hoblist from the MMST to extract the details of the NS
115 // communication buffer that has been reserved by S-EL1/EL3
116 ConfigurationTable = mMmst->MmConfigurationTable;
117 for (Index = 0; Index < mMmst->NumberOfTableEntries; Index++) {
118 if (CompareGuid (&gEfiHobListGuid, &(ConfigurationTable[Index].VendorGuid))) {
119 break;
120 }
121 }
122
123 // Bail out if the Hoblist could not be found
124 if (Index >= mMmst->NumberOfTableEntries) {
125 DEBUG ((DEBUG_INFO, "Hoblist not found - 0x%x\n", Index));
126 return EFI_OUT_OF_RESOURCES;
127 }
128
129 HobStart = ConfigurationTable[Index].VendorTable;
130
131 //
132 // Locate the HOB with the buffer to populate the entry point of this driver
133 //
134 Status = GetGuidedHobData (
135 HobStart,
136 &gEfiArmTfCpuDriverEpDescriptorGuid,
137 (VOID **) &CpuDriverEntryPointDesc
138 );
139 if (EFI_ERROR (Status)) {
140 DEBUG ((DEBUG_INFO, "ArmTfCpuDriverEpDesc HOB data extraction failed - 0x%x\n", Status));
141 return Status;
142 }
143
144 // Share the entry point of the CPU driver
145 DEBUG ((DEBUG_INFO, "Sharing Cpu Driver EP *0x%lx = 0x%lx\n",
146 (UINT64) CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr,
147 (UINT64) PiMmStandaloneArmTfCpuDriverEntry));
148 *(CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr) = PiMmStandaloneArmTfCpuDriverEntry;
149
150 // Find the descriptor that contains the whereabouts of the buffer for
151 // communication with the Normal world.
152 Status = GetGuidedHobData (
153 HobStart,
154 &gEfiStandaloneMmNonSecureBufferGuid,
155 (VOID **) &NsCommBufMmramRange
156 );
157 if (EFI_ERROR (Status)) {
158 DEBUG ((DEBUG_INFO, "NsCommBufMmramRange HOB data extraction failed - 0x%x\n", Status));
159 return Status;
160 }
161
162 DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINT64) NsCommBufMmramRange->PhysicalStart));
163 DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINT64) NsCommBufMmramRange->PhysicalSize));
164
165 CopyMem (&mNsCommBuffer, NsCommBufMmramRange, sizeof(EFI_MMRAM_DESCRIPTOR));
166 DEBUG ((DEBUG_INFO, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer.CpuStart, mNsCommBuffer.PhysicalSize));
167
168 //
169 // Extract the MP information from the Hoblist
170 //
171 Status = GetGuidedHobData (
172 HobStart,
173 &gMpInformationHobGuid,
174 (VOID **) &MpInformationHobData
175 );
176 if (EFI_ERROR (Status)) {
177 DEBUG ((DEBUG_INFO, "MpInformationHob extraction failed - 0x%x\n", Status));
178 return Status;
179 }
180
181 //
182 // Allocate memory for the MP information and copy over the MP information
183 // passed by Trusted Firmware. Use the number of processors passed in the HOB
184 // to copy the processor information
185 //
186 MpInfoSize = sizeof (MP_INFORMATION_HOB_DATA) +
187 (sizeof (EFI_PROCESSOR_INFORMATION) *
188 MpInformationHobData->NumberOfProcessors);
189 Status = mMmst->MmAllocatePool (
190 EfiRuntimeServicesData,
191 MpInfoSize,
192 (VOID **) &mMpInformationHobData
193 );
194 if (EFI_ERROR (Status)) {
195 DEBUG ((DEBUG_INFO, "mMpInformationHobData mem alloc failed - 0x%x\n", Status));
196 return Status;
197 }
198
199 CopyMem (mMpInformationHobData, MpInformationHobData, MpInfoSize);
200
201 // Print MP information
202 DEBUG ((DEBUG_INFO, "mMpInformationHobData: 0x%016lx - 0x%lx\n",
203 mMpInformationHobData->NumberOfProcessors,
204 mMpInformationHobData->NumberOfEnabledProcessors));
205 for (Index = 0; Index < mMpInformationHobData->NumberOfProcessors; Index++) {
206 DEBUG ((DEBUG_INFO, "mMpInformationHobData[0x%lx]: %d, %d, %d\n",
207 mMpInformationHobData->ProcessorInfoBuffer[Index].ProcessorId,
208 mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Package,
209 mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Core,
210 mMpInformationHobData->ProcessorInfoBuffer[Index].Location.Thread));
211 }
212
213 //
214 // Allocate memory for a table to hold pointers to a
215 // EFI_MM_COMMUNICATE_HEADER for each CPU
216 //
217 ArraySize = sizeof (EFI_MM_COMMUNICATE_HEADER *) *
218 mMpInformationHobData->NumberOfEnabledProcessors;
219 Status = mMmst->MmAllocatePool (
220 EfiRuntimeServicesData,
221 ArraySize,
222 (VOID **) &PerCpuGuidedEventContext
223 );
224 if (EFI_ERROR (Status)) {
225 DEBUG ((DEBUG_INFO, "PerCpuGuidedEventContext mem alloc failed - 0x%x\n", Status));
226 return Status;
227 }
228 return Status;
229 }