3 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution. The
8 full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "LightMemoryTest.h"
20 // Since this driver will only ever produce one instance of the memory test
21 // protocol, so we do not need to dynamically allocate the PrivateData.
23 EFI_PHYSICAL_ADDRESS mCurrentAddress
;
24 LIST_ENTRY
*mCurrentLink
;
25 NONTESTED_MEMORY_RANGE
*mCurrentRange
;
26 UINT64 mTestedSystemMemory
;
27 UINT64 mNonTestedSystemMemory
;
29 UINT32 GenericMemoryTestMonoPattern
[GENERIC_CACHELINE_SIZE
/ 4] = {
49 Compares the contents of two buffers.
51 This function compares Length bytes of SourceBuffer to Length bytes of DestinationBuffer.
52 If all Length bytes of the two buffers are identical, then 0 is returned. Otherwise, the
53 value returned is the first mismatched byte in SourceBuffer subtracted from the first
54 mismatched byte in DestinationBuffer.
56 If Length = 0, then ASSERT().
58 @param[in] DestinationBuffer The pointer to the destination buffer to compare.
59 @param[in] SourceBuffer The pointer to the source buffer to compare.
60 @param[in] Length The number of bytes to compare.
62 @return 0 All Length bytes of the two buffers are identical.
63 @retval Non-zero The first mismatched byte in SourceBuffer subtracted from the first
64 mismatched byte in DestinationBuffer.
69 CompareMemWithoutCheckArgument (
70 IN CONST VOID
*DestinationBuffer
,
71 IN CONST VOID
*SourceBuffer
,
76 while ((--Length
!= 0) &&
77 (*(INT8
*)DestinationBuffer
== *(INT8
*)SourceBuffer
)) {
78 DestinationBuffer
= (INT8
*)DestinationBuffer
+ 1;
79 SourceBuffer
= (INT8
*)SourceBuffer
+ 1;
81 return (INTN
)*(UINT8
*)DestinationBuffer
- (INTN
)*(UINT8
*)SourceBuffer
;
85 Construct the system base memory range through GCD service.
87 @param[in] Private Point to generic memory test driver's private data.
89 @retval EFI_SUCCESS Successful construct the base memory range through GCD service.
90 @retval EFI_OUT_OF_RESOURCE Could not allocate needed resource from base memory.
91 @retval Others Failed to construct base memory range through GCD service.
95 ConstructBaseMemoryRange (
96 IN GENERIC_MEMORY_TEST_PRIVATE
*Private
99 UINTN NumberOfDescriptors
;
100 EFI_GCD_MEMORY_SPACE_DESCRIPTOR
*MemorySpaceMap
;
104 // Base memory will always below 4G
106 gDS
->GetMemorySpaceMap (&NumberOfDescriptors
, &MemorySpaceMap
);
108 for (Index
= 0; Index
< NumberOfDescriptors
; Index
++) {
109 if ((MemorySpaceMap
[Index
].GcdMemoryType
== EfiGcdMemoryTypeSystemMemory
) ||
110 (MemorySpaceMap
[Index
].GcdMemoryType
== EfiGcdMemoryTypeMoreReliable
)) {
111 Private
->BaseMemorySize
+= MemorySpaceMap
[Index
].Length
;
119 Destroy the link list base on the correspond link list type.
121 @param[in] Private Point to generic memory test driver's private data.
126 IN GENERIC_MEMORY_TEST_PRIVATE
*Private
130 NONTESTED_MEMORY_RANGE
*NontestedRange
;
132 Link
= Private
->NonTestedMemRanList
.BackLink
;
134 while (Link
!= &Private
->NonTestedMemRanList
) {
135 RemoveEntryList (Link
);
136 NontestedRange
= NONTESTED_MEMORY_RANGE_FROM_LINK (Link
);
137 gBS
->FreePool (NontestedRange
);
138 Link
= Private
->NonTestedMemRanList
.BackLink
;;
143 Convert the memory range to tested.
145 @param BaseAddress Base address of the memory range.
146 @param Length Length of the memory range.
147 @param Capabilities Capabilities of the memory range.
149 @retval EFI_SUCCESS The memory range is converted to tested.
150 @retval others Error happens.
153 ConvertToTestedMemory (
154 IN UINT64 BaseAddress
,
156 IN UINT64 Capabilities
160 Status
= gDS
->RemoveMemorySpace (
164 if (!EFI_ERROR (Status
)) {
165 Status
= gDS
->AddMemorySpace (
166 ((Capabilities
& EFI_MEMORY_MORE_RELIABLE
) == EFI_MEMORY_MORE_RELIABLE
) ?
167 EfiGcdMemoryTypeMoreReliable
: EfiGcdMemoryTypeSystemMemory
,
171 (EFI_MEMORY_PRESENT
| EFI_MEMORY_INITIALIZED
| EFI_MEMORY_TESTED
| EFI_MEMORY_RUNTIME
)
178 Add the extened memory to whole system memory map.
180 @param[in] Private Point to generic memory test driver's private data.
182 @retval EFI_SUCCESS Successful add all the extended memory to system memory map.
183 @retval Others Failed to add the tested extended memory.
188 IN GENERIC_MEMORY_TEST_PRIVATE
*Private
192 NONTESTED_MEMORY_RANGE
*Range
;
194 Link
= Private
->NonTestedMemRanList
.ForwardLink
;
196 while (Link
!= &Private
->NonTestedMemRanList
) {
197 Range
= NONTESTED_MEMORY_RANGE_FROM_LINK (Link
);
199 ConvertToTestedMemory (
202 Range
->Capabilities
&~
203 (EFI_MEMORY_PRESENT
| EFI_MEMORY_INITIALIZED
| EFI_MEMORY_TESTED
| EFI_MEMORY_RUNTIME
)
205 Link
= Link
->ForwardLink
;
212 Test a range of the memory directly .
214 @param[in] Private Point to generic memory test driver's private data.
215 @param[in] StartAddress Starting address of the memory range to be tested.
216 @param[in] Length Length in bytes of the memory range to be tested.
217 @param[in] Capabilities The bit mask of attributes that the memory range supports.
219 @retval EFI_SUCCESS Successful test the range of memory.
220 @retval Others Failed to test the range of memory.
225 IN GENERIC_MEMORY_TEST_PRIVATE
*Private
,
226 IN EFI_PHYSICAL_ADDRESS StartAddress
,
228 IN UINT64 Capabilities
234 // Perform a dummy memory test, so directly write the pattern to all range
236 WriteMemory (Private
, StartAddress
, Length
);
239 // Verify the memory range
241 Status
= VerifyMemory (Private
, StartAddress
, Length
);
242 if (EFI_ERROR (Status
)) {
246 // Add the tested compatible memory to system memory using GCD service
248 ConvertToTestedMemory (
252 (EFI_MEMORY_PRESENT
| EFI_MEMORY_INITIALIZED
| EFI_MEMORY_TESTED
| EFI_MEMORY_RUNTIME
)
259 Construct the system non-tested memory range through GCD service.
261 @param[in] Private Point to generic memory test driver's private data.
263 @retval EFI_SUCCESS Successful construct the non-tested memory range through GCD service.
264 @retval EFI_OUT_OF_RESOURCE Could not allocate needed resource from base memory.
265 @retval Others Failed to construct non-tested memory range through GCD service.
269 ConstructNonTestedMemoryRange (
270 IN GENERIC_MEMORY_TEST_PRIVATE
*Private
273 NONTESTED_MEMORY_RANGE
*Range
;
275 UINTN NumberOfDescriptors
;
276 EFI_GCD_MEMORY_SPACE_DESCRIPTOR
*MemorySpaceMap
;
280 // Non tested memory range may be span 4G here
284 gDS
->GetMemorySpaceMap (&NumberOfDescriptors
, &MemorySpaceMap
);
286 for (Index
= 0; Index
< NumberOfDescriptors
; Index
++) {
287 if (MemorySpaceMap
[Index
].GcdMemoryType
== EfiGcdMemoryTypeReserved
&&
288 (MemorySpaceMap
[Index
].Capabilities
& (EFI_MEMORY_PRESENT
| EFI_MEMORY_INITIALIZED
| EFI_MEMORY_TESTED
)) ==
289 (EFI_MEMORY_PRESENT
| EFI_MEMORY_INITIALIZED
)
293 // Light version do not need to process >4G memory range
297 sizeof (NONTESTED_MEMORY_RANGE
),
301 Range
->Signature
= EFI_NONTESTED_MEMORY_RANGE_SIGNATURE
;
302 Range
->StartAddress
= MemorySpaceMap
[Index
].BaseAddress
;
303 Range
->Length
= MemorySpaceMap
[Index
].Length
;
304 Range
->Capabilities
= MemorySpaceMap
[Index
].Capabilities
;
306 mNonTestedSystemMemory
+= MemorySpaceMap
[Index
].Length
;
307 InsertTailList (&Private
->NonTestedMemRanList
, &Range
->Link
);
312 return EFI_NOT_FOUND
;
319 Write the memory test pattern into a range of physical memory.
321 @param[in] Private Point to generic memory test driver's private data.
322 @param[in] Start The memory range's start address.
323 @param[in] Size The memory range's size.
325 @retval EFI_SUCCESS Successful write the test pattern into the non-tested memory.
326 @retval Others The test pattern may not really write into the physical memory.
331 IN GENERIC_MEMORY_TEST_PRIVATE
*Private
,
332 IN EFI_PHYSICAL_ADDRESS Start
,
336 EFI_PHYSICAL_ADDRESS Address
;
341 // Add 4G memory address check for IA32 platform
342 // NOTE: Without page table, there is no way to use memory above 4G.
344 if (Start
+ Size
> MAX_ADDRESS
) {
348 while (Address
< (Start
+ Size
)) {
349 CopyMem ((VOID
*) (UINTN
) Address
, Private
->MonoPattern
, Private
->MonoTestSize
);
350 Address
+= Private
->CoverageSpan
;
353 // bug bug: we may need GCD service to make the code cache and data uncache,
354 // if GCD do not support it or return fail, then just flush the whole cache.
356 if (Private
->Cpu
!= NULL
) {
357 Private
->Cpu
->FlushDataCache (Private
->Cpu
, Start
, Size
, EfiCpuFlushTypeWriteBackInvalidate
);
364 Verify the range of physical memory which covered by memory test pattern.
366 This function will also do not return any informatin just cause system reset,
367 because the handle error encount fatal error and disable the bad DIMMs.
369 @param[in] Private Point to generic memory test driver's private data.
370 @param[in] Start The memory range's start address.
371 @param[in] Size The memory range's size.
373 @retval EFI_SUCCESS Successful verify the range of memory, no errors' location found.
374 @retval Others The range of memory have errors contained.
379 IN GENERIC_MEMORY_TEST_PRIVATE
*Private
,
380 IN EFI_PHYSICAL_ADDRESS Start
,
384 EFI_PHYSICAL_ADDRESS Address
;
386 EFI_MEMORY_EXTENDED_ERROR_DATA
*ExtendedErrorData
;
389 ExtendedErrorData
= NULL
;
392 // Add 4G memory address check for IA32 platform
393 // NOTE: Without page table, there is no way to use memory above 4G.
395 if (Start
+ Size
> MAX_ADDRESS
) {
400 // Use the software memory test to check whether have detected miscompare
401 // error here. If there is miscompare error here then check if generic
402 // memory test driver can disable the bad DIMM.
404 while (Address
< (Start
+ Size
)) {
405 ErrorFound
= CompareMemWithoutCheckArgument (
406 (VOID
*) (UINTN
) (Address
),
407 Private
->MonoPattern
,
408 Private
->MonoTestSize
410 if (ErrorFound
!= 0) {
412 // Report uncorrectable errors
414 ExtendedErrorData
= AllocateZeroPool (sizeof (EFI_MEMORY_EXTENDED_ERROR_DATA
));
415 if (ExtendedErrorData
== NULL
) {
416 return EFI_OUT_OF_RESOURCES
;
419 ExtendedErrorData
->DataHeader
.HeaderSize
= (UINT16
) sizeof (EFI_STATUS_CODE_DATA
);
420 ExtendedErrorData
->DataHeader
.Size
= (UINT16
) (sizeof (EFI_MEMORY_EXTENDED_ERROR_DATA
) - sizeof (EFI_STATUS_CODE_DATA
));
421 ExtendedErrorData
->Granularity
= EFI_MEMORY_ERROR_DEVICE
;
422 ExtendedErrorData
->Operation
= EFI_MEMORY_OPERATION_READ
;
423 ExtendedErrorData
->Syndrome
= 0x0;
424 ExtendedErrorData
->Address
= Address
;
425 ExtendedErrorData
->Resolution
= 0x40;
427 REPORT_STATUS_CODE_EX (
429 EFI_COMPUTING_UNIT_MEMORY
| EFI_CU_MEMORY_EC_UNCORRECTABLE
,
431 &gEfiGenericMemTestProtocolGuid
,
433 (UINT8
*) ExtendedErrorData
+ sizeof (EFI_STATUS_CODE_DATA
),
434 ExtendedErrorData
->DataHeader
.Size
437 return EFI_DEVICE_ERROR
;
440 Address
+= Private
->CoverageSpan
;
447 Initialize the generic memory test.
449 @param[in] This The protocol instance pointer.
450 @param[in] Level The coverage level of the memory test.
451 @param[out] RequireSoftECCInit Indicate if the memory need software ECC init.
453 @retval EFI_SUCCESS The generic memory test is initialized correctly.
454 @retval EFI_NO_MEDIA The system had no memory to be tested.
459 InitializeMemoryTest (
460 IN EFI_GENERIC_MEMORY_TEST_PROTOCOL
*This
,
461 IN EXTENDMEM_COVERAGE_LEVEL Level
,
462 OUT BOOLEAN
*RequireSoftECCInit
466 GENERIC_MEMORY_TEST_PRIVATE
*Private
;
467 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
469 Private
= GENERIC_MEMORY_TEST_PRIVATE_FROM_THIS (This
);
470 *RequireSoftECCInit
= FALSE
;
473 // This is initialize for default value, but some value may be reset base on
474 // platform memory test driver.
476 Private
->CoverLevel
= Level
;
477 Private
->BdsBlockSize
= TEST_BLOCK_SIZE
;
478 Private
->MonoPattern
= GenericMemoryTestMonoPattern
;
479 Private
->MonoTestSize
= GENERIC_CACHELINE_SIZE
;
482 // Initialize several internal link list
484 InitializeListHead (&Private
->NonTestedMemRanList
);
487 // Construct base memory range
489 ConstructBaseMemoryRange (Private
);
492 // get the cpu arch protocol to support flash cache
494 Status
= gBS
->LocateProtocol (
495 &gEfiCpuArchProtocolGuid
,
499 if (!EFI_ERROR (Status
)) {
503 // Create the CoverageSpan of the memory test base on the coverage level
505 switch (Private
->CoverLevel
) {
507 Private
->CoverageSpan
= GENERIC_CACHELINE_SIZE
;
511 Private
->CoverageSpan
= SPARSE_SPAN_SIZE
;
515 // Even the BDS do not need to test any memory, but in some case it
516 // still need to init ECC memory.
519 Private
->CoverageSpan
= QUICK_SPAN_SIZE
;
523 // This is the first time we construct the non-tested memory range, if no
524 // extended memory found, we know the system have not any extended memory
527 Status
= ConstructNonTestedMemoryRange (Private
);
528 if (Status
== EFI_NOT_FOUND
) {
532 // ready to perform the R/W/V memory test
534 mTestedSystemMemory
= Private
->BaseMemorySize
;
535 mCurrentLink
= Private
->NonTestedMemRanList
.ForwardLink
;
536 mCurrentRange
= NONTESTED_MEMORY_RANGE_FROM_LINK (mCurrentLink
);
537 mCurrentAddress
= mCurrentRange
->StartAddress
;
543 Perform the memory test.
545 @param[in] This The protocol instance pointer.
546 @param[out] TestedMemorySize Return the tested extended memory size.
547 @param[out] TotalMemorySize Return the whole system physical memory size.
548 The total memory size does not include memory in a slot with a disabled DIMM.
549 @param[out] ErrorOut TRUE if the memory error occured.
550 @param[in] IfTestAbort Indicates that the user pressed "ESC" to skip the memory test.
552 @retval EFI_SUCCESS One block of memory passed the test.
553 @retval EFI_NOT_FOUND All memory blocks have already been tested.
554 @retval EFI_DEVICE_ERROR Memory device error occured, and no agent can handle it.
559 GenPerformMemoryTest (
560 IN EFI_GENERIC_MEMORY_TEST_PROTOCOL
*This
,
561 OUT UINT64
*TestedMemorySize
,
562 OUT UINT64
*TotalMemorySize
,
563 OUT BOOLEAN
*ErrorOut
,
568 GENERIC_MEMORY_TEST_PRIVATE
*Private
;
569 EFI_MEMORY_RANGE_EXTENDED_DATA
*RangeData
;
570 UINT64 BlockBoundary
;
572 Private
= GENERIC_MEMORY_TEST_PRIVATE_FROM_THIS (This
);
578 // In extensive mode the boundary of "mCurrentRange->Length" may will lost
579 // some range that is not Private->BdsBlockSize size boundary, so need
580 // the software mechanism to confirm all memory location be covered.
582 if (mCurrentAddress
< (mCurrentRange
->StartAddress
+ mCurrentRange
->Length
)) {
583 if ((mCurrentAddress
+ Private
->BdsBlockSize
) <= (mCurrentRange
->StartAddress
+ mCurrentRange
->Length
)) {
584 BlockBoundary
= Private
->BdsBlockSize
;
586 BlockBoundary
= mCurrentRange
->StartAddress
+ mCurrentRange
->Length
- mCurrentAddress
;
589 // If TestAbort is true, means user cancel the memory test
591 if (!TestAbort
&& Private
->CoverLevel
!= IGNORE
) {
593 // Report status code of every memory range
595 RangeData
= AllocateZeroPool (sizeof (EFI_MEMORY_RANGE_EXTENDED_DATA
));
596 if (RangeData
== NULL
) {
597 return EFI_OUT_OF_RESOURCES
;
599 RangeData
->DataHeader
.HeaderSize
= (UINT16
) sizeof (EFI_STATUS_CODE_DATA
);
600 RangeData
->DataHeader
.Size
= (UINT16
) (sizeof (EFI_MEMORY_RANGE_EXTENDED_DATA
) - sizeof (EFI_STATUS_CODE_DATA
));
601 RangeData
->Start
= mCurrentAddress
;
602 RangeData
->Length
= BlockBoundary
;
604 REPORT_STATUS_CODE_EX (
606 EFI_COMPUTING_UNIT_MEMORY
| EFI_CU_MEMORY_PC_TEST
,
608 &gEfiGenericMemTestProtocolGuid
,
610 (UINT8
*) RangeData
+ sizeof (EFI_STATUS_CODE_DATA
),
611 RangeData
->DataHeader
.Size
615 // The software memory test (R/W/V) perform here. It will detect the
616 // memory mis-compare error.
618 WriteMemory (Private
, mCurrentAddress
, BlockBoundary
);
620 Status
= VerifyMemory (Private
, mCurrentAddress
, BlockBoundary
);
621 if (EFI_ERROR (Status
)) {
623 // If perform here, means there is mis-compare error, and no agent can
624 // handle it, so we return to BDS EFI_DEVICE_ERROR.
627 return EFI_DEVICE_ERROR
;
631 mTestedSystemMemory
+= BlockBoundary
;
632 *TestedMemorySize
= mTestedSystemMemory
;
635 // If the memory test restart after the platform driver disable dimms,
636 // the NonTestSystemMemory may be changed, but the base memory size will
637 // not changed, so we can get the current total memory size.
639 *TotalMemorySize
= Private
->BaseMemorySize
+ mNonTestedSystemMemory
;
642 // Update the current test address pointing to next BDS BLOCK
644 mCurrentAddress
+= Private
->BdsBlockSize
;
649 // Change to next non tested memory range
651 mCurrentLink
= mCurrentLink
->ForwardLink
;
652 if (mCurrentLink
!= &Private
->NonTestedMemRanList
) {
653 mCurrentRange
= NONTESTED_MEMORY_RANGE_FROM_LINK (mCurrentLink
);
654 mCurrentAddress
= mCurrentRange
->StartAddress
;
658 // Here means all the memory test have finished
660 *TestedMemorySize
= mTestedSystemMemory
;
661 *TotalMemorySize
= Private
->BaseMemorySize
+ mNonTestedSystemMemory
;
662 return EFI_NOT_FOUND
;
668 Finish the memory test.
670 @param[in] This The protocol instance pointer.
672 @retval EFI_SUCCESS Success. All resources used in the memory test are freed.
677 GenMemoryTestFinished (
678 IN EFI_GENERIC_MEMORY_TEST_PROTOCOL
*This
682 GENERIC_MEMORY_TEST_PRIVATE
*Private
;
684 Private
= GENERIC_MEMORY_TEST_PRIVATE_FROM_THIS (This
);
687 // Perform Data and Address line test
689 Status
= PerformAddressDataLineTest (Private
);
690 ASSERT_EFI_ERROR (Status
);
693 // Add the non tested memory range to system memory map through GCD service
695 UpdateMemoryMap (Private
);
698 // we need to free all the memory allocate
700 DestroyLinkList (Private
);
706 Provides the capability to test the compatible range used by some special drivers.
708 @param[in] This The protocol instance pointer.
709 @param[in] StartAddress The start address of the compatible memory range that
711 @param[in] Length The compatible memory range's length.
713 @retval EFI_SUCCESS The compatible memory range pass the memory test.
714 @retval EFI_INVALID_PARAMETER The compatible memory range are not below Low 16M.
719 GenCompatibleRangeTest (
720 IN EFI_GENERIC_MEMORY_TEST_PROTOCOL
*This
,
721 IN EFI_PHYSICAL_ADDRESS StartAddress
,
726 GENERIC_MEMORY_TEST_PRIVATE
*Private
;
727 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
728 EFI_PHYSICAL_ADDRESS CurrentBase
;
729 UINT64 CurrentLength
;
731 Private
= GENERIC_MEMORY_TEST_PRIVATE_FROM_THIS (This
);
734 // Check if the parameter is below 16MB
736 if (StartAddress
+ Length
> 0x1000000) {
737 return EFI_INVALID_PARAMETER
;
739 CurrentBase
= StartAddress
;
742 // Check the required memory range status; if the required memory range span
743 // the different GCD memory descriptor, it may be cause different action.
745 Status
= gDS
->GetMemorySpaceDescriptor (
749 if (EFI_ERROR (Status
)) {
753 if (Descriptor
.GcdMemoryType
== EfiGcdMemoryTypeReserved
&&
754 (Descriptor
.Capabilities
& (EFI_MEMORY_PRESENT
| EFI_MEMORY_INITIALIZED
| EFI_MEMORY_TESTED
)) ==
755 (EFI_MEMORY_PRESENT
| EFI_MEMORY_INITIALIZED
)
757 CurrentLength
= Descriptor
.BaseAddress
+ Descriptor
.Length
- CurrentBase
;
758 if (CurrentBase
+ CurrentLength
> StartAddress
+ Length
) {
759 CurrentLength
= StartAddress
+ Length
- CurrentBase
;
761 Status
= DirectRangeTest (
765 Descriptor
.Capabilities
767 if (EFI_ERROR (Status
)) {
771 CurrentBase
= Descriptor
.BaseAddress
+ Descriptor
.Length
;
772 } while (CurrentBase
< StartAddress
+ Length
);
774 // Here means the required range already be tested, so just return success.
780 Perform the address line walking ones test.
782 @param[in] Private Point to generic memory test driver's private data.
784 @retval EFI_SUCCESS Successful finished walking ones test.
785 @retval EFI_OUT_OF_RESOURCE Could not get resource in base memory.
786 @retval EFI_ACCESS_DENIED Code may can not run here because if walking one test
787 failed, system may be already halt.
791 PerformAddressDataLineTest (
792 IN GENERIC_MEMORY_TEST_PRIVATE
*Private
795 LIST_ENTRY
*ExtendedLink
;
796 NONTESTED_MEMORY_RANGE
*ExtendedRange
;
797 BOOLEAN InExtendedRange
;
798 EFI_PHYSICAL_ADDRESS TestAddress
;
801 // Light version no data line test, only perform the address line test
803 TestAddress
= (EFI_PHYSICAL_ADDRESS
) 0x1;
804 while (TestAddress
< MAX_ADDRESS
&& TestAddress
> 0) {
806 // only test if the address falls in the enabled range
808 InExtendedRange
= FALSE
;
809 ExtendedLink
= Private
->NonTestedMemRanList
.BackLink
;
810 while (ExtendedLink
!= &Private
->NonTestedMemRanList
) {
811 ExtendedRange
= NONTESTED_MEMORY_RANGE_FROM_LINK (ExtendedLink
);
812 if ((TestAddress
>= ExtendedRange
->StartAddress
) &&
813 (TestAddress
< (ExtendedRange
->StartAddress
+ ExtendedRange
->Length
))
815 InExtendedRange
= TRUE
;
818 ExtendedLink
= ExtendedLink
->BackLink
;
821 if (InExtendedRange
) {
822 *(EFI_PHYSICAL_ADDRESS
*) (UINTN
) TestAddress
= TestAddress
;
823 Private
->Cpu
->FlushDataCache (Private
->Cpu
, TestAddress
, 1, EfiCpuFlushTypeWriteBackInvalidate
);
824 if (*(EFI_PHYSICAL_ADDRESS
*) (UINTN
) TestAddress
!= TestAddress
) {
825 return EFI_ACCESS_DENIED
;
829 TestAddress
= LShiftU64 (TestAddress
, 1);
837 GENERIC_MEMORY_TEST_PRIVATE mGenericMemoryTestPrivate
= {
838 EFI_GENERIC_MEMORY_TEST_PRIVATE_SIGNATURE
,
842 InitializeMemoryTest
,
843 GenPerformMemoryTest
,
844 GenMemoryTestFinished
,
845 GenCompatibleRangeTest
847 (EXTENDMEM_COVERAGE_LEVEL
) 0,
860 The generic memory test driver's entry point.
862 It initializes private data to default value.
864 @param[in] ImageHandle The firmware allocated handle for the EFI image.
865 @param[in] SystemTable A pointer to the EFI System Table.
867 @retval EFI_SUCCESS The entry point is executed successfully.
868 @retval EFI_NOT_FOUND Can't find HandOff Hob in HobList.
869 @retval other Some error occurs when executing this entry point.
874 GenericMemoryTestEntryPoint (
875 IN EFI_HANDLE ImageHandle
,
876 IN EFI_SYSTEM_TABLE
*SystemTable
881 EFI_BOOT_MODE BootMode
;
882 EFI_PEI_HOB_POINTERS Hob
;
885 // Use the generic pattern to test compatible memory range
887 mGenericMemoryTestPrivate
.MonoPattern
= GenericMemoryTestMonoPattern
;
888 mGenericMemoryTestPrivate
.MonoTestSize
= GENERIC_CACHELINE_SIZE
;
891 // Get the platform boot mode
893 HobList
= GetHobList ();
896 if (Hob
.Header
->HobType
!= EFI_HOB_TYPE_HANDOFF
) {
897 return EFI_NOT_FOUND
;
900 BootMode
= Hob
.HandoffInformationTable
->BootMode
;
903 // Get the platform boot mode and create the default memory test coverage
904 // level and span size for compatible memory test using
907 case BOOT_WITH_FULL_CONFIGURATION
:
908 case BOOT_WITH_DEFAULT_SETTINGS
:
909 mGenericMemoryTestPrivate
.CoverageSpan
= SPARSE_SPAN_SIZE
;
912 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS
:
913 mGenericMemoryTestPrivate
.CoverageSpan
= GENERIC_CACHELINE_SIZE
;
917 mGenericMemoryTestPrivate
.CoverageSpan
= QUICK_SPAN_SIZE
;
921 // Install the protocol
923 Status
= gBS
->InstallProtocolInterface (
924 &mGenericMemoryTestPrivate
.Handle
,
925 &gEfiGenericMemTestProtocolGuid
,
926 EFI_NATIVE_INTERFACE
,
927 &mGenericMemoryTestPrivate
.GenericMemoryTest