]> git.proxmox.com Git - mirror_edk2.git/blob - Nt32Pkg/PlatformBdsDxe/Generic/MemoryTest.c
Clean UGA from Nt32Pkg.
[mirror_edk2.git] / Nt32Pkg / PlatformBdsDxe / Generic / MemoryTest.c
1 /*++
2
3 Copyright (c) 2006 - 2007, 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 "BdsString.h"
25
26 //
27 // BDS Platform Functions
28 //
29 EFI_STATUS
30 PlatformBdsShowProgress (
31 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
32 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
33 IN CHAR16 *Title,
34 IN EFI_GRAPHICS_OUTPUT_BLT_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_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
60 UINT32 SizeOfX;
61 UINT32 SizeOfY;
62 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
63 UINTN BlockHeight;
64 UINTN BlockWidth;
65 UINTN BlockNum;
66 UINTN PosX;
67 UINTN PosY;
68 UINTN Index;
69
70 if (Progress > 100) {
71 return EFI_INVALID_PARAMETER;
72 }
73
74 Status = gBS->HandleProtocol (
75 gST->ConsoleOutHandle,
76 &gEfiGraphicsOutputProtocolGuid,
77 &GraphicsOutput
78 );
79 if (EFI_ERROR (Status)) {
80 return EFI_UNSUPPORTED;
81 }
82
83 SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
84 SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
85
86 BlockWidth = SizeOfX / 100;
87 BlockHeight = SizeOfY / 50;
88
89 BlockNum = Progress;
90
91 PosX = 0;
92 PosY = SizeOfY * 48 / 50;
93
94 if (BlockNum == 0) {
95 //
96 // Clear progress area
97 //
98 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
99
100 Status = GraphicsOutput->Blt (
101 GraphicsOutput,
102 &Color,
103 EfiBltVideoFill,
104 0,
105 0,
106 0,
107 PosY - GLYPH_HEIGHT - 1,
108 SizeOfX,
109 SizeOfY - (PosY - GLYPH_HEIGHT - 1),
110 SizeOfX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
111 );
112 }
113 //
114 // Show progress by drawing blocks
115 //
116 for (Index = PreviousValue; Index < BlockNum; Index++) {
117 PosX = Index * BlockWidth;
118 Status = GraphicsOutput->Blt (
119 GraphicsOutput,
120 &ProgressColor,
121 EfiBltVideoFill,
122 0,
123 0,
124 PosX,
125 PosY,
126 BlockWidth - 1,
127 BlockHeight,
128 (BlockWidth) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
129 );
130 }
131
132 PrintXY (
133 (SizeOfX - StrLen (Title) * GLYPH_WIDTH) / 2,
134 PosY - GLYPH_HEIGHT - 1,
135 &TitleForeground,
136 &TitleBackground,
137 Title
138 );
139
140 return EFI_SUCCESS;
141 }
142
143 EFI_STATUS
144 BdsMemoryTest (
145 IN EXTENDMEM_COVERAGE_LEVEL Level
146 )
147 /*++
148
149 Routine Description:
150
151 Perform the memory test base on the memory test intensive level,
152 and update the memory resource.
153
154 Arguments:
155
156 Level - The memory test intensive level.
157
158 Returns:
159
160 EFI_STATUS - Success test all the system memory and update
161 the memory resource
162
163 --*/
164 {
165 EFI_STATUS Status;
166 EFI_STATUS InitStatus;
167 EFI_STATUS KeyStatus;
168 EFI_STATUS ReturnStatus;
169 BOOLEAN RequireSoftECCInit;
170 EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest;
171 UINT64 TestedMemorySize;
172 UINT64 TotalMemorySize;
173 UINTN TestPercent;
174 UINT64 PreviousValue;
175 BOOLEAN ErrorOut;
176 BOOLEAN TestAbort;
177 EFI_INPUT_KEY Key;
178 CHAR16 StrPercent[16];
179 CHAR16 *StrTotalMemory;
180 CHAR16 *Pos;
181 CHAR16 *TmpStr;
182 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground;
183 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background;
184 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color;
185 UINT8 Value;
186 UINTN DataSize;
187
188 ReturnStatus = EFI_SUCCESS;
189 ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
190
191 Pos = AllocatePool (128);
192
193 if (Pos == NULL) {
194 return ReturnStatus;
195 }
196
197 StrTotalMemory = Pos;
198
199 TestedMemorySize = 0;
200 TotalMemorySize = 0;
201 PreviousValue = 0;
202 ErrorOut = FALSE;
203 TestAbort = FALSE;
204
205 SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
206 SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);
207 SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff);
208
209 RequireSoftECCInit = FALSE;
210
211 gST->ConOut->ClearScreen (gST->ConOut);
212 gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);
213 gST->ConOut->EnableCursor (gST->ConOut, FALSE);
214
215 Status = gBS->LocateProtocol (
216 &gEfiGenericMemTestProtocolGuid,
217 NULL,
218 &GenMemoryTest
219 );
220 if (EFI_ERROR (Status)) {
221 FreePool (Pos);
222 return EFI_SUCCESS;
223 }
224
225 InitStatus = GenMemoryTest->MemoryTestInit (
226 GenMemoryTest,
227 Level,
228 &RequireSoftECCInit
229 );
230 if (InitStatus == EFI_NO_MEDIA) {
231 //
232 // The PEI codes also have the relevant memory test code to check the memory,
233 // it can select to test some range of the memory or all of them. If PEI code
234 // checks all the memory, this BDS memory test will has no not-test memory to
235 // do the test, and then the status of EFI_NO_MEDIA will be returned by
236 // "MemoryTestInit". So it does not need to test memory again, just return.
237 //
238 FreePool (Pos);
239 return EFI_SUCCESS;
240 }
241
242 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 2);
243 TmpStr = GetStringById (STRING_TOKEN (STR_ESC_TO_SKIP_MEM_TEST));
244
245 if (TmpStr != NULL) {
246 gST->ConOut->OutputString (gST->ConOut, TmpStr);
247 FreePool (TmpStr);
248 }
249
250 do {
251 Status = GenMemoryTest->PerformMemoryTest (
252 GenMemoryTest,
253 &TestedMemorySize,
254 &TotalMemorySize,
255 &ErrorOut,
256 TestAbort
257 );
258 if (ErrorOut && (Status == EFI_DEVICE_ERROR)) {
259 TmpStr = GetStringById (STRING_TOKEN (STR_SYSTEM_MEM_ERROR));
260 if (TmpStr != NULL) {
261 PrintXY (10, 10, NULL, NULL, TmpStr);
262 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 4);
263 gST->ConOut->OutputString (gST->ConOut, TmpStr);
264 FreePool (TmpStr);
265 }
266
267 ASSERT (0);
268 }
269
270 TestPercent = (UINTN) DivU64x32 (
271 DivU64x32 (MultU64x32 (TestedMemorySize, 100), 16),
272 (UINTN)DivU64x32 (TotalMemorySize, 16)
273 );
274 if (TestPercent != PreviousValue) {
275 UnicodeValueToString (StrPercent, 0, TestPercent, 0);
276 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);
277 TmpStr = GetStringById (STRING_TOKEN (STR_MEMORY_TEST_PERCENT));
278 if (TmpStr != NULL) {
279 BdsLibOutputStrings (gST->ConOut, StrPercent, TmpStr, NULL);
280 FreePool (TmpStr);
281 }
282
283 TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));
284 if (TmpStr != NULL) {
285 PlatformBdsShowProgress (
286 Foreground,
287 Background,
288 TmpStr,
289 Color,
290 TestPercent,
291 (UINTN) PreviousValue
292 );
293 FreePool (TmpStr);
294 }
295 }
296
297 PreviousValue = TestPercent;
298
299 KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
300 if (Key.ScanCode == SCAN_ESC) {
301 if (!RequireSoftECCInit) {
302 TmpStr = GetStringById (STRING_TOKEN (STR_PERFORM_MEM_TEST));
303 if (TmpStr != NULL) {
304 PlatformBdsShowProgress (
305 Foreground,
306 Background,
307 TmpStr,
308 Color,
309 100,
310 (UINTN) PreviousValue
311 );
312 FreePool (TmpStr);
313 }
314
315 gST->ConOut->SetCursorPosition (gST->ConOut, 0, 0);
316 gST->ConOut->OutputString (gST->ConOut, L"100");
317 Status = GenMemoryTest->Finished (GenMemoryTest);
318 goto Done;
319 }
320
321 TestAbort = TRUE;
322 }
323 } while (Status != EFI_NOT_FOUND);
324
325 Status = GenMemoryTest->Finished (GenMemoryTest);
326
327 Done:
328 UnicodeValueToString (StrTotalMemory, COMMA_TYPE, (UINTN) TotalMemorySize, 0);
329 if (StrTotalMemory[0] == L',') {
330 StrTotalMemory++;
331 }
332
333 TmpStr = GetStringById (STRING_TOKEN (STR_MEM_TEST_COMPLETED));
334 if (TmpStr != NULL) {
335 StrCat (StrTotalMemory, TmpStr);
336 FreePool (TmpStr);
337 }
338
339 gST->ConOut->ClearScreen (gST->ConOut);
340 gST->ConOut->SetAttribute (gST->ConOut, EFI_YELLOW | EFI_BRIGHT);
341 gST->ConOut->EnableCursor (gST->ConOut, FALSE);
342 gST->ConOut->OutputString (gST->ConOut, StrTotalMemory);
343 PlatformBdsShowProgress (
344 Foreground,
345 Background,
346 StrTotalMemory,
347 Color,
348 100,
349 (UINTN) PreviousValue
350 );
351
352 FreePool (Pos);
353
354 DataSize = sizeof (Value);
355 Status = gRT->GetVariable (
356 L"BootState",
357 &gEfiBootStateGuid,
358 NULL,
359 &DataSize,
360 &Value
361 );
362
363 if (EFI_ERROR (Status)) {
364 Value = 1;
365 gRT->SetVariable (
366 L"BootState",
367 &gEfiBootStateGuid,
368 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
369 sizeof (Value),
370 &Value
371 );
372 }
373
374 return ReturnStatus;
375 }