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