]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTest.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / MemoryTest / NullMemoryTestDxe / NullMemoryTest.c
CommitLineData
674dced3 1/** @file\r
b3764698 2 Implementation of Generic Memory Test Protocol which does not perform real memory test.\r
05177bef 3\r
1c06bd48 4Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
05177bef 6\r
674dced3 7**/\r
05177bef 8\r
05177bef 9#include "NullMemoryTest.h"\r
10\r
1436aea4
MK
11UINT64 mTestedSystemMemory = 0;\r
12UINT64 mTotalSystemMemory = 0;\r
13EFI_HANDLE mGenericMemoryTestHandle;\r
05177bef 14\r
05177bef 15EFI_GENERIC_MEMORY_TEST_PROTOCOL mGenericMemoryTest = {\r
16 InitializeMemoryTest,\r
17 GenPerformMemoryTest,\r
18 GenMemoryTestFinished,\r
19 GenCompatibleRangeTest\r
20};\r
21\r
b3764698 22/**\r
23 Entry point of the NULL memory test driver.\r
d1102dba 24\r
b3764698 25 This function is the entry point of the NULL memory test driver.\r
26 It simply installs the Generic Memory Test Protocol.\r
27\r
28 @param ImageHandle The firmware allocated handle for the EFI image.\r
29 @param SystemTable A pointer to the EFI System Table.\r
30\r
31 @retval EFI_SUCCESS Generic Memory Test Protocol is successfully installed.\r
32\r
33**/\r
05177bef 34EFI_STATUS\r
35EFIAPI\r
36GenericMemoryTestEntryPoint (\r
1436aea4
MK
37 IN EFI_HANDLE ImageHandle,\r
38 IN EFI_SYSTEM_TABLE *SystemTable\r
05177bef 39 )\r
05177bef 40{\r
41 EFI_STATUS Status;\r
42\r
05177bef 43 Status = gBS->InstallProtocolInterface (\r
44 &mGenericMemoryTestHandle,\r
45 &gEfiGenericMemTestProtocolGuid,\r
46 EFI_NATIVE_INTERFACE,\r
47 &mGenericMemoryTest\r
48 );\r
b3764698 49 ASSERT_EFI_ERROR (Status);\r
05177bef 50\r
b3764698 51 return EFI_SUCCESS;\r
05177bef 52}\r
b3764698 53\r
1c06bd48 54/**\r
ee37e964 55 Convert the memory range to tested.\r
1c06bd48 56\r
ee37e964
RN
57 @param BaseAddress Base address of the memory range.\r
58 @param Length Length of the memory range.\r
59 @param Capabilities Capabilities of the memory range.\r
1c06bd48 60\r
ee37e964 61 @retval EFI_SUCCESS The memory range is converted to tested.\r
1c06bd48
RN
62 @retval others Error happens.\r
63**/\r
64EFI_STATUS\r
65ConvertToTestedMemory (\r
1436aea4
MK
66 IN UINT64 BaseAddress,\r
67 IN UINT64 Length,\r
68 IN UINT64 Capabilities\r
1c06bd48
RN
69 )\r
70{\r
1436aea4
MK
71 EFI_STATUS Status;\r
72\r
1c06bd48 73 Status = gDS->RemoveMemorySpace (\r
ee37e964
RN
74 BaseAddress,\r
75 Length\r
1c06bd48
RN
76 );\r
77 if (!EFI_ERROR (Status)) {\r
78 Status = gDS->AddMemorySpace (\r
ee37e964 79 ((Capabilities & EFI_MEMORY_MORE_RELIABLE) == EFI_MEMORY_MORE_RELIABLE) ?\r
1c06bd48 80 EfiGcdMemoryTypeMoreReliable : EfiGcdMemoryTypeSystemMemory,\r
ee37e964
RN
81 BaseAddress,\r
82 Length,\r
83 Capabilities &~\r
1c06bd48
RN
84 (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED | EFI_MEMORY_RUNTIME)\r
85 );\r
86 }\r
1436aea4 87\r
1c06bd48
RN
88 return Status;\r
89}\r
90\r
b3764698 91/**\r
92 Initialize the generic memory test.\r
93\r
94 This function implements EFI_GENERIC_MEMORY_TEST_PROTOCOL.MemoryTestInit.\r
95 It simply promotes untested reserved memory to system memory without real test.\r
96\r
d1102dba
LG
97 @param This Protocol instance pointer.\r
98 @param Level The coverage level of the memory test.\r
99 @param RequireSoftECCInit Indicate if the memory need software ECC init.\r
b3764698 100\r
d1102dba
LG
101 @retval EFI_SUCCESS The generic memory test initialized correctly.\r
102 @retval EFI_NO_MEDIA There is not any non-tested memory found, in this\r
103 function if not any non-tesed memory found means\r
104 that the memory test driver have not detect any\r
105 non-tested extended memory of current system.\r
b3764698 106\r
107**/\r
05177bef 108EFI_STATUS\r
109EFIAPI\r
110InitializeMemoryTest (\r
1436aea4
MK
111 IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This,\r
112 IN EXTENDMEM_COVERAGE_LEVEL Level,\r
113 OUT BOOLEAN *RequireSoftECCInit\r
05177bef 114 )\r
05177bef 115{\r
1436aea4
MK
116 EFI_STATUS Status;\r
117 UINTN NumberOfDescriptors;\r
118 EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;\r
119 UINTN Index;\r
05177bef 120\r
121 gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);\r
122 for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
1436aea4
MK
123 if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved) &&\r
124 ((MemorySpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==\r
125 (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))\r
126 )\r
127 {\r
b3764698 128 //\r
129 // For those reserved memory that have not been tested, simply promote to system memory.\r
130 //\r
ee37e964
RN
131 Status = ConvertToTestedMemory (\r
132 MemorySpaceMap[Index].BaseAddress,\r
133 MemorySpaceMap[Index].Length,\r
134 MemorySpaceMap[Index].Capabilities\r
135 );\r
1c06bd48 136 ASSERT_EFI_ERROR (Status);\r
05177bef 137 mTestedSystemMemory += MemorySpaceMap[Index].Length;\r
1436aea4 138 mTotalSystemMemory += MemorySpaceMap[Index].Length;\r
1c06bd48 139 } else if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) ||\r
1436aea4
MK
140 (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMoreReliable))\r
141 {\r
05177bef 142 mTotalSystemMemory += MemorySpaceMap[Index].Length;\r
143 }\r
144 }\r
145\r
146 FreePool (MemorySpaceMap);\r
147\r
148 *RequireSoftECCInit = FALSE;\r
149 return EFI_SUCCESS;\r
150}\r
151\r
b3764698 152/**\r
153 Perform the memory test.\r
154\r
155 This function implements EFI_GENERIC_MEMORY_TEST_PROTOCOL.PerformMemoryTest.\r
156 It simply returns EFI_NOT_FOUND.\r
157\r
d1102dba
LG
158 @param This Protocol instance pointer.\r
159 @param TestedMemorySize Return the tested extended memory size.\r
160 @param TotalMemorySize Return the whole system physical memory size, this\r
161 value may be changed if in some case some error\r
162 DIMMs be disabled.\r
163 @param ErrorOut Any time the memory error occurs, this will be\r
164 TRUE.\r
165 @param IfTestAbort Indicate if the user press "ESC" to skip the memory\r
166 test.\r
167\r
168 @retval EFI_SUCCESS One block of memory test ok, the block size is hide\r
169 internally.\r
170 @retval EFI_NOT_FOUND Indicate all the non-tested memory blocks have\r
171 already go through.\r
b3764698 172 @retval EFI_DEVICE_ERROR Mis-compare error, and no agent can handle it\r
173\r
174**/\r
05177bef 175EFI_STATUS\r
176EFIAPI\r
177GenPerformMemoryTest (\r
1436aea4
MK
178 IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This,\r
179 IN OUT UINT64 *TestedMemorySize,\r
180 OUT UINT64 *TotalMemorySize,\r
181 OUT BOOLEAN *ErrorOut,\r
182 IN BOOLEAN TestAbort\r
05177bef 183 )\r
05177bef 184{\r
185 *ErrorOut = FALSE;\r
186 *TestedMemorySize = mTestedSystemMemory;\r
187 *TotalMemorySize = mTotalSystemMemory;\r
188\r
189 return EFI_NOT_FOUND;\r
05177bef 190}\r
191\r
b3764698 192/**\r
193 The memory test finished.\r
194\r
195 This function implements EFI_GENERIC_MEMORY_TEST_PROTOCOL.Finished.\r
196 It simply returns EFI_SUCCESS.\r
197\r
d1102dba 198 @param This Protocol instance pointer.\r
b3764698 199\r
d1102dba
LG
200 @retval EFI_SUCCESS Successful free all the generic memory test driver\r
201 allocated resource and notify to platform memory\r
202 test driver that memory test finished.\r
b3764698 203\r
204**/\r
05177bef 205EFI_STATUS\r
206EFIAPI\r
207GenMemoryTestFinished (\r
1436aea4 208 IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This\r
05177bef 209 )\r
05177bef 210{\r
211 return EFI_SUCCESS;\r
212}\r
213\r
b3764698 214/**\r
215 Provide capability to test compatible range which used by some special\r
216 driver required using memory range before BDS perform memory test.\r
217\r
218 This function implements EFI_GENERIC_MEMORY_TEST_PROTOCOL.CompatibleRangeTest.\r
219 It simply sets the memory range to system memory.\r
220\r
d1102dba
LG
221 @param This Protocol instance pointer.\r
222 @param StartAddress The start address of the memory range.\r
223 @param Length The memory range's length.\r
224\r
225 @retval EFI_SUCCESS The compatible memory range pass the memory test.\r
b3764698 226 @retval EFI_INVALID_PARAMETER The compatible memory range must be below 16M.\r
227\r
228**/\r
05177bef 229EFI_STATUS\r
230EFIAPI\r
231GenCompatibleRangeTest (\r
1436aea4
MK
232 IN EFI_GENERIC_MEMORY_TEST_PROTOCOL *This,\r
233 IN EFI_PHYSICAL_ADDRESS StartAddress,\r
234 IN UINT64 Length\r
05177bef 235 )\r
05177bef 236{\r
1436aea4
MK
237 EFI_STATUS Status;\r
238 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;\r
239 EFI_PHYSICAL_ADDRESS CurrentBase;\r
240 UINT64 CurrentLength;\r
61c1742b
RN
241\r
242 //\r
243 // Check if the parameter is below 16MB\r
244 //\r
245 if (StartAddress + Length > SIZE_16MB) {\r
246 return EFI_INVALID_PARAMETER;\r
1c06bd48 247 }\r
1436aea4 248\r
61c1742b
RN
249 CurrentBase = StartAddress;\r
250 do {\r
251 //\r
252 // Check the required memory range status; if the required memory range span\r
253 // the different GCD memory descriptor, it may be cause different action.\r
254 //\r
255 Status = gDS->GetMemorySpaceDescriptor (\r
256 CurrentBase,\r
257 &Descriptor\r
258 );\r
259 if (EFI_ERROR (Status)) {\r
260 return Status;\r
261 }\r
262\r
1436aea4
MK
263 if ((Descriptor.GcdMemoryType == EfiGcdMemoryTypeReserved) &&\r
264 ((Descriptor.Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==\r
265 (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))\r
266 )\r
267 {\r
61c1742b
RN
268 CurrentLength = Descriptor.BaseAddress + Descriptor.Length - CurrentBase;\r
269 if (CurrentBase + CurrentLength > StartAddress + Length) {\r
270 CurrentLength = StartAddress + Length - CurrentBase;\r
271 }\r
1436aea4 272\r
61c1742b
RN
273 Status = ConvertToTestedMemory (\r
274 CurrentBase,\r
275 CurrentLength,\r
276 Descriptor.Capabilities\r
277 );\r
278 if (EFI_ERROR (Status)) {\r
279 return Status;\r
280 }\r
281 }\r
1436aea4 282\r
61c1742b
RN
283 CurrentBase = Descriptor.BaseAddress + Descriptor.Length;\r
284 } while (CurrentBase < StartAddress + Length);\r
1436aea4 285\r
61c1742b
RN
286 //\r
287 // Here means the required range already be tested, so just return success.\r
288 //\r
289 return EFI_SUCCESS;\r
05177bef 290}\r