123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- /** @file
- Diagnostics Protocol implementation for the MMC DXE driver
- Copyright (c) 2011-2020, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Uefi.h>
- #include <Library/DebugLib.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/MemoryAllocationLib.h>
- #include <Library/BaseLib.h>
- #include "Mmc.h"
- #define DIAGNOSTIC_LOGBUFFER_MAXCHAR 1024
- CHAR16 *mLogBuffer = NULL;
- UINTN mLogRemainChar = 0;
- CHAR16 *
- DiagnosticInitLog (
- UINTN MaxBufferChar
- )
- {
- mLogRemainChar = MaxBufferChar;
- mLogBuffer = AllocatePool ((UINTN)MaxBufferChar * sizeof (CHAR16));
- return mLogBuffer;
- }
- UINTN
- DiagnosticLog (
- CONST CHAR16 *Str
- )
- {
- UINTN len = StrLen (Str);
- if (len < mLogRemainChar) {
- StrCpyS (mLogBuffer, mLogRemainChar, Str);
- mLogRemainChar -= len;
- mLogBuffer += len;
- return len;
- } else {
- return 0;
- }
- }
- VOID
- GenerateRandomBuffer (
- VOID *Buffer,
- UINTN BufferSize
- )
- {
- UINT64 i;
- UINT64 *Buffer64 = (UINT64 *)Buffer;
- for (i = 0; i < (BufferSize >> 3); i++) {
- *Buffer64 = i | LShiftU64 (~i, 32);
- Buffer64++;
- }
- }
- BOOLEAN
- CompareBuffer (
- VOID *BufferA,
- VOID *BufferB,
- UINTN BufferSize
- )
- {
- UINTN i;
- UINT64 *BufferA64 = (UINT64 *)BufferA;
- UINT64 *BufferB64 = (UINT64 *)BufferB;
- for (i = 0; i < (BufferSize >> 3); i++) {
- if (*BufferA64 != *BufferB64) {
- DEBUG ((DEBUG_ERROR, "CompareBuffer: Error at %i", i));
- DEBUG ((DEBUG_ERROR, "(0x%lX) != (0x%lX)\n", *BufferA64, *BufferB64));
- return FALSE;
- }
- BufferA64++;
- BufferB64++;
- }
- return TRUE;
- }
- EFI_STATUS
- MmcReadWriteDataTest (
- MMC_HOST_INSTANCE *MmcHostInstance,
- EFI_LBA Lba,
- UINTN BufferSize
- )
- {
- VOID *BackBuffer;
- VOID *WriteBuffer;
- VOID *ReadBuffer;
- EFI_STATUS Status;
- // Check if a Media is Present
- if (!MmcHostInstance->BlockIo.Media->MediaPresent) {
- DiagnosticLog (L"ERROR: No Media Present\n");
- return EFI_NO_MEDIA;
- }
- if (MmcHostInstance->State != MmcTransferState) {
- DiagnosticLog (L"ERROR: Not ready for Transfer state\n");
- return EFI_NOT_READY;
- }
- BackBuffer = AllocatePool (BufferSize);
- WriteBuffer = AllocatePool (BufferSize);
- ReadBuffer = AllocatePool (BufferSize);
- // Read (and save) buffer at a specific location
- Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId, Lba, BufferSize, BackBuffer);
- if (Status != EFI_SUCCESS) {
- DiagnosticLog (L"ERROR: Fail to Read Block (1)\n");
- return Status;
- }
- // Write buffer at the same location
- GenerateRandomBuffer (WriteBuffer, BufferSize);
- Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId, Lba, BufferSize, WriteBuffer);
- if (Status != EFI_SUCCESS) {
- DiagnosticLog (L"ERROR: Fail to Write Block (1)\n");
- return Status;
- }
- // Read the buffer at the same location
- Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId, Lba, BufferSize, ReadBuffer);
- if (Status != EFI_SUCCESS) {
- DiagnosticLog (L"ERROR: Fail to Read Block (2)\n");
- return Status;
- }
- // Check that is conform
- if (!CompareBuffer (ReadBuffer, WriteBuffer, BufferSize)) {
- DiagnosticLog (L"ERROR: Fail to Read/Write Block (1)\n");
- return EFI_INVALID_PARAMETER;
- }
- // Restore content at the original location
- Status = MmcWriteBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId, Lba, BufferSize, BackBuffer);
- if (Status != EFI_SUCCESS) {
- DiagnosticLog (L"ERROR: Fail to Write Block (2)\n");
- return Status;
- }
- // Read the restored content
- Status = MmcReadBlocks (&(MmcHostInstance->BlockIo), MmcHostInstance->BlockIo.Media->MediaId, Lba, BufferSize, ReadBuffer);
- if (Status != EFI_SUCCESS) {
- DiagnosticLog (L"ERROR: Fail to Read Block (3)\n");
- return Status;
- }
- // Check the content is correct
- if (!CompareBuffer (ReadBuffer, BackBuffer, BufferSize)) {
- DiagnosticLog (L"ERROR: Fail to Read/Write Block (2)\n");
- return EFI_INVALID_PARAMETER;
- }
- return EFI_SUCCESS;
- }
- EFI_STATUS
- EFIAPI
- MmcDriverDiagnosticsRunDiagnostics (
- IN EFI_DRIVER_DIAGNOSTICS_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
- )
- {
- LIST_ENTRY *CurrentLink;
- MMC_HOST_INSTANCE *MmcHostInstance;
- EFI_STATUS Status;
- if ((Language == NULL) ||
- (ErrorType == NULL) ||
- (Buffer == NULL) ||
- (ControllerHandle == NULL) ||
- (BufferSize == NULL))
- {
- return EFI_INVALID_PARAMETER;
- }
- // Check Language is supported (i.e. is "en-*" - only English is supported)
- if (AsciiStrnCmp (Language, "en", 2) != 0) {
- return EFI_UNSUPPORTED;
- }
- Status = EFI_SUCCESS;
- *ErrorType = NULL;
- *BufferSize = DIAGNOSTIC_LOGBUFFER_MAXCHAR;
- *Buffer = DiagnosticInitLog (DIAGNOSTIC_LOGBUFFER_MAXCHAR);
- DiagnosticLog (L"MMC Driver Diagnostics\n");
- // Find the MMC Host instance on which we have been asked to run diagnostics
- MmcHostInstance = NULL;
- CurrentLink = mMmcHostPool.ForwardLink;
- while (CurrentLink != NULL && CurrentLink != &mMmcHostPool && (Status == EFI_SUCCESS)) {
- MmcHostInstance = MMC_HOST_INSTANCE_FROM_LINK (CurrentLink);
- ASSERT (MmcHostInstance != NULL);
- if (MmcHostInstance->MmcHandle == ControllerHandle) {
- break;
- }
- CurrentLink = CurrentLink->ForwardLink;
- }
- // If we didn't find the controller, return EFI_UNSUPPORTED
- if ( (MmcHostInstance == NULL)
- || (MmcHostInstance->MmcHandle != ControllerHandle))
- {
- return EFI_UNSUPPORTED;
- }
- // LBA=1 Size=BlockSize
- DiagnosticLog (L"MMC Driver Diagnostics - Test: First Block\n");
- Status = MmcReadWriteDataTest (MmcHostInstance, 1, MmcHostInstance->BlockIo.Media->BlockSize);
- // LBA=2 Size=BlockSize
- DiagnosticLog (L"MMC Driver Diagnostics - Test: Second Block\n");
- Status = MmcReadWriteDataTest (MmcHostInstance, 2, MmcHostInstance->BlockIo.Media->BlockSize);
- // LBA=10 Size=BlockSize
- DiagnosticLog (L"MMC Driver Diagnostics - Test: Any Block\n");
- Status = MmcReadWriteDataTest (
- MmcHostInstance,
- RShiftU64 (MmcHostInstance->BlockIo.Media->LastBlock, 1),
- MmcHostInstance->BlockIo.Media->BlockSize
- );
- // LBA=LastBlock Size=BlockSize
- DiagnosticLog (L"MMC Driver Diagnostics - Test: Last Block\n");
- Status = MmcReadWriteDataTest (MmcHostInstance, MmcHostInstance->BlockIo.Media->LastBlock, MmcHostInstance->BlockIo.Media->BlockSize);
- // LBA=1 Size=2*BlockSize
- DiagnosticLog (L"MMC Driver Diagnostics - Test: First Block / 2 BlockSSize\n");
- Status = MmcReadWriteDataTest (MmcHostInstance, 1, 2 * MmcHostInstance->BlockIo.Media->BlockSize);
- return Status;
- }
- //
- // EFI Driver Diagnostics 2 Protocol
- //
- GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gMmcDriverDiagnostics2 = {
- (EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS)MmcDriverDiagnosticsRunDiagnostics,
- "en"
- };
|