/** @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"
};
