]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - EmbeddedPkg/Universal/MmcDxe/Diagnostics.c
LcdGraphicsOutputDxe: Update FrameBufferSize as per UEFI spec section 11.9
[mirror_edk2.git] / EmbeddedPkg / Universal / MmcDxe / Diagnostics.c
... / ...
CommitLineData
1/** @file\r
2 Diagnostics Protocol implementation for the MMC DXE driver\r
3\r
4 Copyright (c) 2011, ARM Limited. All rights reserved.\r
5 \r
6 This program and the accompanying materials \r
7 are licensed and made available under the terms and conditions of the BSD License \r
8 which accompanies this distribution. The full text of the license may be found at \r
9 http://opensource.org/licenses/bsd-license.php \r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13\r
14**/\r
15\r
16#include <Uefi.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20\r
21#include "Mmc.h"\r
22\r
23#define DIAGNOSTIC_LOGBUFFER_MAXCHAR 1024\r
24\r
25CHAR16* mLogBuffer = NULL;\r
26UINTN mLogRemainChar = 0;\r
27\r
28CHAR16*\r
29DiagnosticInitLog (\r
30 UINTN MaxBufferChar\r
31 )\r
32{\r
33 mLogRemainChar = MaxBufferChar;\r
34 mLogBuffer = AllocatePool ((UINTN)MaxBufferChar * sizeof(CHAR16));\r
35 return mLogBuffer;\r
36}\r
37\r
38UINTN\r
39DiagnosticLog (\r
40 CONST CHAR16* Str\r
41 )\r
42{\r
43 UINTN len = StrLen (Str);\r
44 if (len <= mLogRemainChar) {\r
45 mLogRemainChar -= len;\r
46 StrCpy (mLogBuffer, Str);\r
47 mLogBuffer += len;\r
48 return len;\r
49 } else {\r
50 return 0;\r
51 }\r
52}\r
53\r
54VOID\r
55GenerateRandomBuffer (\r
56 VOID* Buffer,\r
57 UINTN BufferSize\r
58 )\r
59{\r
60 UINT64 i;\r
61 UINT64* Buffer64 = (UINT64*)Buffer;\r
62\r
63 for (i = 0; i < (BufferSize >> 3); i++) {\r
64 *Buffer64 = i | (~i << 32);\r
65 Buffer64++;\r
66 }\r
67}\r
68\r
69BOOLEAN\r
70CompareBuffer (\r
71 VOID *BufferA,\r
72 VOID *BufferB,\r
73 UINTN BufferSize\r
74 )\r
75{\r
76 UINTN i;\r
77 UINT64* BufferA64 = (UINT64*)BufferA;\r
78 UINT64* BufferB64 = (UINT64*)BufferB;\r
79\r
80 for (i = 0; i < (BufferSize >> 3); i++) {\r
81 if (*BufferA64 != *BufferB64) {\r
82 DEBUG((EFI_D_ERROR, "CompareBuffer: Error at %i", i));\r
83 DEBUG((EFI_D_ERROR, "(0x%lX) != (0x%lX)\n", *BufferA64, *BufferB64));\r
84 return FALSE;\r
85 }\r
86 BufferA64++;\r
87 BufferB64++;\r
88 }\r
89 return TRUE;\r
90}\r
91\r
92EFI_STATUS\r
93MmcReadWriteDataTest (\r
94 MMC_HOST_INSTANCE *MmcHostInstance,\r
95 EFI_LBA Lba,\r
96 UINTN BufferSize\r
97 )\r
98{\r
99 VOID *BackBuffer;\r
100 VOID *WriteBuffer;\r
101 VOID *ReadBuffer;\r
102 EFI_STATUS Status;\r
103\r
104 // Check if a Media is Present\r
105 if (!MmcHostInstance->BlockIo.Media->MediaPresent) {\r
106 DiagnosticLog (L"ERROR: No Media Present\n");\r
107 return EFI_NO_MEDIA;\r
108 }\r
109\r
110 if (MmcHostInstance->State != MmcTransferState) {\r
111 DiagnosticLog (L"ERROR: Not ready for Transfer state\n");\r
112 return EFI_NOT_READY;\r
113 }\r
114\r
115 BackBuffer = AllocatePool (BufferSize);\r
116 WriteBuffer = AllocatePool (BufferSize);\r
117 ReadBuffer = AllocatePool (BufferSize);\r
118\r
119 // Read (and save) buffer at a specific location\r
120 Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,BackBuffer);\r
121 if (Status != EFI_SUCCESS) {\r
122 DiagnosticLog (L"ERROR: Fail to Read Block (1)\n");\r
123 return Status;\r
124 }\r
125\r
126 // Write buffer at the same location\r
127 GenerateRandomBuffer (WriteBuffer,BufferSize);\r
128 Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,WriteBuffer);\r
129 if (Status != EFI_SUCCESS) {\r
130 DiagnosticLog (L"ERROR: Fail to Write Block (1)\n");\r
131 return Status;\r
132 }\r
133\r
134 // Read the buffer at the same location\r
135 Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,ReadBuffer);\r
136 if (Status != EFI_SUCCESS) {\r
137 DiagnosticLog (L"ERROR: Fail to Read Block (2)\n");\r
138 return Status;\r
139 }\r
140\r
141 // Check that is conform\r
142 if (!CompareBuffer (ReadBuffer,WriteBuffer,BufferSize)) {\r
143 DiagnosticLog (L"ERROR: Fail to Read/Write Block (1)\n");\r
144 return EFI_INVALID_PARAMETER;\r
145 }\r
146\r
147 // Restore content at the original location\r
148 Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,BackBuffer);\r
149 if (Status != EFI_SUCCESS) {\r
150 DiagnosticLog (L"ERROR: Fail to Write Block (2)\n");\r
151 return Status;\r
152 }\r
153\r
154 // Read the restored content\r
155 Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,ReadBuffer);\r
156 if (Status != EFI_SUCCESS) {\r
157 DiagnosticLog (L"ERROR: Fail to Read Block (3)\n");\r
158 return Status;\r
159 }\r
160\r
161 // Check the content is correct\r
162 if (!CompareBuffer (ReadBuffer,BackBuffer,BufferSize)) {\r
163 DiagnosticLog (L"ERROR: Fail to Read/Write Block (2)\n");\r
164 return EFI_INVALID_PARAMETER;\r
165 }\r
166\r
167 return EFI_SUCCESS;\r
168}\r
169\r
170EFI_STATUS\r
171EFIAPI\r
172MmcDriverDiagnosticsRunDiagnostics (\r
173 IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,\r
174 IN EFI_HANDLE ControllerHandle,\r
175 IN EFI_HANDLE ChildHandle OPTIONAL,\r
176 IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,\r
177 IN CHAR8 *Language,\r
178 OUT EFI_GUID **ErrorType,\r
179 OUT UINTN *BufferSize,\r
180 OUT CHAR16 **Buffer\r
181 )\r
182{\r
183 LIST_ENTRY *CurrentLink;\r
184 MMC_HOST_INSTANCE *MmcHostInstance;\r
185 EFI_STATUS Status;\r
186\r
187 if ((Language == NULL) ||\r
188 (ErrorType == NULL) ||\r
189 (Buffer == NULL) ||\r
190 (ControllerHandle == NULL) ||\r
191 (BufferSize == NULL)) {\r
192 return EFI_INVALID_PARAMETER;\r
193 }\r
194\r
195 Status = EFI_SUCCESS;\r
196 *ErrorType = NULL;\r
197 *BufferSize = DIAGNOSTIC_LOGBUFFER_MAXCHAR;\r
198 *Buffer = DiagnosticInitLog (DIAGNOSTIC_LOGBUFFER_MAXCHAR);\r
199\r
200 DiagnosticLog (L"MMC Driver Diagnostics\n");\r
201\r
202 // For each MMC instance\r
203 CurrentLink = mMmcHostPool.ForwardLink;\r
204 while (CurrentLink != NULL && CurrentLink != &mMmcHostPool && (Status == EFI_SUCCESS)) {\r
205 MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK(CurrentLink);\r
206 ASSERT(MmcHostInstance != NULL);\r
207\r
208 // LBA=1 Size=BlockSize\r
209 DiagnosticLog (L"MMC Driver Diagnostics - Test: First Block\n");\r
210 Status = MmcReadWriteDataTest (MmcHostInstance, 1, MmcHostInstance->BlockIo.Media->BlockSize);\r
211\r
212 // LBA=2 Size=BlockSize\r
213 DiagnosticLog (L"MMC Driver Diagnostics - Test: Second Block\n");\r
214 Status = MmcReadWriteDataTest (MmcHostInstance, 2, MmcHostInstance->BlockIo.Media->BlockSize);\r
215\r
216 // LBA=10 Size=BlockSize\r
217 DiagnosticLog (L"MMC Driver Diagnostics - Test: Any Block\n");\r
218 Status = MmcReadWriteDataTest (MmcHostInstance, MmcHostInstance->BlockIo.Media->LastBlock >> 1, MmcHostInstance->BlockIo.Media->BlockSize);\r
219\r
220 // LBA=LastBlock Size=BlockSize\r
221 DiagnosticLog (L"MMC Driver Diagnostics - Test: Last Block\n");\r
222 Status = MmcReadWriteDataTest (MmcHostInstance, MmcHostInstance->BlockIo.Media->LastBlock, MmcHostInstance->BlockIo.Media->BlockSize);\r
223\r
224 // LBA=1 Size=2*BlockSize\r
225 DiagnosticLog (L"MMC Driver Diagnostics - Test: First Block / 2 BlockSSize\n");\r
226 Status = MmcReadWriteDataTest (MmcHostInstance, 1, 2*MmcHostInstance->BlockIo.Media->BlockSize);\r
227\r
228 CurrentLink = CurrentLink->ForwardLink;\r
229 }\r
230\r
231 return Status;\r
232}\r
233\r
234//\r
235// EFI Driver Diagnostics 2 Protocol\r
236//\r
237GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gMmcDriverDiagnostics2 = {\r
238 (EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS) MmcDriverDiagnosticsRunDiagnostics,\r
239 "en"\r
240};\r