slimbootloader/PayloadPkg/OsLoader/BlockIoTest.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