]> git.proxmox.com Git - mirror_edk2.git/blob - StandaloneMmPkg/Drivers/StandaloneMmCpu/AArch64/StandaloneMmCpu.c
StandaloneMmPkg/StandaloneMmCpu: fix typo Standlone -> Standalone
[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 - 2018, ARM Limited. All rights reserved.
6
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
11
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.
14
15 **/
16
17 #include <Base.h>
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>
25
26 #include <Protocol/DebugSupport.h> // for EFI_SYSTEM_CONTEXT
27
28 #include <Guid/ZeroGuid.h>
29 #include <Guid/MmramMemoryReserve.h>
30
31
32 #include "StandaloneMmCpu.h"
33
34 // GUID to identify HOB with whereabouts of communication buffer with Normal
35 // World
36 extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;
37
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
40 // event
41 extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;
42
43 //
44 // Private copy of the MM system table for future use
45 //
46 EFI_MM_SYSTEM_TABLE *mMmst = NULL;
47
48 //
49 // Globals used to initialize the protocol
50 //
51 STATIC EFI_HANDLE mMmCpuHandle = NULL;
52
53 EFI_STATUS
54 GetGuidedHobData (
55 IN VOID *HobList,
56 IN CONST EFI_GUID *HobGuid,
57 OUT VOID **HobData
58 )
59 {
60 EFI_HOB_GUID_TYPE *Hob;
61
62 if (!HobList || !HobGuid || !HobData)
63 return EFI_INVALID_PARAMETER;
64
65 Hob = GetNextGuidHob (HobGuid, HobList);
66 if (!Hob)
67 return EFI_NOT_FOUND;
68
69 *HobData = GET_GUID_HOB_DATA (Hob);
70 if (!HobData)
71 return EFI_NOT_FOUND;
72
73 return EFI_SUCCESS;
74 }
75
76 EFI_STATUS
77 StandaloneMmCpuInitialize (
78 IN EFI_HANDLE ImageHandle, // not actual imagehandle
79 IN EFI_MM_SYSTEM_TABLE *SystemTable // not actual systemtable
80 )
81 {
82 ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;
83 EFI_CONFIGURATION_TABLE *ConfigurationTable;
84 MP_INFORMATION_HOB_DATA *MpInformationHobData;
85 EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;
86 EFI_STATUS Status;
87 EFI_HANDLE DispatchHandle;
88 UINT32 MpInfoSize;
89 UINTN Index;
90 UINTN ArraySize;
91 VOID *HobStart;
92
93 ASSERT (SystemTable != NULL);
94 mMmst = SystemTable;
95
96 // publish the MM config protocol so the MM core can register its entry point
97 Status = mMmst->MmInstallProtocolInterface (
98 &mMmCpuHandle,
99 &gEfiMmConfigurationProtocolGuid,
100 EFI_NATIVE_INTERFACE,
101 &mMmConfig
102 );
103 if (EFI_ERROR (Status)) {
104 return Status;
105 }
106
107 // register the root MMI handler
108 Status = mMmst->MmiHandlerRegister (
109 PiMmCpuTpFwRootMmiHandler,
110 NULL,
111 &DispatchHandle
112 );
113 if (EFI_ERROR (Status)) {
114 return Status;
115 }
116
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))) {
122 break;
123 }
124 }
125
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;
130 }
131
132 HobStart = ConfigurationTable[Index].VendorTable;
133
134 //
135 // Locate the HOB with the buffer to populate the entry point of this driver
136 //
137 Status = GetGuidedHobData (
138 HobStart,
139 &gEfiArmTfCpuDriverEpDescriptorGuid,
140 (VOID **) &CpuDriverEntryPointDesc
141 );
142 if (EFI_ERROR (Status)) {
143 DEBUG ((DEBUG_INFO, "ArmTfCpuDriverEpDesc HOB data extraction failed - 0x%x\n", Status));
144 return Status;
145 }
146
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) PiMmStandaloneArmTfCpuDriverEntry));
151 *(CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr) = PiMmStandaloneArmTfCpuDriverEntry;
152
153 // Find the descriptor that contains the whereabouts of the buffer for
154 // communication with the Normal world.
155 Status = GetGuidedHobData (
156 HobStart,
157 &gEfiStandaloneMmNonSecureBufferGuid,
158 (VOID **) &NsCommBufMmramRange
159 );
160 if (EFI_ERROR (Status)) {
161 DEBUG ((DEBUG_INFO, "NsCommBufMmramRange HOB data extraction failed - 0x%x\n", Status));
162 return Status;
163 }
164
165 DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalStart - 0x%lx\n", (UINT64) NsCommBufMmramRange->PhysicalStart));
166 DEBUG ((DEBUG_INFO, "mNsCommBuffer.PhysicalSize - 0x%lx\n", (UINT64) NsCommBufMmramRange->PhysicalSize));
167
168 CopyMem (&mNsCommBuffer, NsCommBufMmramRange, sizeof(EFI_MMRAM_DESCRIPTOR));
169 DEBUG ((DEBUG_INFO, "mNsCommBuffer: 0x%016lx - 0x%lx\n", mNsCommBuffer.CpuStart, mNsCommBuffer.PhysicalSize));
170
171 //
172 // Extract the MP information from the Hoblist
173 //
174 Status = GetGuidedHobData (
175 HobStart,
176 &gMpInformationHobGuid,
177 (VOID **) &MpInformationHobData
178 );
179 if (EFI_ERROR (Status)) {
180 DEBUG ((DEBUG_INFO, "MpInformationHob extraction failed - 0x%x\n", Status));
181 return Status;
182 }
183
184 //
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
188 //
189 MpInfoSize = sizeof (MP_INFORMATION_HOB_DATA) +
190 (sizeof (EFI_PROCESSOR_INFORMATION) *
191 MpInformationHobData->NumberOfProcessors);
192 Status = mMmst->MmAllocatePool (
193 EfiRuntimeServicesData,
194 MpInfoSize,
195 (VOID **) &mMpInformationHobData
196 );
197 if (EFI_ERROR (Status)) {
198 DEBUG ((DEBUG_INFO, "mMpInformationHobData mem alloc failed - 0x%x\n", Status));
199 return Status;
200 }
201
202 CopyMem (mMpInformationHobData, MpInformationHobData, MpInfoSize);
203
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));
214 }
215
216 //
217 // Allocate memory for a table to hold pointers to a
218 // EFI_MM_COMMUNICATE_HEADER for each CPU
219 //
220 ArraySize = sizeof (EFI_MM_COMMUNICATE_HEADER *) *
221 mMpInformationHobData->NumberOfEnabledProcessors;
222 Status = mMmst->MmAllocatePool (
223 EfiRuntimeServicesData,
224 ArraySize,
225 (VOID **) &PerCpuGuidedEventContext
226 );
227 if (EFI_ERROR (Status)) {
228 DEBUG ((DEBUG_INFO, "PerCpuGuidedEventContext mem alloc failed - 0x%x\n", Status));
229 return Status;
230 }
231 return Status;
232 }