141 lines
5.1 KiB
C
141 lines
5.1 KiB
C
/** @file
|
|
|
|
Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include "BlockIoTest.h"
|
|
|
|
#if TEST_DEVICE_WRITE
|
|
|
|
/**
|
|
Perform the BlockIO test for the given device type.
|
|
|
|
@param OsBootOption pointer to boot optoin info.
|
|
|
|
@retval EFI_SUCCESS on successful read/write test to the block dev
|
|
|
|
**/
|
|
EFI_STATUS
|
|
TestDevBlocks (
|
|
IN OS_BOOT_OPTION *OsBootOption
|
|
)
|
|
{
|
|
RETURN_STATUS Status ;
|
|
UINT8 *Buffer;
|
|
UINT32 Index;
|
|
UINT8 *TestData1;
|
|
UINT8 *TestData2;
|
|
DEVICE_BLOCK_INFO BlockInfo;
|
|
UINT64 TestLba;
|
|
UINTN BootMediumPciBase;
|
|
DEVICE_BLOCK_FUNC DevBlockFunc;
|
|
EFI_PEI_BLOCK_DEVICE_TYPE DevType;
|
|
//
|
|
// Get OS boot device address
|
|
//
|
|
BootMediumPciBase = GetDeviceAddr (OsBootOption->DevType, OsBootOption->DevInstance);
|
|
BootMediumPciBase = TO_MM_PCI_ADDRESS (BootMediumPciBase);
|
|
DEBUG ((DEBUG_INFO, "BootMediumPciBase(0x%x)\n", BootMediumPciBase));
|
|
|
|
//
|
|
// Init Boot device functions
|
|
//
|
|
if (OsBootOption->DevType == OsBootDeviceEmmc) {
|
|
DevBlockFunc.DevInit = MmcInitialize;
|
|
DevBlockFunc.GetInfo = MmcGetMediaInfo;
|
|
DevBlockFunc.ReadBlocks = MmcReadBlocks;
|
|
DevBlockFunc.WriteBlocks = MmcWriteBlocks;
|
|
DevType = EMMC;
|
|
} else if (OsBootOption->DevType == OsBootDeviceSd) {
|
|
DevBlockFunc.DevInit = SdInitialize;
|
|
DevBlockFunc.GetInfo = MmcGetMediaInfo;
|
|
DevBlockFunc.ReadBlocks = MmcReadBlocks;
|
|
DevBlockFunc.WriteBlocks = MmcWriteBlocks;
|
|
DevType = SD;
|
|
} else if (OsBootOption->DevType == OsBootDeviceUfs) {
|
|
DevBlockFunc.DevInit = InitializeUfs;
|
|
DevBlockFunc.GetInfo = UfsGetMediaInfo;
|
|
DevBlockFunc.ReadBlocks = UfsReadBlocks;
|
|
DevBlockFunc.WriteBlocks = UfsWriteBlocks;
|
|
DevType = UfsDevice;
|
|
} else if (OsBootOption->DevType == OsBootDeviceNvme) {
|
|
DevBlockFunc.DevInit = NvmeInitialize;
|
|
DevBlockFunc.GetInfo = NvmeGetMediaInfo;
|
|
DevBlockFunc.ReadBlocks = NvmeReadBlocks;
|
|
DevBlockFunc.WriteBlocks = NvmeWriteBlocks;
|
|
DevType = UfsDevice;
|
|
} else {
|
|
DEBUG ((DEBUG_ERROR, "Invalid Boot device configured!"));
|
|
return RETURN_UNSUPPORTED;
|
|
}
|
|
|
|
// Prepare buffer
|
|
Buffer = (UINT8 *)AllocatePool (4096 * 3);
|
|
TestData1 = Buffer + 4096;
|
|
TestData2 = TestData1 + 4096;
|
|
SetMem32 (TestData1, 4096 / 4, 0x00FF5AA5);
|
|
SetMem32 (TestData2, 4096 / 4, 0x11224488);
|
|
|
|
|
|
//Init the device.
|
|
Status = DevBlockFunc.DevInit (BootMediumPciBase, DevInitAll);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "Mmcinitialize Error %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
// Test GetInfo, read and write
|
|
for (Index = 0; Index < 7; Index++ ) {
|
|
ZeroMem (&BlockInfo, sizeof (BlockInfo));
|
|
Status = DevBlockFunc.GetInfo (Index, &BlockInfo);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "GetInfo [%d] %r\n", Index, Status));
|
|
continue;
|
|
}
|
|
DEBUG ((DEBUG_INFO, "\nP[%d]: BlockNum=0x%lx BlockSize=0x%x\n", Index, BlockInfo.BlockNum, BlockInfo.BlockSize));
|
|
|
|
if ((BlockInfo.BlockNum != 0) && (BlockInfo.BlockSize != 0)) {
|
|
// Test last block read/write
|
|
TestLba = BlockInfo.BlockNum - 1;
|
|
|
|
// test read
|
|
DEBUG ((DEBUG_INFO, " P[%d]: Try to read block 0x%lx with BlockSize=0x%x\n", Index, TestLba, BlockInfo.BlockSize));
|
|
Status = DevBlockFunc.ReadBlocks (Index, TestLba, BlockInfo.BlockSize, Buffer);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, " P[%d]: Read block Status = %r\n", Index, Status));
|
|
continue;
|
|
}
|
|
DEBUG ((DEBUG_INFO, " P[%d]: Dump Read Data\n", Index));
|
|
DumpBuffer (Buffer, 0x200);
|
|
|
|
// test write
|
|
DEBUG ((DEBUG_INFO, " P[%d]: try to write block 0x%lx with BlockSize=0x%x\n", Index, TestLba, BlockInfo.BlockSize));
|
|
if (* (UINT32 *)Buffer == * (UINT32 *)TestData1) {
|
|
Status = DevBlockFunc.WriteBlocks (Index, TestLba, BlockInfo.BlockSize, TestData2);
|
|
DEBUG ((DEBUG_INFO, " P[%d]: write 0x%x to block\n", Index, * (UINT32 *)TestData2));
|
|
} else {
|
|
Status = DevBlockFunc.WriteBlocks (Index, TestLba, BlockInfo.BlockSize, TestData1);
|
|
DEBUG ((DEBUG_INFO, " P[%d]: write 0x%x to block\n", * (UINT32 *)TestData1));
|
|
}
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, " P[%d]: Write block Status = %r\n", Index, Status));
|
|
continue;
|
|
}
|
|
DEBUG ((DEBUG_INFO, " P[%d]: try to re-read block 0x%lx with BlockSize=0x%x\n", Index, TestLba,
|
|
BlockInfo.BlockSize));
|
|
Status = DevBlockFunc.ReadBlocks (Index, TestLba, BlockInfo.BlockSize, Buffer);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, " P[%d]: Read written data. Status = %r\n", Index, Status));
|
|
continue;
|
|
}
|
|
DEBUG ((DEBUG_INFO, " P[%d]: Dump Read Data after written.\n", Index));
|
|
DumpBuffer (Buffer, 0x200);
|
|
}
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
#endif
|
|
|