+++ /dev/null
-/** @file\r
- Diagnostics Protocol implementation for the MMC DXE driver\r
-\r
- Copyright (c) 2011, ARM Limited. All rights reserved.\r
- \r
- This program and the accompanying materials \r
- are licensed and made available under the terms and conditions of the BSD License \r
- which accompanies this distribution. The full text of the license may be found at \r
- http://opensource.org/licenses/bsd-license.php \r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-**/\r
-\r
-#include <Uefi.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-\r
-#include "Mmc.h"\r
-\r
-#define DIAGNOSTIC_LOGBUFFER_MAXCHAR 1024\r
-\r
-CHAR16* mLogBuffer = NULL;\r
-UINTN mLogRemainChar = 0;\r
-\r
-CHAR16* DiagnosticInitLog(UINTN MaxBufferChar) {\r
- mLogRemainChar = MaxBufferChar;\r
- mLogBuffer = AllocatePool ((UINTN)MaxBufferChar * sizeof(CHAR16));\r
- return mLogBuffer;\r
-}\r
-\r
-UINTN DiagnosticLog(CONST CHAR16* Str) {\r
- UINTN len = StrLen (Str);\r
- if (len <= mLogRemainChar) {\r
- mLogRemainChar -= len;\r
- StrCpy (mLogBuffer, Str);\r
- mLogBuffer += len;\r
- return len;\r
- } else {\r
- return 0;\r
- }\r
-}\r
-\r
-VOID GenerateRandomBuffer(VOID* Buffer, UINTN BufferSize) {\r
- UINT64 i;\r
- UINT64* Buffer64 = (UINT64*)Buffer;\r
-\r
- for (i = 0; i < (BufferSize >> 3); i++) {\r
- *Buffer64 = i | (~i << 32);\r
- Buffer64++;\r
- }\r
-}\r
-\r
-BOOLEAN CompareBuffer(VOID *BufferA, VOID *BufferB, UINTN BufferSize) {\r
- UINTN i;\r
- UINT64* BufferA64 = (UINT64*)BufferA;\r
- UINT64* BufferB64 = (UINT64*)BufferB;\r
-\r
- for (i = 0; i < (BufferSize >> 3); i++) {\r
- if (*BufferA64 != *BufferB64) {\r
- DEBUG((EFI_D_ERROR, "CompareBuffer: Error at %i", i));\r
- DEBUG((EFI_D_ERROR, "(0x%lX) != (0x%lX)\n", *BufferA64, *BufferB64));\r
- return FALSE;\r
- }\r
- BufferA64++;\r
- BufferB64++;\r
- }\r
- return TRUE;\r
-}\r
-\r
-EFI_STATUS MmcReadWriteDataTest(MMC_HOST_INSTANCE *MmcHostInstance, EFI_LBA Lba, UINTN BufferSize) {\r
- VOID *BackBuffer;\r
- VOID *WriteBuffer;\r
- VOID *ReadBuffer;\r
- EFI_STATUS Status;\r
- \r
- // Check if a Media is Present\r
- if (!MmcHostInstance->BlockIo.Media->MediaPresent) {\r
- DiagnosticLog(L"ERROR: No Media Present\n");\r
- return EFI_NO_MEDIA;\r
- }\r
-\r
- if (MmcHostInstance->State != MmcTransferState) {\r
- DiagnosticLog(L"ERROR: Not ready for Transfer state\n");\r
- return EFI_NOT_READY;\r
- }\r
-\r
- BackBuffer = AllocatePool(BufferSize);\r
- WriteBuffer = AllocatePool(BufferSize);\r
- ReadBuffer = AllocatePool(BufferSize);\r
-\r
- // Read (and save) buffer at a specific location\r
- Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,BackBuffer);\r
- if (Status != EFI_SUCCESS) {\r
- DiagnosticLog(L"ERROR: Fail to Read Block (1)\n");\r
- return Status;\r
- }\r
-\r
- // Write buffer at the same location\r
- GenerateRandomBuffer(WriteBuffer,BufferSize);\r
- Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,WriteBuffer);\r
- if (Status != EFI_SUCCESS) {\r
- DiagnosticLog(L"ERROR: Fail to Write Block (1)\n");\r
- return Status;\r
- }\r
-\r
- // Read the buffer at the same location\r
- Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,ReadBuffer);\r
- if (Status != EFI_SUCCESS) {\r
- DiagnosticLog(L"ERROR: Fail to Read Block (2)\n");\r
- return Status;\r
- }\r
-\r
- // Check that is conform\r
- if (!CompareBuffer(ReadBuffer,WriteBuffer,BufferSize)) {\r
- DiagnosticLog(L"ERROR: Fail to Read/Write Block (1)\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // Restore content at the original location\r
- Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,BackBuffer);\r
- if (Status != EFI_SUCCESS) {\r
- DiagnosticLog(L"ERROR: Fail to Write Block (2)\n");\r
- return Status;\r
- }\r
-\r
- // Read the restored content\r
- Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId,Lba,BufferSize,ReadBuffer);\r
- if (Status != EFI_SUCCESS) {\r
- DiagnosticLog(L"ERROR: Fail to Read Block (3)\n");\r
- return Status;\r
- }\r
-\r
- // Check the content is correct\r
- if (!CompareBuffer(ReadBuffer,BackBuffer,BufferSize)) {\r
- DiagnosticLog(L"ERROR: Fail to Read/Write Block (2)\n");\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-MmcDriverDiagnosticsRunDiagnostics (\r
- IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE ChildHandle OPTIONAL,\r
- IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,\r
- IN CHAR8 *Language,\r
- OUT EFI_GUID **ErrorType,\r
- OUT UINTN *BufferSize,\r
- OUT CHAR16 **Buffer\r
- )\r
-{\r
- LIST_ENTRY *CurrentLink;\r
- MMC_HOST_INSTANCE *MmcHostInstance;\r
- EFI_STATUS Status;\r
-\r
- if (Language == NULL ||\r
- ErrorType == NULL ||\r
- Buffer == NULL ||\r
- ControllerHandle == NULL ||\r
- BufferSize == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = EFI_SUCCESS;\r
- *ErrorType = NULL;\r
- *BufferSize = DIAGNOSTIC_LOGBUFFER_MAXCHAR;\r
- *Buffer = DiagnosticInitLog(DIAGNOSTIC_LOGBUFFER_MAXCHAR);\r
-\r
- DiagnosticLog(L"MMC Driver Diagnostics\n");\r
-\r
- // For each MMC instance\r
- CurrentLink = mMmcHostPool.ForwardLink;\r
- while (CurrentLink != NULL && CurrentLink != &mMmcHostPool && (Status == EFI_SUCCESS)) {\r
- MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK(CurrentLink);\r
- ASSERT(MmcHostInstance != NULL);\r
-\r
- // LBA=1 Size=BlockSize\r
- DiagnosticLog(L"MMC Driver Diagnostics - Test: First Block\n");\r
- Status = MmcReadWriteDataTest(MmcHostInstance, 1, MmcHostInstance->BlockIo.Media->BlockSize);\r
-\r
- // LBA=2 Size=BlockSize\r
- DiagnosticLog(L"MMC Driver Diagnostics - Test: Second Block\n");\r
- Status = MmcReadWriteDataTest(MmcHostInstance, 2, MmcHostInstance->BlockIo.Media->BlockSize);\r
-\r
- // LBA=10 Size=BlockSize\r
- DiagnosticLog(L"MMC Driver Diagnostics - Test: Any Block\n");\r
- Status = MmcReadWriteDataTest(MmcHostInstance, MmcHostInstance->BlockIo.Media->LastBlock >> 1, MmcHostInstance->BlockIo.Media->BlockSize);\r
-\r
- // LBA=LastBlock Size=BlockSize\r
- DiagnosticLog(L"MMC Driver Diagnostics - Test: Last Block\n");\r
- Status = MmcReadWriteDataTest(MmcHostInstance, MmcHostInstance->BlockIo.Media->LastBlock, MmcHostInstance->BlockIo.Media->BlockSize);\r
-\r
- // LBA=1 Size=2*BlockSize\r
- DiagnosticLog(L"MMC Driver Diagnostics - Test: First Block / 2 BlockSSize\n");\r
- Status = MmcReadWriteDataTest(MmcHostInstance, 1, 2*MmcHostInstance->BlockIo.Media->BlockSize);\r
-\r
- CurrentLink = CurrentLink->ForwardLink;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-//\r
-// EFI Driver Diagnostics 2 Protocol\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gMmcDriverDiagnostics2 = {\r
- (EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS) MmcDriverDiagnosticsRunDiagnostics,\r
- "en"\r
-};\r