TianoCore EDK2 master
Loading...
Searching...
No Matches
Diagnostics.c
Go to the documentation of this file.
1
10#include <Uefi.h>
11#include <Library/DebugLib.h>
14#include <Library/BaseLib.h>
15
16#include "Mmc.h"
17
18#define DIAGNOSTIC_LOGBUFFER_MAXCHAR 1024
19
20CHAR16 *mLogBuffer = NULL;
21UINTN mLogRemainChar = 0;
22
23CHAR16 *
24DiagnosticInitLog (
25 UINTN MaxBufferChar
26 )
27{
28 mLogRemainChar = MaxBufferChar;
29 mLogBuffer = AllocatePool ((UINTN)MaxBufferChar * sizeof (CHAR16));
30 return mLogBuffer;
31}
32
34DiagnosticLog (
35 CONST CHAR16 *Str
36 )
37{
38 UINTN len = StrLen (Str);
39
40 if (len < mLogRemainChar) {
41 StrCpyS (mLogBuffer, mLogRemainChar, Str);
42 mLogRemainChar -= len;
43 mLogBuffer += len;
44 return len;
45 } else {
46 return 0;
47 }
48}
49
50VOID
51GenerateRandomBuffer (
52 VOID *Buffer,
53 UINTN BufferSize
54 )
55{
56 UINT64 i;
57 UINT64 *Buffer64 = (UINT64 *)Buffer;
58
59 for (i = 0; i < (BufferSize >> 3); i++) {
60 *Buffer64 = i | LShiftU64 (~i, 32);
61 Buffer64++;
62 }
63}
64
65BOOLEAN
66CompareBuffer (
67 VOID *BufferA,
68 VOID *BufferB,
69 UINTN BufferSize
70 )
71{
72 UINTN i;
73 UINT64 *BufferA64 = (UINT64 *)BufferA;
74 UINT64 *BufferB64 = (UINT64 *)BufferB;
75
76 for (i = 0; i < (BufferSize >> 3); i++) {
77 if (*BufferA64 != *BufferB64) {
78 DEBUG ((DEBUG_ERROR, "CompareBuffer: Error at %i", i));
79 DEBUG ((DEBUG_ERROR, "(0x%lX) != (0x%lX)\n", *BufferA64, *BufferB64));
80 return FALSE;
81 }
82
83 BufferA64++;
84 BufferB64++;
85 }
86
87 return TRUE;
88}
89
91MmcReadWriteDataTest (
92 MMC_HOST_INSTANCE *MmcHostInstance,
93 EFI_LBA Lba,
94 UINTN BufferSize
95 )
96{
97 VOID *BackBuffer;
98 VOID *WriteBuffer;
99 VOID *ReadBuffer;
100 EFI_STATUS Status;
101
102 // Check if a Media is Present
103 if (!MmcHostInstance->BlockIo.Media->MediaPresent) {
104 DiagnosticLog (L"ERROR: No Media Present\n");
105 return EFI_NO_MEDIA;
106 }
107
108 if (MmcHostInstance->State != MmcTransferState) {
109 DiagnosticLog (L"ERROR: Not ready for Transfer state\n");
110 return EFI_NOT_READY;
111 }
112
113 BackBuffer = AllocatePool (BufferSize);
114 WriteBuffer = AllocatePool (BufferSize);
115 ReadBuffer = AllocatePool (BufferSize);
116
117 // Read (and save) buffer at a specific location
118 Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId, Lba, BufferSize, BackBuffer);
119 if (Status != EFI_SUCCESS) {
120 DiagnosticLog (L"ERROR: Fail to Read Block (1)\n");
121 return Status;
122 }
123
124 // Write buffer at the same location
125 GenerateRandomBuffer (WriteBuffer, BufferSize);
126 Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId, Lba, BufferSize, WriteBuffer);
127 if (Status != EFI_SUCCESS) {
128 DiagnosticLog (L"ERROR: Fail to Write Block (1)\n");
129 return Status;
130 }
131
132 // Read the buffer at the same location
133 Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId, Lba, BufferSize, ReadBuffer);
134 if (Status != EFI_SUCCESS) {
135 DiagnosticLog (L"ERROR: Fail to Read Block (2)\n");
136 return Status;
137 }
138
139 // Check that is conform
140 if (!CompareBuffer (ReadBuffer, WriteBuffer, BufferSize)) {
141 DiagnosticLog (L"ERROR: Fail to Read/Write Block (1)\n");
142 return EFI_INVALID_PARAMETER;
143 }
144
145 // Restore content at the original location
146 Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId, Lba, BufferSize, BackBuffer);
147 if (Status != EFI_SUCCESS) {
148 DiagnosticLog (L"ERROR: Fail to Write Block (2)\n");
149 return Status;
150 }
151
152 // Read the restored content
153 Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId, Lba, BufferSize, ReadBuffer);
154 if (Status != EFI_SUCCESS) {
155 DiagnosticLog (L"ERROR: Fail to Read Block (3)\n");
156 return Status;
157 }
158
159 // Check the content is correct
160 if (!CompareBuffer (ReadBuffer, BackBuffer, BufferSize)) {
161 DiagnosticLog (L"ERROR: Fail to Read/Write Block (2)\n");
162 return EFI_INVALID_PARAMETER;
163 }
164
165 return EFI_SUCCESS;
166}
167
169EFIAPI
170MmcDriverDiagnosticsRunDiagnostics (
172 IN EFI_HANDLE ControllerHandle,
173 IN EFI_HANDLE ChildHandle OPTIONAL,
174 IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,
175 IN CHAR8 *Language,
176 OUT EFI_GUID **ErrorType,
177 OUT UINTN *BufferSize,
178 OUT CHAR16 **Buffer
179 )
180{
181 LIST_ENTRY *CurrentLink;
182 MMC_HOST_INSTANCE *MmcHostInstance;
183 EFI_STATUS Status;
184
185 if ((Language == NULL) ||
186 (ErrorType == NULL) ||
187 (Buffer == NULL) ||
188 (ControllerHandle == NULL) ||
189 (BufferSize == NULL))
190 {
191 return EFI_INVALID_PARAMETER;
192 }
193
194 // Check Language is supported (i.e. is "en-*" - only English is supported)
195 if (AsciiStrnCmp (Language, "en", 2) != 0) {
196 return EFI_UNSUPPORTED;
197 }
198
199 Status = EFI_SUCCESS;
200 *ErrorType = NULL;
201 *BufferSize = DIAGNOSTIC_LOGBUFFER_MAXCHAR;
202 *Buffer = DiagnosticInitLog (DIAGNOSTIC_LOGBUFFER_MAXCHAR);
203
204 DiagnosticLog (L"MMC Driver Diagnostics\n");
205
206 // Find the MMC Host instance on which we have been asked to run diagnostics
207 MmcHostInstance = NULL;
208 CurrentLink = mMmcHostPool.ForwardLink;
209 while (CurrentLink != NULL && CurrentLink != &mMmcHostPool && (Status == EFI_SUCCESS)) {
210 MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK (CurrentLink);
211 ASSERT (MmcHostInstance != NULL);
212 if (MmcHostInstance->MmcHandle == ControllerHandle) {
213 break;
214 }
215
216 CurrentLink = CurrentLink->ForwardLink;
217 }
218
219 // If we didn't find the controller, return EFI_UNSUPPORTED
220 if ( (MmcHostInstance == NULL)
221 || (MmcHostInstance->MmcHandle != ControllerHandle))
222 {
223 return EFI_UNSUPPORTED;
224 }
225
226 // LBA=1 Size=BlockSize
227 DiagnosticLog (L"MMC Driver Diagnostics - Test: First Block\n");
228 Status = MmcReadWriteDataTest (MmcHostInstance, 1, MmcHostInstance->BlockIo.Media->BlockSize);
229
230 // LBA=2 Size=BlockSize
231 DiagnosticLog (L"MMC Driver Diagnostics - Test: Second Block\n");
232 Status = MmcReadWriteDataTest (MmcHostInstance, 2, MmcHostInstance->BlockIo.Media->BlockSize);
233
234 // LBA=10 Size=BlockSize
235 DiagnosticLog (L"MMC Driver Diagnostics - Test: Any Block\n");
236 Status = MmcReadWriteDataTest (
237 MmcHostInstance,
238 RShiftU64 (MmcHostInstance->BlockIo.Media->LastBlock, 1),
239 MmcHostInstance->BlockIo.Media->BlockSize
240 );
241
242 // LBA=LastBlock Size=BlockSize
243 DiagnosticLog (L"MMC Driver Diagnostics - Test: Last Block\n");
244 Status = MmcReadWriteDataTest (MmcHostInstance, MmcHostInstance->BlockIo.Media->LastBlock, MmcHostInstance->BlockIo.Media->BlockSize);
245
246 // LBA=1 Size=2*BlockSize
247 DiagnosticLog (L"MMC Driver Diagnostics - Test: First Block / 2 BlockSSize\n");
248 Status = MmcReadWriteDataTest (MmcHostInstance, 1, 2 * MmcHostInstance->BlockIo.Media->BlockSize);
249
250 return Status;
251}
252
253//
254// EFI Driver Diagnostics 2 Protocol
255//
257 (EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS)MmcDriverDiagnosticsRunDiagnostics,
258 "en"
259};
UINT64 UINTN
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
INTN EFIAPI AsciiStrnCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString, IN UINTN Length)
Definition: String.c:872
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
EFI_STATUS(EFIAPI * EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS)(IN EFI_DRIVER_DIAGNOSTICS2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType, IN CHAR8 *Language, OUT EFI_GUID **ErrorType, OUT UINTN *BufferSize, OUT CHAR16 **Buffer)
EFI_DRIVER_DIAGNOSTIC_TYPE
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS EFIAPI MmcReadBlocks(IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, OUT VOID *Buffer)
Definition: MmcBlockIo.c:374
EFI_STATUS EFIAPI MmcWriteBlocks(IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, IN VOID *Buffer)
Definition: MmcBlockIo.c:387
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_LBA
Definition: UefiBaseType.h:45
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BLOCK_IO_MEDIA * Media
Definition: BlockIo.h:224
UINT32 BlockSize
Definition: BlockIo.h:167
EFI_LBA LastBlock
Definition: BlockIo.h:178
BOOLEAN MediaPresent
Definition: BlockIo.h:144
Definition: Base.h:213