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