]> git.proxmox.com Git - mirror_edk2.git/blob - EdkNt32Pkg/Dxe/PlatformBds/Generic/MemoryTest.c
Initial import.
[mirror_edk2.git] / EdkNt32Pkg / Dxe / PlatformBds / Generic / MemoryTest.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 MemoryTest.c
15
16 Abstract:
17
18 Perform the platform memory test
19
20 --*/
21
22 #include "bds.h"
23 #include "BdsPlatform.h"
24 #include "String.h"
25
26 //
27 // BDS Platform Functions
28 //
29 EFI_STATUS
30 PlatformBdsShowProgress (
31 IN EFI_UGA_PIXEL TitleForeground,
32 IN EFI_UGA_PIXEL TitleBackground,
33 IN CHAR16 *Title,
34 IN EFI_UGA_PIXEL ProgressColor,
35 IN UINTN Progress,
36 IN UINTN PreviousValue
37 )
38 /*++
39
40 Routine Description:
41
42 Show progress bar with title above it. It only works in UGA mode.
43
44 Arguments:
45
46 TitleForeground - Foreground color for Title.
47 TitleBackground - Background color for Title.
48 Title - Title above progress bar.
49 ProgressColor - Progress bar color.
50 Progress - Progress (0-100)
51
52 Returns:
53
54 EFI_STATUS - Success update the progress bar
55
56 --*/
57 {
58 EFI_STATUS Status;
59 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
60 UINT32 SizeOfX;
61 UINT32 SizeOfY;
62 UINT32 ColorDepth;
63 UINT32 RefreshRate;
64 EFI_UGA_PIXEL Color;
65 UINTN BlockHeight;
66 UINTN BlockWidth;
67 UINTN BlockNum;
68 UINTN PosX;
69 UINTN PosY;
70 UINTN Index;
71
72 if (Progress > 100) {
73 return EFI_INVALID_PARAMETER;
74 }
75
76 Status = gBS->HandleProtocol (
77 gST->ConsoleOutHandle,
78 &gEfiUgaDrawProtocolGuid,
79 &UgaDraw
80 );
81 if (EFI_ERROR (Status)) {
82 return EFI_UNSUPPORTED;
83 }
84
85 Status = UgaDraw->GetMode (
86 UgaDraw,
87 &SizeOfX,
88 &SizeOfY,
89 &ColorDepth,
90 &RefreshRate
91 );
92 if (EFI_ERROR (Status)) {
93 return EFI_UNSUPPORTED;
94 }
95
96 BlockWidth = SizeOfX / 100;
97 BlockHeight = SizeOfY / 50;
98
99 BlockNum = Progress;
100
101 PosX = 0;
102 PosY = SizeOfY * 48 / 50;
103
104 if (BlockNum == 0) {
105 //
106 // Clear progress area
107 //
108 SetMem (&Color, sizeof (EFI_UGA_PIXEL), 0x0);
109
110 Status = UgaDraw->Blt (
111 UgaDraw,
112 &Color,
113 EfiUgaVideoFill,
114 0,
115 0,
116 0,
117 PosY - GLYPH_HEIGHT - 1,
118 SizeOfX,
119 SizeOfY - (PosY - GLYPH_HEIGHT - 1),
120 SizeOfX * sizeof (EFI_UGA_PIXEL)
121 );
122 }
123 //
124 // Show progress by drawing blocks
125 //
126 for (Index = PreviousValue; Index < BlockNum; Index++) {
127 PosX = Index * BlockWidth;
128 Status = UgaDraw->Blt (
129 UgaDraw,
130 &ProgressColor,
131 EfiUgaVideoFill,
132 0,
133 0,
134 PosX,
135 PosY,
136 BlockWidth - 1,
137 BlockHeight,
138 (BlockWidth) * sizeof (EFI_UGA_PIXEL)
139 );
140 }
141
142 PrintXY (
143 (SizeOfX - StrLen (Title) * GLYPH_WIDTH) / 2,
144 PosY - GLYPH_HEIGHT - 1,
145 &TitleForeground,
146 &TitleBackground,
147 Title
148 );
149
150 return EFI_SUCCESS;
151 }
152
153 EFI_STATUS
154 BdsMemoryTest (
155 IN EXTENDMEM_COVERAGE_LEVEL Level
156 )
157 /*++
158
159 Routine Description:
160
161 Perform the memory test base on the memory test intensive level,
162 and update the memory resource.
163
164 Arguments:
165
166 Level - The memory test intensive level.
167
168 Returns:
169
170 EFI_STATUS - Success test all the system memory and update
171 the memory resource
172
173 --*/
174 {
175 EFI_STATUS Status;
176 EFI_STATUS InitStatus;
177 EFI_STATUS KeyStatus;
178 EFI_STATUS ReturnStatus;
179 BOOLEAN RequireSoftECCInit;
180 EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest;
181 UINT64 TestedMemorySize;
182 UINT64 TotalMemorySize;
183 UINTN TestPercent;
184 UINT64 PreviousValue;
185 BOOLEAN ErrorOut;
186 BOOLEAN TestAbort;
187 EFI_INPUT_KEY Key;
188 CHAR16 StrPercent[16];
189 CHAR16 *StrTotalMemory;
190 CHAR16 *Pos;
191 CHAR16 *TmpStr;
192 EFI_UGA_PIXEL Foreground;
193 EFI_UGA_PIXEL Background;
194 EFI_UGA_PIXEL Color;
195 UINT8 Value;
196 UINTN DataSize;
197 UINT32 Attributes;
198
199 ReturnStatus = EFI_SUCCESS;
200 ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
201
202 Pos = AllocatePool (128);
203
204 if (Pos == NULL) {
205 return ReturnStatus;
206 }
207
208 StrTotalMemory = Pos;
209
210 TestedMemorySize = 0;
211 TotalMemorySize = 0;
212 PreviousValue = 0;
213 ErrorOut = FALSE;
214 TestAbort = FALSE;
215
216 SetMem (&Foreground, sizeof (EFI_UGA_PIXEL), 0xff);
217 SetMem (&Background, sizeof (EFI_UGA_PIXEL), 0x0);
218 SetMem (&Color, sizeof (EFI_UGA_PIXEL), 0xff);
219
220 RequireSoftECCInit = FALSE;
221
222 gST->ConOut->ClearScreen (gST->ConOut);
223 gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);
224 gST->ConOut->EnableCursor (gST->ConOut, FALSE);
225
226 Status = gBS->LocateProtocol (
227 &gEfiGenericMemTestProtocolGuid,
228 NULL,
229 &GenMemoryTest
230 );
231 if (EFI_ERROR (Status)) {
232 gBS->FreePool (Pos);
233 return EFI_SUCCESS;
234 }
235
236 InitStatus = GenMemoryTest->MemoryTestInit (
237 GenMemoryTest,
238 Level,
239 &RequireSoftECCInit
240 );
241 if (InitStatus == EFI_NO_MEDIA) {
242 //
243 // The PEI codes also have the relevant memory test code to check the memory,
244 // it can select to test some range of the memory or all of them. If PEI code
245 // checks all the memory, this BDS memory test will has no not-test memory to
246 // do the test, and then the status of EFI_NO_MEDIA will be returned by
247 // "MemoryTestInit". So it does not need to test memory again, just return.
248 //
249 gBS->FreePool (Pos);
250 return EFI_SUCCESS;
251 }
252
253 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 2);
254 TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST));
255
256 if (TmpStr != NULL) {
257 gST->ConOut->OutputString (gST->ConOut, TmpStr);
258 gBS->FreePool (TmpStr);
259 }
260
261 do {
262 Status = GenMemoryTest->PerformMemoryTest (
263 GenMemoryTest,
264 &TestedMemorySize,
265 &TotalMemorySize,
266 &ErrorOut,
267 TestAbort
268 );
269 if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {
270 TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR));
271 if (TmpStr != NULL) {
272 PrintXY (10, 10, NULL, NULL, TmpStr);
273 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 4);
274 gST->ConOut->OutputString (gST->ConOut, TmpStr);
275 gBS->FreePool (TmpStr);
276 }
277
278 ASSERT (0);
279 }
280
281 TestPercent = (UINTN) DivU64x32 (
282 DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),
283 (UINTN)DivU64x32 (TotalMemorySize, 16)
284 );
285 if (TestPercent != PreviousValue) {
286 UnicodeValueToString (StrPercent, 0, TestPercent, 0);
287 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);
288 TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT));
289 if (TmpStr != NULL) {
290 BdsLibOutputStrings (gST->ConOut, StrPercent, TmpStr, NULL);
291 gBS->FreePool (TmpStr);
292 }
293
294 TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));
295 if (TmpStr != NULL) {
296 PlatformBdsShowProgress (
297 Foreground,
298 Background,
299 TmpStr,
300 Color,
301 TestPercent,
302 (UINTN) PreviousValue
303 );
304 gBS->FreePool (TmpStr);
305 }
306 }
307
308 PreviousValue = TestPercent;
309
310 KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
311 if (Key.ScanCode == SCAN_ESC) {
312 if (!RequireSoftECCInit) {
313 TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));
314 if (TmpStr != NULL) {
315 PlatformBdsShowProgress (
316 Foreground,
317 Background,
318 TmpStr,
319 Color,
320 100,
321 (UINTN) PreviousValue
322 );
323 gBS->FreePool (TmpStr);
324 }
325
326 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);
327 gST->ConOut->OutputString (gST->ConOut, L"100");
328 Status = GenMemoryTest->Finished (GenMemoryTest);
329 goto Done;
330 }
331
332 TestAbort = TRUE;
333 }
334 } while (Status != EFI_NOT_FOUND);
335
336 Status = GenMemoryTest->Finished (GenMemoryTest);
337
338 Done:
339 UnicodeValueToString (StrTotalMemory, COMMA_TYPE, (UINTN) TotalMemorySize, 0);
340 if (StrTotalMemory[0] == L',') {
341 StrTotalMemory++;
342 }
343
344 TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED));
345 if (TmpStr != NULL) {
346 StrCat (StrTotalMemory, TmpStr);
347 gBS->FreePool (TmpStr);
348 }
349
350 gST->ConOut->ClearScreen (gST->ConOut);
351 gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);
352 gST->ConOut->EnableCursor (gST->ConOut, FALSE);
353 gST->ConOut->OutputString (gST->ConOut, StrTotalMemory);
354 PlatformBdsShowProgress (
355 Foreground,
356 Background,
357 StrTotalMemory,
358 Color,
359 100,
360 (UINTN) PreviousValue
361 );
362
363 gBS->FreePool (Pos);
364
365 DataSize = sizeof (Value);
366 Status = gRT->GetVariable (
367 L"BootState",
368 &gEfiBootStateGuid,
369 &Attributes,
370 &DataSize,
371 &Value
372 );
373
374 if (EFI_ERROR (Status)) {
375 Value = 1;
376 gRT->SetVariable (
377 L"BootState",
378 &gEfiBootStateGuid,
379 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
380 sizeof (Value),
381 &Value
382 );
383 }
384
385 return ReturnStatus;
386 }