2 Null instance of Memory Test Library.
4 Copyright (c) 2009, Intel Corporation.<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/MemoryTestLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/CacheMaintenanceLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/PcdLib.h>
20 #include <Library/ReportStatusCodeLib.h>
23 UINT32 TestPattern
[] = {
43 Internal function to compare two memory buffers of a given length.
45 This is the internal function to compare two memory buffers. We cannot
46 use CompareMem() in BaseLib, for that function ASSERT when buffer address
49 @param DestinationBuffer First memory buffer
50 @param SourceBuffer Second memory buffer
51 @param Length Length of DestinationBuffer and SourceBuffer memory
54 @return 0 All Length bytes of the two buffers are identical.
55 @retval Non-zero The first mismatched byte in SourceBuffer subtracted from the first
56 mismatched byte in DestinationBuffer.
61 IN CONST VOID
*DestinationBuffer
,
62 IN CONST VOID
*SourceBuffer
,
66 while ((--Length
!= 0) &&
67 (*(INT8
*)DestinationBuffer
== *(INT8
*)SourceBuffer
)) {
68 DestinationBuffer
= (INT8
*)DestinationBuffer
+ 1;
69 SourceBuffer
= (INT8
*)SourceBuffer
+ 1;
71 return (INTN
)*(UINT8
*)DestinationBuffer
- (INTN
)*(UINT8
*)SourceBuffer
;
75 Internal worker function for system memory range test.
77 This function is the internal worker function for system memory range test.
78 It writes test pattern to memory range and then reads back to check if memory
81 @param StartAddress Start address of the memory range to test.
82 @param Length Length of the memory range to test.
83 @param ErrorAddress Address of the memory where error is encountered.
85 @retval RETURN_SUCCESS The memory range passes test.
86 @retval RETURN_DEVICE_ERROR The memory range does not pass test.
91 IN VOID
*StartAddress
,
94 OUT VOID
**ErrorAddress
100 // Make sure we don't try and test anything above the max physical address range
102 ASSERT ((UINTN
) StartAddress
+ Length
< MAX_ADDRESS
);
104 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, PcdGet32 (PcdStatusCodeValueMemoryTestStarted
));
107 // Write the test pattern into memory range
109 TempAddress
= StartAddress
;
110 while ((UINTN
) TempAddress
< (UINTN
) StartAddress
+ Length
) {
111 CopyMem (TempAddress
, TestPattern
, sizeof (TestPattern
));
112 TempAddress
= (VOID
*) ((UINTN
) TempAddress
+ SpanSize
);
116 // Write back and invalidate cache to make sure data is in memory
118 WriteBackInvalidateDataCacheRange (StartAddress
, (UINTN
) Length
);
121 // Read pattern from memory and compare it
123 TempAddress
= StartAddress
;
124 while ((UINTN
) TempAddress
< (UINTN
) StartAddress
+ Length
) {
125 if (CompareMemoryWorker (TempAddress
, TestPattern
, sizeof (TestPattern
)) != 0) {
127 // Value read back does not equal to the value written, so error is detected.
129 *ErrorAddress
= TempAddress
;
130 REPORT_STATUS_CODE (EFI_ERROR_CODE
| EFI_ERROR_UNRECOVERED
, PcdGet32 (PcdStatusCodeValueUncorrectableMemoryError
));
132 return RETURN_DEVICE_ERROR
;
135 TempAddress
= (VOID
*) ((UINTN
) TempAddress
+ SpanSize
);
138 return RETURN_SUCCESS
;
142 Perform a quick system memory range test.
144 This function performs a quick system memory range test. It leads to quick performance
145 but least reliability.
147 @param StartAddress Start address of the memory range to test.
148 @param Length Length of the memory range to test.
149 @param ErrorAddress Address of the memory where error is encountered.
151 @retval RETURN_SUCCESS The memory range passes test.
152 @retval RETURN_DEVICE_ERROR The memory range does not pass test.
158 IN VOID
*StartAddress
,
160 OUT VOID
**ErrorAddress
163 RETURN_STATUS Status
;
165 Status
= MemoryTestWorker (
168 sizeof (TestPattern
) * 0x20000,
176 Test a system memory range with sparsely sampled memory units.
178 This function tests a system memory range, whose memory units
179 are sampled sparsely. It leads to relatively good performance
180 and partial reliability.
182 @param StartAddress Start address of the memory range to test.
183 @param Length Length of the memory range to test.
184 @param ErrorAddress Address of the memory where error is encountered.
186 @retval RETURN_SUCCESS The memory range passes test.
187 @retval RETURN_DEVICE_ERROR The memory range does not pass test.
193 IN VOID
*StartAddress
,
195 OUT VOID
**ErrorAddress
198 RETURN_STATUS Status
;
200 Status
= MemoryTestWorker (
203 sizeof (TestPattern
) * 0x8000,
211 Test a system memory range with extensively sampled memory units.
213 This function tests a system memory range, whose memory units
214 are sampled extensively. Compared with SparseMemoryTest, it achieves
215 more reliability and less performance.
217 @param StartAddress Start address of the memory range to test.
218 @param Length Length of the memory range to test.
219 @param ErrorAddress Address of the memory where error is encountered.
221 @retval RETURN_SUCCESS The memory range passes test.
222 @retval RETURN_DEVICE_ERROR The memory range does not pass test.
227 ExtensiveMemoryTest (
228 IN VOID
*StartAddress
,
230 OUT VOID
**ErrorAddress
233 RETURN_STATUS Status
;
235 Status
= MemoryTestWorker (
238 sizeof (TestPattern
),
246 Check if soft ECC initialzation is needed for system
248 @retval TRUE Soft ECC initialzation is needed.
249 @retval FALSE Soft ECC initialzation is not needed.
254 IsSoftEccInitRequired (