]> git.proxmox.com Git - mirror_edk2.git/blob - StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/CreateHobList.c
StandaloneMmPkg: Add an AArch64 specific entry point library.
[mirror_edk2.git] / StandaloneMmPkg / Library / StandaloneMmCoreEntryPoint / AArch64 / CreateHobList.c
1 /** @file
2 Creates HOB during Standalone MM Foundation entry point
3 on ARM platforms.
4
5 Copyright (c) 2017 - 2018, ARM Ltd. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16
17 #include <PiMm.h>
18
19 #include <PiPei.h>
20 #include <Guid/MmramMemoryReserve.h>
21 #include <Guid/MpInformation.h>
22
23 #include <Library/AArch64/StandaloneMmCoreEntryPoint.h>
24 #include <Library/ArmMmuLib.h>
25 #include <Library/ArmSvcLib.h>
26 #include <Library/DebugLib.h>
27 #include <Library/HobLib.h>
28 #include <Library/BaseLib.h>
29 #include <Library/BaseMemoryLib.h>
30 #include <Library/SerialPortLib.h>
31
32 #include <IndustryStandard/ArmStdSmc.h>
33
34 extern EFI_HOB_HANDOFF_INFO_TABLE*
35 HobConstructor (
36 IN VOID *EfiMemoryBegin,
37 IN UINTN EfiMemoryLength,
38 IN VOID *EfiFreeMemoryBottom,
39 IN VOID *EfiFreeMemoryTop
40 );
41
42 // GUID to identify HOB with whereabouts of communication buffer with Normal
43 // World
44 extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;
45
46 // GUID to identify HOB where the entry point of the CPU driver will be
47 // populated to allow this entry point driver to invoke it upon receipt of an
48 // event
49 extern EFI_GUID gEfiArmTfCpuDriverEpDescriptorGuid;
50
51 /**
52 Use the boot information passed by privileged firmware to populate a HOB list
53 suitable for consumption by the MM Core and drivers.
54
55 @param PayloadBootInfo Boot information passed by privileged firmware
56
57 **/
58 VOID *
59 CreateHobListFromBootInfo (
60 IN OUT PI_MM_ARM_TF_CPU_DRIVER_ENTRYPOINT *CpuDriverEntryPoint,
61 IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo
62 )
63 {
64 EFI_HOB_HANDOFF_INFO_TABLE *HobStart;
65 EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
66 UINT32 Index;
67 UINT32 BufferSize;
68 UINT32 Flags;
69 EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHob;
70 EFI_MMRAM_DESCRIPTOR *MmramRanges;
71 EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;
72 MP_INFORMATION_HOB_DATA *MpInformationHobData;
73 EFI_PROCESSOR_INFORMATION *ProcInfoBuffer;
74 EFI_SECURE_PARTITION_CPU_INFO *CpuInfo;
75 ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;
76
77 // Create a hoblist with a PHIT and EOH
78 HobStart = HobConstructor (
79 (VOID *) PayloadBootInfo->SpMemBase,
80 (UINTN) PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase,
81 (VOID *) PayloadBootInfo->SpHeapBase,
82 (VOID *) (PayloadBootInfo->SpHeapBase + PayloadBootInfo->SpHeapSize)
83 );
84
85 // Check that the Hoblist starts at the bottom of the Heap
86 ASSERT (HobStart == (VOID *) PayloadBootInfo->SpHeapBase);
87
88 // Build a Boot Firmware Volume HOB
89 BuildFvHob (PayloadBootInfo->SpImageBase, PayloadBootInfo->SpImageSize);
90
91 // Build a resource descriptor Hob that describes the available physical
92 // memory range
93 Attributes = (
94 EFI_RESOURCE_ATTRIBUTE_PRESENT |
95 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
96 EFI_RESOURCE_ATTRIBUTE_TESTED |
97 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
98 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
99 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
100 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
101 );
102
103 BuildResourceDescriptorHob (
104 EFI_RESOURCE_SYSTEM_MEMORY,
105 Attributes,
106 (UINTN) PayloadBootInfo->SpMemBase,
107 PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase
108 );
109
110 // Find the size of the GUIDed HOB with MP information
111 BufferSize = sizeof (MP_INFORMATION_HOB_DATA);
112 BufferSize += sizeof (EFI_PROCESSOR_INFORMATION) * PayloadBootInfo->NumCpus;
113
114 // Create a Guided MP information HOB to enable the ARM TF CPU driver to
115 // perform per-cpu allocations.
116 MpInformationHobData = BuildGuidHob (&gMpInformationHobGuid, BufferSize);
117
118 // Populate the MP information HOB with the topology information passed by
119 // privileged firmware
120 MpInformationHobData->NumberOfProcessors = PayloadBootInfo->NumCpus;
121 MpInformationHobData->NumberOfEnabledProcessors = PayloadBootInfo->NumCpus;
122 ProcInfoBuffer = MpInformationHobData->ProcessorInfoBuffer;
123 CpuInfo = PayloadBootInfo->CpuInfo;
124
125 for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {
126 ProcInfoBuffer[Index].ProcessorId = CpuInfo[Index].Mpidr;
127 ProcInfoBuffer[Index].Location.Package = GET_CLUSTER_ID(CpuInfo[Index].Mpidr);
128 ProcInfoBuffer[Index].Location.Core = GET_CORE_ID(CpuInfo[Index].Mpidr);
129 ProcInfoBuffer[Index].Location.Thread = GET_CORE_ID(CpuInfo[Index].Mpidr);
130
131 Flags = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;
132 if (CpuInfo[Index].Flags & CPU_INFO_FLAG_PRIMARY_CPU) {
133 Flags |= PROCESSOR_AS_BSP_BIT;
134 }
135 ProcInfoBuffer[Index].StatusFlag = Flags;
136 }
137
138 // Create a Guided HOB to tell the ARM TF CPU driver the location and length
139 // of the communication buffer shared with the Normal world.
140 NsCommBufMmramRange = (EFI_MMRAM_DESCRIPTOR *) BuildGuidHob (
141 &gEfiStandaloneMmNonSecureBufferGuid,
142 sizeof (EFI_MMRAM_DESCRIPTOR)
143 );
144 NsCommBufMmramRange->PhysicalStart = PayloadBootInfo->SpNsCommBufBase;
145 NsCommBufMmramRange->CpuStart = PayloadBootInfo->SpNsCommBufBase;
146 NsCommBufMmramRange->PhysicalSize = PayloadBootInfo->SpNsCommBufSize;
147 NsCommBufMmramRange->RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
148
149 // Create a Guided HOB to enable the ARM TF CPU driver to share its entry
150 // point and populate it with the address of the shared buffer
151 CpuDriverEntryPointDesc = (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR *) BuildGuidHob (
152 &gEfiArmTfCpuDriverEpDescriptorGuid,
153 sizeof (ARM_TF_CPU_DRIVER_EP_DESCRIPTOR)
154 );
155
156 *CpuDriverEntryPoint = NULL;
157 CpuDriverEntryPointDesc->ArmTfCpuDriverEpPtr = CpuDriverEntryPoint;
158
159 // Find the size of the GUIDed HOB with SRAM ranges
160 BufferSize = sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK);
161 BufferSize += PayloadBootInfo->NumSpMemRegions * sizeof (EFI_MMRAM_DESCRIPTOR);
162
163 // Create a GUIDed HOB with SRAM ranges
164 MmramRangesHob = BuildGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, BufferSize);
165
166 // Fill up the number of MMRAM memory regions
167 MmramRangesHob->NumberOfMmReservedRegions = PayloadBootInfo->NumSpMemRegions;
168 // Fill up the MMRAM ranges
169 MmramRanges = &MmramRangesHob->Descriptor[0];
170
171 // Base and size of memory occupied by the Standalone MM image
172 MmramRanges[0].PhysicalStart = PayloadBootInfo->SpImageBase;
173 MmramRanges[0].CpuStart = PayloadBootInfo->SpImageBase;
174 MmramRanges[0].PhysicalSize = PayloadBootInfo->SpImageSize;
175 MmramRanges[0].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
176
177 // Base and size of buffer shared with privileged Secure world software
178 MmramRanges[1].PhysicalStart = PayloadBootInfo->SpSharedBufBase;
179 MmramRanges[1].CpuStart = PayloadBootInfo->SpSharedBufBase;
180 MmramRanges[1].PhysicalSize = PayloadBootInfo->SpPcpuSharedBufSize * PayloadBootInfo->NumCpus;
181 MmramRanges[1].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
182
183 // Base and size of buffer used for synchronous communication with Normal
184 // world software
185 MmramRanges[2].PhysicalStart = PayloadBootInfo->SpNsCommBufBase;
186 MmramRanges[2].CpuStart = PayloadBootInfo->SpNsCommBufBase;
187 MmramRanges[2].PhysicalSize = PayloadBootInfo->SpNsCommBufSize;
188 MmramRanges[2].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
189
190 // Base and size of memory allocated for stacks for all cpus
191 MmramRanges[3].PhysicalStart = PayloadBootInfo->SpStackBase;
192 MmramRanges[3].CpuStart = PayloadBootInfo->SpStackBase;
193 MmramRanges[3].PhysicalSize = PayloadBootInfo->SpPcpuStackSize * PayloadBootInfo->NumCpus;
194 MmramRanges[3].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
195
196 // Base and size of heap memory shared by all cpus
197 MmramRanges[4].PhysicalStart = (EFI_PHYSICAL_ADDRESS) HobStart;
198 MmramRanges[4].CpuStart = (EFI_PHYSICAL_ADDRESS) HobStart;
199 MmramRanges[4].PhysicalSize = HobStart->EfiFreeMemoryBottom - (EFI_PHYSICAL_ADDRESS) HobStart;
200 MmramRanges[4].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
201
202 // Base and size of heap memory shared by all cpus
203 MmramRanges[5].PhysicalStart = HobStart->EfiFreeMemoryBottom;
204 MmramRanges[5].CpuStart = HobStart->EfiFreeMemoryBottom;
205 MmramRanges[5].PhysicalSize = HobStart->EfiFreeMemoryTop - HobStart->EfiFreeMemoryBottom;
206 MmramRanges[5].RegionState = EFI_CACHEABLE;
207
208 return HobStart;
209 }