]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Universal/MmcDxe/Diagnostics.c
MmcDxe Diagnostics: return EFI_UNSUPPORTED for Language other than english
[mirror_edk2.git] / EmbeddedPkg / Universal / MmcDxe / Diagnostics.c
CommitLineData
1bfda055 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
c8af31ec 20#include <Library/BaseLib.h>\r
1bfda055 21\r
22#include "Mmc.h"\r
23\r
24#define DIAGNOSTIC_LOGBUFFER_MAXCHAR 1024\r
25\r
26CHAR16* mLogBuffer = NULL;\r
27UINTN mLogRemainChar = 0;\r
28\r
11c20f4e 29CHAR16*\r
30DiagnosticInitLog (\r
31 UINTN MaxBufferChar\r
32 )\r
33{\r
34 mLogRemainChar = MaxBufferChar;\r
c8af31ec 35 mLogBuffer = AllocatePool ((UINTN)MaxBufferChar * sizeof (CHAR16));\r
11c20f4e 36 return mLogBuffer;\r
1bfda055 37}\r
38\r
11c20f4e 39UINTN\r
40DiagnosticLog (\r
41 CONST CHAR16* Str\r
42 )\r
43{\r
44 UINTN len = StrLen (Str);\r
45 if (len <= mLogRemainChar) {\r
46 mLogRemainChar -= len;\r
47 StrCpy (mLogBuffer, Str);\r
48 mLogBuffer += len;\r
49 return len;\r
50 } else {\r
51 return 0;\r
52 }\r
1bfda055 53}\r
54\r
11c20f4e 55VOID\r
56GenerateRandomBuffer (\r
57 VOID* Buffer,\r
58 UINTN BufferSize\r
59 )\r
60{\r
61 UINT64 i;\r
62 UINT64* Buffer64 = (UINT64*)Buffer;\r
1bfda055 63\r
11c20f4e 64 for (i = 0; i < (BufferSize >> 3); i++) {\r
65 *Buffer64 = i | (~i << 32);\r
66 Buffer64++;\r
67 }\r
1bfda055 68}\r
69\r
11c20f4e 70BOOLEAN\r
71CompareBuffer (\r
72 VOID *BufferA,\r
73 VOID *BufferB,\r
74 UINTN BufferSize\r
75 )\r
76{\r
77 UINTN i;\r
78 UINT64* BufferA64 = (UINT64*)BufferA;\r
79 UINT64* BufferB64 = (UINT64*)BufferB;\r
80\r
81 for (i = 0; i < (BufferSize >> 3); i++) {\r
82 if (*BufferA64 != *BufferB64) {\r
c8af31ec
OM
83 DEBUG ((EFI_D_ERROR, "CompareBuffer: Error at %i", i));\r
84 DEBUG ((EFI_D_ERROR, "(0x%lX) != (0x%lX)\n", *BufferA64, *BufferB64));\r
11c20f4e 85 return FALSE;\r
1bfda055 86 }\r
11c20f4e 87 BufferA64++;\r
88 BufferB64++;\r
89 }\r
90 return TRUE;\r
1bfda055 91}\r
92\r
11c20f4e 93EFI_STATUS\r
94MmcReadWriteDataTest (\r
95 MMC_HOST_INSTANCE *MmcHostInstance,\r
96 EFI_LBA Lba,\r
97 UINTN BufferSize\r
98 )\r
99{\r
100 VOID *BackBuffer;\r
101 VOID *WriteBuffer;\r
102 VOID *ReadBuffer;\r
103 EFI_STATUS Status;\r
104\r
105 // Check if a Media is Present\r
106 if (!MmcHostInstance->BlockIo.Media->MediaPresent) {\r
107 DiagnosticLog (L"ERROR: No Media Present\n");\r
108 return EFI_NO_MEDIA;\r
109 }\r
110\r
111 if (MmcHostInstance->State != MmcTransferState) {\r
112 DiagnosticLog (L"ERROR: Not ready for Transfer state\n");\r
113 return EFI_NOT_READY;\r
114 }\r
115\r
116 BackBuffer = AllocatePool (BufferSize);\r
117 WriteBuffer = AllocatePool (BufferSize);\r
118 ReadBuffer = AllocatePool (BufferSize);\r
119\r
120 // Read (and save) buffer at a specific location\r
121 Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,BackBuffer);\r
122 if (Status != EFI_SUCCESS) {\r
123 DiagnosticLog (L"ERROR: Fail to Read Block (1)\n");\r
124 return Status;\r
125 }\r
1bfda055 126\r
11c20f4e 127 // Write buffer at the same location\r
128 GenerateRandomBuffer (WriteBuffer,BufferSize);\r
129 Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,WriteBuffer);\r
130 if (Status != EFI_SUCCESS) {\r
131 DiagnosticLog (L"ERROR: Fail to Write Block (1)\n");\r
132 return Status;\r
133 }\r
1bfda055 134\r
11c20f4e 135 // Read the buffer at the same location\r
136 Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,ReadBuffer);\r
137 if (Status != EFI_SUCCESS) {\r
138 DiagnosticLog (L"ERROR: Fail to Read Block (2)\n");\r
139 return Status;\r
140 }\r
141\r
142 // Check that is conform\r
143 if (!CompareBuffer (ReadBuffer,WriteBuffer,BufferSize)) {\r
144 DiagnosticLog (L"ERROR: Fail to Read/Write Block (1)\n");\r
145 return EFI_INVALID_PARAMETER;\r
146 }\r
147\r
148 // Restore content at the original location\r
149 Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,BackBuffer);\r
150 if (Status != EFI_SUCCESS) {\r
151 DiagnosticLog (L"ERROR: Fail to Write Block (2)\n");\r
152 return Status;\r
153 }\r
1bfda055 154\r
11c20f4e 155 // Read the restored content\r
156 Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,ReadBuffer);\r
157 if (Status != EFI_SUCCESS) {\r
158 DiagnosticLog (L"ERROR: Fail to Read Block (3)\n");\r
159 return Status;\r
160 }\r
1bfda055 161\r
11c20f4e 162 // Check the content is correct\r
163 if (!CompareBuffer (ReadBuffer,BackBuffer,BufferSize)) {\r
164 DiagnosticLog (L"ERROR: Fail to Read/Write Block (2)\n");\r
165 return EFI_INVALID_PARAMETER;\r
166 }\r
1bfda055 167\r
11c20f4e 168 return EFI_SUCCESS;\r
1bfda055 169}\r
170\r
171EFI_STATUS\r
172EFIAPI\r
173MmcDriverDiagnosticsRunDiagnostics (\r
174 IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,\r
175 IN EFI_HANDLE ControllerHandle,\r
176 IN EFI_HANDLE ChildHandle OPTIONAL,\r
177 IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,\r
178 IN CHAR8 *Language,\r
179 OUT EFI_GUID **ErrorType,\r
180 OUT UINTN *BufferSize,\r
181 OUT CHAR16 **Buffer\r
182 )\r
183{\r
11c20f4e 184 LIST_ENTRY *CurrentLink;\r
185 MMC_HOST_INSTANCE *MmcHostInstance;\r
186 EFI_STATUS Status;\r
187\r
188 if ((Language == NULL) ||\r
189 (ErrorType == NULL) ||\r
190 (Buffer == NULL) ||\r
191 (ControllerHandle == NULL) ||\r
192 (BufferSize == NULL)) {\r
193 return EFI_INVALID_PARAMETER;\r
194 }\r
195\r
c8af31ec
OM
196 // Check Language is supported (i.e. is "en-*" - only English is supported)\r
197 if (AsciiStrnCmp (Language, "en", 2) != 0) {\r
198 return EFI_UNSUPPORTED;\r
199 }\r
200\r
11c20f4e 201 Status = EFI_SUCCESS;\r
202 *ErrorType = NULL;\r
203 *BufferSize = DIAGNOSTIC_LOGBUFFER_MAXCHAR;\r
204 *Buffer = DiagnosticInitLog (DIAGNOSTIC_LOGBUFFER_MAXCHAR);\r
205\r
206 DiagnosticLog (L"MMC Driver Diagnostics\n");\r
207\r
208 // For each MMC instance\r
209 CurrentLink = mMmcHostPool.ForwardLink;\r
210 while (CurrentLink != NULL && CurrentLink != &mMmcHostPool && (Status == EFI_SUCCESS)) {\r
c8af31ec
OM
211 MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK (CurrentLink);\r
212 ASSERT (MmcHostInstance != NULL);\r
11c20f4e 213\r
214 // LBA=1 Size=BlockSize\r
215 DiagnosticLog (L"MMC Driver Diagnostics - Test: First Block\n");\r
216 Status = MmcReadWriteDataTest (MmcHostInstance, 1, MmcHostInstance->BlockIo.Media->BlockSize);\r
217\r
218 // LBA=2 Size=BlockSize\r
219 DiagnosticLog (L"MMC Driver Diagnostics - Test: Second Block\n");\r
220 Status = MmcReadWriteDataTest (MmcHostInstance, 2, MmcHostInstance->BlockIo.Media->BlockSize);\r
221\r
222 // LBA=10 Size=BlockSize\r
223 DiagnosticLog (L"MMC Driver Diagnostics - Test: Any Block\n");\r
224 Status = MmcReadWriteDataTest (MmcHostInstance, MmcHostInstance->BlockIo.Media->LastBlock >> 1, MmcHostInstance->BlockIo.Media->BlockSize);\r
225\r
226 // LBA=LastBlock Size=BlockSize\r
227 DiagnosticLog (L"MMC Driver Diagnostics - Test: Last Block\n");\r
228 Status = MmcReadWriteDataTest (MmcHostInstance, MmcHostInstance->BlockIo.Media->LastBlock, MmcHostInstance->BlockIo.Media->BlockSize);\r
229\r
230 // LBA=1 Size=2*BlockSize\r
231 DiagnosticLog (L"MMC Driver Diagnostics - Test: First Block / 2 BlockSSize\n");\r
232 Status = MmcReadWriteDataTest (MmcHostInstance, 1, 2*MmcHostInstance->BlockIo.Media->BlockSize);\r
233\r
234 CurrentLink = CurrentLink->ForwardLink;\r
235 }\r
236\r
237 return Status;\r
1bfda055 238}\r
239\r
240//\r
241// EFI Driver Diagnostics 2 Protocol\r
242//\r
243GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gMmcDriverDiagnostics2 = {\r
244 (EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS) MmcDriverDiagnosticsRunDiagnostics,\r
245 "en"\r
246};\r