]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Pei/Hob/Hob.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Hob / Hob.c
1 /** @file
2 This module provide Hand-Off Block manipulation.
3
4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "PeiMain.h"
10
11 /**
12
13 Gets the pointer to the HOB List.
14
15 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
16 @param HobList Pointer to the HOB List.
17
18 @retval EFI_SUCCESS Get the pointer of HOB List
19 @retval EFI_NOT_AVAILABLE_YET the HOB List is not yet published
20 @retval EFI_INVALID_PARAMETER HobList is NULL (in debug mode)
21
22 **/
23 EFI_STATUS
24 EFIAPI
25 PeiGetHobList (
26 IN CONST EFI_PEI_SERVICES **PeiServices,
27 IN OUT VOID **HobList
28 )
29 {
30 PEI_CORE_INSTANCE *PrivateData;
31
32 //
33 // Only check this parameter in debug mode
34 //
35
36 DEBUG_CODE_BEGIN ();
37 if (HobList == NULL) {
38 return EFI_INVALID_PARAMETER;
39 }
40
41 DEBUG_CODE_END ();
42
43 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
44
45 *HobList = PrivateData->HobList.Raw;
46
47 return EFI_SUCCESS;
48 }
49
50 /**
51 Add a new HOB to the HOB List.
52
53 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
54 @param Type Type of the new HOB.
55 @param Length Length of the new HOB to allocate.
56 @param Hob Pointer to the new HOB.
57
58 @return EFI_SUCCESS Success to create HOB.
59 @retval EFI_INVALID_PARAMETER if Hob is NULL
60 @retval EFI_NOT_AVAILABLE_YET if HobList is still not available.
61 @retval EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
62
63 **/
64 EFI_STATUS
65 EFIAPI
66 PeiCreateHob (
67 IN CONST EFI_PEI_SERVICES **PeiServices,
68 IN UINT16 Type,
69 IN UINT16 Length,
70 IN OUT VOID **Hob
71 )
72 {
73 EFI_STATUS Status;
74 EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
75 EFI_HOB_GENERIC_HEADER *HobEnd;
76 EFI_PHYSICAL_ADDRESS FreeMemory;
77
78 Status = PeiGetHobList (PeiServices, Hob);
79 if (EFI_ERROR (Status)) {
80 return Status;
81 }
82
83 HandOffHob = *Hob;
84
85 //
86 // Check Length to avoid data overflow.
87 //
88 if (0x10000 - Length <= 0x7) {
89 return EFI_INVALID_PARAMETER;
90 }
91
92 Length = (UINT16)((Length + 0x7) & (~0x7));
93
94 FreeMemory = HandOffHob->EfiFreeMemoryTop -
95 HandOffHob->EfiFreeMemoryBottom;
96
97 if (FreeMemory < Length) {
98 DEBUG ((DEBUG_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length));
99 DEBUG ((DEBUG_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop));
100 DEBUG ((DEBUG_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom));
101 return EFI_OUT_OF_RESOURCES;
102 }
103
104 *Hob = (VOID *)(UINTN)HandOffHob->EfiEndOfHobList;
105 ((EFI_HOB_GENERIC_HEADER *)*Hob)->HobType = Type;
106 ((EFI_HOB_GENERIC_HEADER *)*Hob)->HobLength = Length;
107 ((EFI_HOB_GENERIC_HEADER *)*Hob)->Reserved = 0;
108
109 HobEnd = (EFI_HOB_GENERIC_HEADER *)((UINTN)*Hob + Length);
110 HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
111
112 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
113 HobEnd->HobLength = (UINT16)sizeof (EFI_HOB_GENERIC_HEADER);
114 HobEnd->Reserved = 0;
115 HobEnd++;
116 HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
117
118 return EFI_SUCCESS;
119 }
120
121 /**
122 Install SEC HOB data to the HOB List.
123
124 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
125 @param SecHobList Pointer to SEC HOB List.
126
127 @return EFI_SUCCESS Success to install SEC HOB data.
128 @retval EFI_OUT_OF_RESOURCES If there is no more memory to grow the Hoblist.
129
130 **/
131 EFI_STATUS
132 PeiInstallSecHobData (
133 IN CONST EFI_PEI_SERVICES **PeiServices,
134 IN EFI_HOB_GENERIC_HEADER *SecHobList
135 )
136 {
137 EFI_STATUS Status;
138 EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
139 EFI_PEI_HOB_POINTERS HobStart;
140 EFI_PEI_HOB_POINTERS Hob;
141 UINTN SecHobListLength;
142 EFI_PHYSICAL_ADDRESS FreeMemory;
143 EFI_HOB_GENERIC_HEADER *HobEnd;
144
145 HandOffHob = NULL;
146 Status = PeiGetHobList (PeiServices, (VOID **)&HandOffHob);
147 if (EFI_ERROR (Status)) {
148 return Status;
149 }
150
151 ASSERT (HandOffHob != NULL);
152
153 HobStart.Raw = (UINT8 *)SecHobList;
154 //
155 // The HobList must not contain a EFI_HOB_HANDOFF_INFO_TABLE HOB (PHIT) HOB.
156 //
157 ASSERT (HobStart.Header->HobType != EFI_HOB_TYPE_HANDOFF);
158 //
159 // Calculate the SEC HOB List length,
160 // not including the terminated HOB(EFI_HOB_TYPE_END_OF_HOB_LIST).
161 //
162 for (Hob.Raw = HobStart.Raw; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
163 }
164
165 SecHobListLength = (UINTN)Hob.Raw - (UINTN)HobStart.Raw;
166 //
167 // The length must be 8-bytes aligned.
168 //
169 ASSERT ((SecHobListLength & 0x7) == 0);
170
171 FreeMemory = HandOffHob->EfiFreeMemoryTop -
172 HandOffHob->EfiFreeMemoryBottom;
173
174 if (FreeMemory < SecHobListLength) {
175 DEBUG ((DEBUG_ERROR, "PeiInstallSecHobData fail: SecHobListLength - 0x%08x\n", SecHobListLength));
176 DEBUG ((DEBUG_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop));
177 DEBUG ((DEBUG_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom));
178 return EFI_OUT_OF_RESOURCES;
179 }
180
181 Hob.Raw = (UINT8 *)(UINTN)HandOffHob->EfiEndOfHobList;
182 CopyMem (Hob.Raw, HobStart.Raw, SecHobListLength);
183
184 HobEnd = (EFI_HOB_GENERIC_HEADER *)((UINTN)Hob.Raw + SecHobListLength);
185 HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
186
187 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
188 HobEnd->HobLength = (UINT16)sizeof (EFI_HOB_GENERIC_HEADER);
189 HobEnd->Reserved = 0;
190 HobEnd++;
191 HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
192
193 return EFI_SUCCESS;
194 }
195
196 /**
197
198 Builds a Handoff Information Table HOB
199
200 @param BootMode - Current Bootmode
201 @param MemoryBegin - Start Memory Address.
202 @param MemoryLength - Length of Memory.
203
204 @return EFI_SUCCESS Always success to initialize HOB.
205
206 **/
207 EFI_STATUS
208 PeiCoreBuildHobHandoffInfoTable (
209 IN EFI_BOOT_MODE BootMode,
210 IN EFI_PHYSICAL_ADDRESS MemoryBegin,
211 IN UINT64 MemoryLength
212 )
213 {
214 EFI_HOB_HANDOFF_INFO_TABLE *Hob;
215 EFI_HOB_GENERIC_HEADER *HobEnd;
216
217 Hob = (VOID *)(UINTN)MemoryBegin;
218 HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
219 Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
220 Hob->Header.HobLength = (UINT16)sizeof (EFI_HOB_HANDOFF_INFO_TABLE);
221 Hob->Header.Reserved = 0;
222
223 HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
224 HobEnd->HobLength = (UINT16)sizeof (EFI_HOB_GENERIC_HEADER);
225 HobEnd->Reserved = 0;
226
227 Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
228 Hob->BootMode = BootMode;
229
230 Hob->EfiMemoryTop = MemoryBegin + MemoryLength;
231 Hob->EfiMemoryBottom = MemoryBegin;
232 Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength;
233 Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd + 1);
234 Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
235
236 return EFI_SUCCESS;
237 }